common

package
v0.0.0-...-e96e9f3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 28, 2026 License: GPL-3.0 Imports: 21 Imported by: 0

Documentation

Index

Constants

View Source
const (
	MaxKeySize        = 127
	MaxSourceAddrSize = 255
	MaxRemoteAddrSize = 255
)

Wire limits of the values that end up in the table. The mutex port reads a key size as a signed byte and the manager port writes every size as an unsigned one, a value beyond these cannot travel back to a client.

Variables

This section is empty.

Functions

func ExtractSourceAddr

func ExtractSourceAddr(conn net.Conn) string

Types

type Channel

type Channel struct {
	Key string
	// contains filtered or unexported fields
}

func NewChannel

func NewChannel(key string) *Channel

func (*Channel) Close

func (c *Channel) Close()

func (*Channel) Pull

func (c *Channel) Pull()

func (*Channel) Push

func (c *Channel) Push(r *Request) bool

Push waits for the key to become free and takes the ownership of it. It reports false when the request is revoked before it can own the key, the caller is expected to retry on a fresh channel in that case.

func (*Channel) PushContext

func (c *Channel) PushContext(ctx context.Context, r *Request) bool

PushContext is Push for a requester that may go away while it waits. When ctx is done before the key is won, the request is withdrawn from the queue and false is reported, the key is never handed to a requester that is gone. A request that is already the owner is not affected, the context only matters while waiting.

func (*Channel) Report

func (c *Channel) Report() *ChannelReport

func (*Channel) Reset

func (c *Channel) Reset(sourceAddr string)

func (*Channel) Restore

func (c *Channel) Restore(r *Request) bool

Restore puts a fresh channel straight into the held state, for a key that was held when the previous run ended. It reports false on a channel that is already held.

func (*Channel) TryPush

func (c *Channel) TryPush(r *Request) bool

TryPush takes the ownership of the key only if it is free right now, without ever waiting. It reports false when the key is already held or is being reset, so the caller can decide what to do instead of queueing. A waiter is never registered, a try that does not win simply leaves no trace.

type ChannelReport

type ChannelReport struct {
	Key     string
	Current *Request
}

type ChannelReports

type ChannelReports []*ChannelReport

func (ChannelReports) Len

func (c ChannelReports) Len() int

func (ChannelReports) Less

func (c ChannelReports) Less(i, j int) bool

func (ChannelReports) Swap

func (c ChannelReports) Swap(i, j int)

type Entry

type Entry struct {
	Kind   entryKind `json:"kind"`
	Holder Holder    `json:"holder"`
}

Entry is one durable change to the lock table. An acquire carries the whole holder, a release carries only the key of the Holder.

func AcquireEntry

func AcquireEntry(report *ChannelReport) Entry

AcquireEntry records that a key became held.

func ReleaseEntry

func ReleaseEntry(key string) Entry

ReleaseEntry records that a key was released.

type Holder

type Holder struct {
	Key        rawString `json:"key"`
	Id         string    `json:"id"`
	Stamp      time.Time `json:"stamp"`
	SourceAddr rawString `json:"source_addr"`
	RemoteAddr string    `json:"remote_addr"`
}

Holder is the durable form of a held key. Waiting requests are not kept, they are blocked connections that die with the process and retry on their own.

type Lock

type Lock struct {
	// contains filtered or unexported fields
}

func NewLock

func NewLock() *Lock

func NewLockWithStore

func NewLockWithStore(store Store) (*Lock, error)

NewLockWithStore brings back the holders that the store kept from the previous run and keeps the store up to date from then on. The restored state is compacted straight back, so a store that cannot be written fails the start up rather than the first lock request, and a torn tail from the previous crash is healed before anything new is appended.

func (*Lock) Compactions

func (l *Lock) Compactions() uint64

Compactions counts the times the log has been rewritten since the start up.

func (*Lock) Keys

func (l *Lock) Keys() ChannelReports

