Documentation
¶
Overview ¶
Package client is the daemon's client, as AutoDoc's own programs use it: a Session (the handshake, the connection's generation, spawning --serve when nothing answers), the restart handoffs that decide which build serves next, and the waits around a restart. The TUI, --call, --print-endpoint and --restart all connect through it.
A Session is safe for concurrent use: its state is under one mutex, and a call runs on whatever goroutine makes it.
Index ¶
- Constants
- func HasHandoff(stateDir, sock string) bool
- func SpawnServe(configPath, stateDir string) (string, error)
- func WaitGone(ctx context.Context, pid int64, d time.Duration) bool
- func WriteHandoff(stateDir, sock string, pid int64) error
- type ConnectError
- type MismatchError
- type OlderServer
- type Session
- func (s *Session) Address() string
- func (s *Session) As(name string) *Session
- func (s *Session) Call(ctx context.Context, method string, params ...any) (any, error)
- func (s *Session) CanSpawn() bool
- func (s *Session) Client() string
- func (s *Session) Close()
- func (s *Session) Connect(ctx context.Context) error
- func (s *Session) Done() <-chan struct{}
- func (s *Session) EventsHead() int64
- func (s *Session) ForStore(configured, storePath string) *Session
- func (s *Session) ForgetStale()
- func (s *Session) Gen() uint64
- func (s *Session) PID() int64
- func (s *Session) RemoveHandoff()
- func (s *Session) SetAfterCall(f func(method string))
- func (s *Session) SetBeforeCall(f func(method string, params []any))
- func (s *Session) SetProbeWindow(d time.Duration)
- func (s *Session) SetProcess(pid int64)
- func (s *Session) Stale() *OlderServer
- func (s *Session) StopStale(ctx context.Context) error
- func (s *Session) UseHandoffs(stateDir string) *Session
- func (s *Session) UseResolver(configured string, resolve func(ctx context.Context) string) *Session
- func (s *Session) Version() string
- func (s *Session) WriteHandoff() error
- type StoreMismatchError
Constants ¶
const RestartWait = 15 * time.Second
RestartWait bounds waiting for the old daemon to exit before the new one is started. Every build shares it, so a handoff another build wrote is never longer than this one's (handoffSpan).
Variables ¶
This section is empty.
Functions ¶
func HasHandoff ¶
HasHandoff reports whether a restart handoff for sock is kept in stateDir, standing or not.
func SpawnServe ¶
SpawnServe starts this executable's `--serve` detached from the TUI (its own session, so it outlives the terminal), appending its output to serve.log in the state directory, and returns the log's path. It makes the state directory first: the daemon's log is the first thing written there.
func WaitGone ¶
WaitGone waits until process pid has exited, or d has passed (false): the TUI's restart and `autodoc --print-endpoint --restart` wait on the stopped daemon so.
func WriteHandoff ¶
WriteHandoff announces that process pid is restarting the daemon on sock, as a TUI does before it stops one: until the handoff's deadline, every other client of sock only dials. A launcher other than the TUI restarting the daemon announces it so.
Types ¶
type ConnectError ¶
type ConnectError struct {
Addr string // the socket dialed
Window time.Duration // how long it was dialed for
LogPath string // the spawned daemon's log; "" when none was spawned
Last error // the last dial's error
}
ConnectError is a daemon that did not answer within the probe window.
func (*ConnectError) Error ¶
func (e *ConnectError) Error() string
func (*ConnectError) Unwrap ¶
func (e *ConnectError) Unwrap() error
type MismatchError ¶
MismatchError is a daemon speaking another protocol than this build's.
func (*MismatchError) Error ¶
func (e *MismatchError) Error() string
type OlderServer ¶
OlderServer is a daemon of an older protocol than this build's, as its probe said: a restart stops it and starts the installed autodoc.
type Session ¶
type Session struct {
// contains filtered or unexported fields
}
Session is a client's ONLY path to the core: a golib rpc client, the handshake, and the connection's generation. Every result the host applies was asked under a generation; a reconnect moves it on, so an answer from an old connection is never applied.
func NewSession ¶
NewSession is the session to the daemon on the unix socket addr. spawn, when not nil, starts the daemon once when nothing answers.
func (*Session) Address ¶
Version is the daemon's, as its hello said. Address is where the session dials now: the address a Connect resolved, or the configured one after a spawn.
func (*Session) As ¶
As has the session say hello as name. Any name but rpc.TUIName is admitted across the daemon's protocol range: a daemon older than this build is spoken to at its own protocol, when this build still serves it (rpc.MinProtocol), so a client that is not the TUI survives a protocol apart.
func (*Session) CanSpawn ¶
CanSpawn is whether this session starts a daemon when none answers: what a restart needs to bring one back.
func (*Session) Client ¶
Client is this connection's client token, as its hello said: the events this TUI caused carry it.
func (*Session) Connect ¶
Connect dials the daemon: on refusal it spawns --serve (once, when it may) and retries with backoff, 100 ms doubling to 2 s, within the probe window; then it says hello at this build's protocol. The generation moves as soon as Connect begins. While another process's restart handoff stands (heldBack), it only dials, the probe window suspended, and connects as soon as that restart's daemon answers; once the handoff ends, dies, lapses or reaches this Connect's cap, a full window starts, with the spawn allowed. ctx ends it at any point.
func (*Session) Done ¶
func (s *Session) Done() <-chan struct{}
Done is closed when the connection ends; nil (never ready) with none.
func (*Session) EventsHead ¶
EventsHead is the event log's head when this connection said hello: where following it begins.
func (*Session) ForStore ¶
ForStore has each Connect find the daemon serving the store at storePath (internal/endpoint): the configured socket, or another config's, when that daemon's lease-info names it and it answers as this store's daemon.
func (*Session) ForgetStale ¶
func (s *Session) ForgetStale()
ForgetStale drops the older daemon once it has stopped: a retry then starts the installed one.
func (*Session) RemoveHandoff ¶
func (s *Session) RemoveHandoff()
RemoveHandoff removes this process's handoff, once its daemon answers or its restart failed.
func (*Session) SetAfterCall ¶
SetAfterCall runs f after each call, before its answer is handed back: the seam that holds an answer already read while the caller moves on.
func (*Session) SetBeforeCall ¶
SetBeforeCall runs f before each call, on the goroutine making it: the seam that holds one answer back while a later one lands.
func (*Session) SetProbeWindow ¶
SetProbeWindow is how long Connect keeps dialing after the first refusal (spawnProbeWindow).
func (*Session) SetProcess ¶
SetProcess is the process this session's handoffs are written as: another pid makes two sessions of one process behave as two processes' would.
func (*Session) Stale ¶
func (s *Session) Stale() *OlderServer
Stale is the older daemon this build's hello was refused by; nil when there is none.
func (*Session) StopStale ¶
StopStale stops the older daemon: a connection declaring its protocol, for sys.hello and sys.shutdown alone (frozen across protocols).
func (*Session) UseHandoffs ¶
UseHandoffs keeps restart handoffs in stateDir, the daemon's state directory: Connect waits on another process's restart before it spawns, and WriteHandoff announces this one's (handoff.go).
func (*Session) UseResolver ¶
UseResolver has each Connect find its address with resolve first, and dial configured, where a spawned daemon binds, once it spawns one: a daemon found on another socket that is gone by the time it is dialed costs one spawn here, never a dial loop on a dead address.
func (*Session) WriteHandoff ¶
WriteHandoff announces that this process is restarting the daemon: until the handoff's deadline, another client's Connect only dials, so the daemon this one spawns is the one that serves. A session without a state directory writes none.
type StoreMismatchError ¶
type StoreMismatchError = endpoint.StoreMismatchError
StoreMismatchError is a daemon answering on the session's socket for another store than the config names (endpoint.CheckStore).