func (*Lock) Lock

func (l *Lock) Lock(key string, sourceAddr string, remoteAddr net.Addr) (bool, error)

Lock reports false when the request is reset before it can own the key, the caller is expected to try again to contend for the fresh channel. An error means the key could not be made durable, it is released again and the caller should not blindly retry.

func (*Lock) LockContext

func (l *Lock) LockContext(ctx context.Context, key string, sourceAddr string, remoteAddr net.Addr) (bool, error)

LockContext is Lock for a requester that may go away while it waits, a client whose connection drops while its request is queued. When ctx is done before the key is won and made durable, nothing is acquired and the context's error is returned, so the caller can tell "the requester is gone" from "reset, try again". Without this, a request left behind by a dead client would still win the key later and hold it with nobody to release it.

func (*Lock) Persistent

func (l *Lock) Persistent() bool

Persistent reports whether the holders survive a restart.

func (*Lock) ResetByKey

func (l *Lock) ResetByKey(key string) error

func (*Lock) ResetBySource

func (l *Lock) ResetBySource(sourceAddr string) error

func (*Lock) StoreWriteErrors

func (l *Lock) StoreWriteErrors() uint64

StoreWriteErrors counts the appends and compactions that failed since the start up.

func (*Lock) TryLock

func (l *Lock) TryLock(key string, sourceAddr string, remoteAddr net.Addr) (bool, error)

TryLock takes the key only if it is free right now and never waits. It reports false, and takes nothing, when the key is already held. An acquire is made durable before it is reported, exactly like Lock, so a true survives a restart. An error means the key could not be made durable and was released again.

func (*Lock) Unlock

func (l *Lock) Unlock(key string) error

Unlock always releases the key in memory. The error only reports that the store could not be updated, a restart may bring the key back in that case.

type Request

type Request struct {
	Id    string
	Stamp time.Time

	SourceAddr string
	RemoteAddr net.Addr
}

func NewRequest

func NewRequest(sourceAddr string, remoteAddr net.Addr) *Request

type RestoredAddr

type RestoredAddr string

RestoredAddr stands in for the peer address of a connection that ended before the restart.

func (RestoredAddr) Network

func (r RestoredAddr) Network() string

func (RestoredAddr) String

func (r RestoredAddr) String() string

type Store

type Store interface {
	// Load returns the holders of the previous run, none when there was no
	// previous run.
	Load() ([]Holder, error)
	// Append records the entries durably. They are on disk by the time it
	// returns, the client is acknowledged right after. It reports whether the
	// log has grown enough that the caller should Compact.
	Append(entries []Entry) (compact bool, err error)
	// Compact rewrites the log from the store's own durable view, dropping the
	// released keys, so it never grows without bound. It works from what has
	// actually been made durable, not from the caller's in-memory table, which
	// can momentarily disagree with the disk on either side of an append.
	Compact() error
}

Store keeps the holders across restarts.

type WALStore

type WALStore struct {
	// contains filtered or unexported fields
}

WALStore is an append only log of the lock table changes, compacted in place when it outgrows the live set.

The store keeps its own view of the durably recorded holders, updated only after an append has been synced. A compaction rewrites the log from that view, never from the caller's in-memory table, so a compaction can never disagree with what has actually been made durable, whichever way the caller's memory and the disk are momentarily out of step.

func NewWALStore

func NewWALStore(path string) (*WALStore, error)

func (*WALStore) Append

func (w *WALStore) Append(entries []Entry) (bool, error)

func (*WALStore) Close

func (w *WALStore) Close() error

Close releases the append handle. The lock table does not need it for correctness, the process exits either way, it is here for a tidy shutdown and for the tests on windows.

func (*WALStore) Compact

func (w *WALStore) Compact() error

func (*WALStore) Load

func (w *WALStore) Load() ([]Holder, error)

func (*WALStore) Path

func (w *WALStore) Path() string

Path is where the log lives, with the symlinks resolved.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL