Documentation
¶
Overview ¶
Package host is the Looprig Department runtime host.
A Host owns resident sessions for one tenant: it consumes commands, keeps runtime targets resident, serves the HostLink realtime surface, and drains on release. It is consumed BY Factory and imports nothing from it; the dependency boundary that states this is enforced by import_boundary_test.go rather than by convention.
A Host is constructed from validated Options and holds a resolved, immutable configuration: identity and tenant, the HostLink address it advertises, its Department, its collaborators, and the placement, capacity and timing bounds it runs under. The Department it serves — the immutable set of launch targets, and the segregated runtime capabilities Host consumes — lives in the department subpackage. Residency, command consumption, HostLink and drain follow.
Index ¶
- Constants
- func Run(ctx context.Context, blueprint Composition, listen ListenOptions) error
- type AttachError
- type AttachRequest
- type AuthVerifier
- type Checkpointer
- type Clock
- type Collaborators
- type Composition
- type CompositionClock
- type DrainFailure
- type DrainOptions
- type DrainReport
- type EvidenceKey
- type Host
- func (h *Host) ApplyDeadline() time.Duration
- func (h *Host) Auth() AuthVerifier
- func (h *Host) Capacity() uint64
- func (h *Host) ClaimTTL() time.Duration
- func (h *Host) Clock() Clock
- func (h *Host) CommandQueueSize() int
- func (h *Host) Department() *department.Department
- func (h *Host) FixedSessionID() sessionwire.SessionID
- func (h *Host) ID() sessionwire.HostID
- func (h *Host) InternalEndpoint() sessionwire.InternalEndpoint
- func (h *Host) IsolationClass() sessionwire.HostIsolationClass
- func (h *Host) Placement() sessionwire.HostPlacement
- func (h *Host) ReconcileBatch() int
- func (h *Host) ReconcileInterval() time.Duration
- func (h *Host) RegistryExpiry() time.Duration
- func (h *Host) RegistryHeartbeat() time.Duration
- func (h *Host) SessionStore() SessionStore
- func (h *Host) WarmTTL() time.Duration
- func (h *Host) Workspaces() WorkspaceProvider
- type InvalidCompositionError
- type InvalidOptionsError
- type LinkOptions
- type ListenOptions
- type NamespaceLayout
- type OptionErrorCode
- type Options
- type Registrar
- type RegistrarFunc
- type Residency
- type RigSessionIDs
- type Service
- func (s *Service) Attach(ctx context.Context, request AttachRequest) (Residency, error)
- func (s *Service) Department() *department.Department
- func (s *Service) Handler() http.Handler
- func (s *Service) Host() *Host
- func (s *Service) Live() bool
- func (s *Service) MetricsHandler() http.Handler
- func (s *Service) Ready() bool
- func (s *Service) Routes() http.Handler
- func (s *Service) Start(ctx context.Context) error
- func (s *Service) Stop(ctx context.Context) (DrainReport, error)
- type SessionStore
- type WarmTimer
- type WorkspaceProvider
- type Workspaces
Constants ¶
const HostLinkPathPrefix = compose.HostLinkPathPrefix
HostLinkPathPrefix is the path every HostLink connection arrives under on the Handler; the segment after it is the tenant the connection claims and the server then authenticates.
const MaxCommandQueueSize = hostconfig.MaxCommandQueueSize
MaxCommandQueueSize bounds the command queue: an unbounded one converts backpressure into memory growth.
const MaxReconcileBatch = hostconfig.MaxReconcileBatch
MaxReconcileBatch bounds one reconciliation pass, so a Host that has drifted far does not attempt to converge in a single unbounded sweep.
const MinClaimAttemptsBeforeDeadline = hostconfig.MinClaimAttemptsBeforeDeadline
MinClaimAttemptsBeforeDeadline is how many claim lifetimes must fit inside the apply deadline, so a claim that lapses mid-apply still leaves a whole attempt inside the deadline. It is stricter than the runbook's "below"; see internal/hostconfig for the failure model it is chosen against.
const MinHeartbeatsBeforeExpiry = hostconfig.MinHeartbeatsBeforeExpiry
MinHeartbeatsBeforeExpiry is how many heartbeat intervals must fit inside the registry expiry. "Safely below" is a MARGIN, not `<`: three means two consecutive heartbeats may be late or lost before Factory stops seeing this Host. The rule is internal/hostconfig's; this is its published value.
const StepCloseStore = "close_store"
StepCloseStore names the Stop step that closes the session store Compose opened; a failure there is reported on the DrainReport under this step.
Variables ¶
This section is empty.
Functions ¶
func Run ¶ added in v0.2.0
func Run(ctx context.Context, blueprint Composition, listen ListenOptions) error
Run composes the Host, starts it, serves Routes until ctx is done or the listener fails, then drains within Drain.Grace and shuts the listener down.
THE ORDER IS COMPOSE, START, SERVE, DRAIN, CLOSE, and each refusal happens as early as it can be made: a Composition that cannot be validated opens no store; one whose first advertisement the directory refuses fails at Start rather than running invisibly. The drain runs BEFORE the listener closes, because a Factory reads the bounded drain-status observation over HostLink and a listener closed at the signal would leave it inferring completion from a disconnect.
A drain failure is returned as an error, one DrainFailure per failed step joined with the shutdown's own, because a process that drained with failures has left something for an operator to reconcile and must not exit zero. Run's caller decides whether that is fatal.
Types ¶
type AttachError ¶ added in v0.2.0
type AttachError struct {
Step string
Code sessionwire.HostLinkErrorCode
CurrentLeaseEpoch uint64
Reason string
Cause error
// Unreleased names every compensation that itself failed, so "the attach
// failed and took nothing" can be told from "something is still held".
Unreleased []string
}
AttachError reports a refused or failed attach.
Step names WHERE it failed. Code is the HostLink class a Factory branches on and is EMPTY when the failure is not a placement outcome — a store that failed, a launch that failed outright — which is Core's own rule for such failures. CurrentLeaseEpoch is set for epoch_mismatch when the OTHER holder's epoch was readable; it is that holder's, never this Host's, and a caller must not bind with it.
func (*AttachError) Error ¶ added in v0.2.0
func (e *AttachError) Error() string
func (*AttachError) HostLinkCode ¶ added in v0.2.0
func (e *AttachError) HostLinkCode() (sessionwire.HostLinkErrorCode, bool)
HostLinkCode returns the refusal class Factory branches on, and whether this failure has one at all.
func (*AttachError) Unwrap ¶ added in v0.2.0
func (e *AttachError) Unwrap() error
Unwrap returns the typed error a lower layer produced, if any.
type AttachRequest ¶ added in v0.2.0
type AttachRequest struct {
TenantID sessionwire.TenantID
SessionID sessionwire.SessionID
AgentID sessionwire.AgentID
// Mode is Core's closed attach mode: create or restore.
Mode sessionwire.HostLinkAttachMode
// RuntimeCompatibilityID is the build the session was placed on. Optional;
// when set it must equal the target's, and a resident session's.
RuntimeCompatibilityID string
// ActorID is who the attach acts for — a service identity, not an end
// user — and is REQUIRED so the attach can be attributed. TraceID is
// optional correlation.
ActorID string
TraceID string
}
AttachRequest asks this Host to make one session resident, in process.
type AuthVerifier ¶
type AuthVerifier interface {
// VerifyTenant reports whether a presented credential acts for the tenant.
VerifyTenant(context.Context, sessionwire.TenantID, string) error
}
AuthVerifier authenticates an inbound HostLink or command caller.
type Checkpointer ¶
type Checkpointer interface {
Checkpoint(ctx context.Context, tenant sessionwire.TenantID, session sessionwire.SessionID) error
}
Checkpointer commits the checkpoints a nonterminal release requires.
IT HAS NO IMPLEMENTATION IN THIS MODULE AND THAT IS A STATEMENT ABOUT WHERE THE KNOWLEDGE LIVES, not an omission to be filled in with a no-op. A release checkpoint is the runtime's conversation state and the workspace's contents, and Host holds neither. A composition that silently treated the step as done would report a drained Host whose sessions had lost whatever was not already durable, which is the one drain failure that destroys work. So the seam is REQUIRED rather than optional: a Host composed without one does not start.
type Collaborators ¶ added in v0.2.0
type Collaborators struct {
// Backend is the storage composite the session store is opened over. It
// is REQUIRED. Compose opens the store itself — see Compose for why a
// caller may not hand one in.
Backend *storage.Composite
// StoreOptions are passed to sessionstore.Open ahead of the settlement
// evidence option Compose adds. WithDispositionEvidence must NOT be among
// them: the store refuses two, so a caller's would fail the composition
// rather than silently replace the router Compose built.
StoreOptions []sessionstore.Option
// JournalStores are this deployment's settlement evidence readers, one per
// (tenant, storage binding). REQUIRED and non-empty: a Host with no reader
// cannot settle anything and is refused at composition rather than at the
// first command.
JournalStores map[EvidenceKey]sessionstore.DispositionEvidenceReader
// Registrar produces the Department this Host serves. REQUIRED.
Registrar Registrar
// Checkpointer commits the checkpoints a nonterminal release requires.
// REQUIRED; see Checkpointer.
Checkpointer Checkpointer
// Auth verifies the service credential on every HostLink connection.
// REQUIRED.
Auth AuthVerifier
// Workspaces materializes and releases session workspaces. REQUIRED.
Workspaces Workspaces
// NamespaceLayout is REQUIRED; see NamespaceLayout.
NamespaceLayout NamespaceLayout
// RigSessionIDs is REQUIRED; see RigSessionIDs.
RigSessionIDs RigSessionIDs
}
Collaborators is everything a deployment supplies that this module cannot know: which store, which journals, which agents, how to checkpoint, who may connect, where workspaces live.
type Composition ¶ added in v0.2.0
type Composition struct {
// Options is the Host's configuration. ITS COLLABORATOR FIELDS MUST BE
// NIL — Department, SessionStore, Workspaces, Clock and Auth — because
// Compose supplies every one of them from Collaborators: the Department
// from the Registrar, the store it opened, the Workspaces, the clock, the
// verifier. A caller-supplied one would be a second store or a second
// clock beside the one the composition runs on, and is refused.
Options Options
// Generation is this process's incarnation, non-zero. It belongs to the
// RUN and not the configuration: a Host restarted on identical Options is
// a new generation, which is why Options does not carry it.
Generation uint64
Link LinkOptions
Drain DrainOptions
// CompatibilityTimeout bounds the synchronous compatibility wait; WorkPoll
// is how often resident sessions are asked what they are doing. Both are
// required and positive.
CompatibilityTimeout time.Duration
WorkPoll time.Duration
// Clock is optional; nil means the system clock.
Clock CompositionClock
Collaborators Collaborators
}
Composition is one runnable Host, described.
type CompositionClock ¶ added in v0.2.0
type CompositionClock interface {
Now() time.Time
After(time.Duration) <-chan time.Time
NewTimer(time.Duration) *time.Timer
NewWarmTimer(time.Duration) WarmTimer
}
CompositionClock is the composition's single time source: the Host's Clock, the drain's bound and the warm releaser's countdown, all one timeline. Its zero value in Composition means the system clock.
type DrainFailure ¶ added in v0.2.0
type DrainFailure struct {
TenantID sessionwire.TenantID
SessionID sessionwire.SessionID
Step string
Err error
}
DrainFailure is one drain step that did not succeed.
func (DrainFailure) Error ¶ added in v0.2.0
func (f DrainFailure) Error() string
func (DrainFailure) Unwrap ¶ added in v0.2.0
func (f DrainFailure) Unwrap() error
Unwrap returns the step's own error.
type DrainOptions ¶ added in v0.2.0
type DrainOptions struct {
// Grace is the platform's termination grace; Run also bounds Stop by it.
Grace time.Duration
// IdleBoundary bounds the wait for a session to reach a safe boundary.
IdleBoundary time.Duration
// PublishBound bounds the nonaccepting publication.
PublishBound time.Duration
}
DrainOptions bound the drain.
type DrainReport ¶ added in v0.2.0
type DrainReport struct {
Generation uint64
State sessionwire.HostLinkDrainState
Failures []DrainFailure
}
DrainReport is what Stop reports: the drain's generation and terminal state and every step that did not succeed. A drained Host with failures IS drained; the failures are what an operator must reconcile, and Core's two-valued drain state cannot carry them over HostLink.
type EvidenceKey ¶ added in v0.2.0
type EvidenceKey struct {
TenantID sessionwire.TenantID
StorageBindingID string
}
EvidenceKey names the journal store that serves one tenant's sessions under one storage binding. The tenant is half of the key on purpose: a harness Store files ONE tenant's sessions and refuses a request naming another, so a table keyed on the binding alone could route tenant-b's settlement into tenant-a's journal — refused correctly, and only after the dispatch.
type Host ¶
type Host struct {
// contains filtered or unexported fields
}
Host is the tenant-scoped Department runtime host.
It holds a RESOLVED configuration: every option was validated once at construction and nothing here changes afterwards. Residency, command consumption, HostLink and drain are separate concerns; what this type fixes is that a Host which exists is a Host whose configuration was coherent.
The fields are unexported and the accessors return values. Nothing mutable is handed out, and nothing the caller still holds can reach in: Options is taken BY VALUE, so a caller mutating its own copy afterwards changes nothing here. Department and the collaborator interfaces are shared by design — Department is immutable by construction, and a copied SessionStore would be a different SessionStore.
SINCE v0.2.0 THE RESOLVED CONFIGURATION LIVES IN internal/hostconfig AND THIS TYPE CARRIES IT. Every package under internal/ consumes the configuration, and this package now also exports the composition that runs it (Compose), which imports those packages; a leaf both sides import cannot live in either, so it moved down and this type became the exported carrier. Nothing a v0.1.0 caller could see has changed: the method set, the Options fields, the error codes and the constants are the same names with the same values, held to the internal ones by test rather than by aliasing — an alias would have changed the exported type's identity, which is a break.
func New ¶
New validates options and returns a Host.
It returns *InvalidOptionsError, carrying a stable OptionErrorCode, for every refusal. A Host with an incoherent configuration is never returned: there is no partially valid Host and no package-global default to fall back on, so a caller that ignores the error has nothing to use. The rules themselves are internal/hostconfig's, and every one of them reaches this constructor; TestNewDelegatesEveryRefusal holds that.
func (*Host) ApplyDeadline ¶
ApplyDeadline returns the outer bound for applying an admitted command.
func (*Host) CommandQueueSize ¶
CommandQueueSize returns the inbound command buffer size.
func (*Host) Department ¶
func (h *Host) Department() *department.Department
Department returns the immutable set of launch targets this Host serves.
func (*Host) FixedSessionID ¶
func (h *Host) FixedSessionID() sessionwire.SessionID
FixedSessionID returns the session a dedicated Host is bound to, or empty for a pooled Host.
func (*Host) InternalEndpoint ¶
func (h *Host) InternalEndpoint() sessionwire.InternalEndpoint
InternalEndpoint returns the address Factory dials for HostLink.
func (*Host) IsolationClass ¶
func (h *Host) IsolationClass() sessionwire.HostIsolationClass
IsolationClass returns the advertised cross-tenant boundary, which is also this Host's pooled admission rule. There is no TenantID accessor beside it: see Options.IsolationClass for H8.
func (*Host) Placement ¶
func (h *Host) Placement() sessionwire.HostPlacement
Placement returns the admission model this Host runs under.
func (*Host) ReconcileBatch ¶
ReconcileBatch returns the bound on one reconciliation pass.
func (*Host) ReconcileInterval ¶
ReconcileInterval returns how often reconciliation runs.
func (*Host) RegistryExpiry ¶
RegistryExpiry returns how long an advertisement survives without a refresh.
func (*Host) RegistryHeartbeat ¶
RegistryHeartbeat returns the advertisement refresh interval.
func (*Host) SessionStore ¶
func (h *Host) SessionStore() SessionStore
SessionStore returns the durable session state collaborator.
func (*Host) Workspaces ¶
func (h *Host) Workspaces() WorkspaceProvider
Workspaces returns the workspace collaborator. It does not checkpoint; see WorkspaceProvider.
type InvalidCompositionError ¶ added in v0.2.0
InvalidCompositionError reports a Composition that may not run.
func (*InvalidCompositionError) Error ¶ added in v0.2.0
func (e *InvalidCompositionError) Error() string
func (*InvalidCompositionError) Unwrap ¶ added in v0.2.0
func (e *InvalidCompositionError) Unwrap() error
Unwrap returns the lower layer's error, if any.
type InvalidOptionsError ¶
type InvalidOptionsError struct {
Code OptionErrorCode
Field string
Reason string
Cause error
}
InvalidOptionsError reports an option Host may not run with.
Code is what a caller branches on, Field names the option, Reason is for a person, and Cause carries the typed error a lower layer produced — Core's *RequestValidationError for an endpoint, for instance — so errors.As reaches it instead of a caller substring-matching a sentence.
func (*InvalidOptionsError) Error ¶
func (e *InvalidOptionsError) Error() string
func (*InvalidOptionsError) Unwrap ¶
func (e *InvalidOptionsError) Unwrap() error
Unwrap returns the typed error this one was built from, if any.
type LinkOptions ¶ added in v0.2.0
type LinkOptions struct {
// PingInterval and PongTimeout are the HostLink heartbeat. Optional and
// paired: one without the other is refused.
PingInterval time.Duration
PongTimeout time.Duration
// MaxBindingsPerLink and MaxBindings bound what one link and one tenant's
// routing table may hold. MaxTenantLinks bounds how many per-tenant
// transports this Host allocates at once; it is a memory bound and not a
// tenant allowlist.
MaxBindingsPerLink int
MaxBindings int
MaxTenantLinks int
}
LinkOptions bound the HostLink transport.
type ListenOptions ¶ added in v0.2.0
type ListenOptions struct {
// Address is the TCP address to listen on. Ignored when Listener is set.
Address string
// Listener is an already-bound listener, for a platform that hands one in
// or a test that needs to know the port. Run closes it on return.
Listener net.Listener
// ReadHeaderTimeout bounds a client's request headers; zero means ten
// seconds. It is never unbounded: an unbounded header read is a slowloris.
ReadHeaderTimeout time.Duration
}
ListenOptions is where Run serves.
type NamespaceLayout ¶ added in v0.2.0
type NamespaceLayout func(sessionwire.TenantID, sessionwire.SessionID) string
NamespaceLayout answers the durable object prefix a session's runtime writes under. It is a REQUIRED collaborator: the released store publishes no layout accessor and the residency manager refuses a hydration with no namespace in both modes, so a Host composed without one could never attach a session.
type OptionErrorCode ¶
type OptionErrorCode string
OptionErrorCode is a stable, machine-readable reason an option was refused. Reason is free text a caller must not branch on; this is what it branches on.
const ( OptionErrorCodeMissing OptionErrorCode = OptionErrorCode(hostconfig.OptionErrorCodeMissing) OptionErrorCodeInvalid OptionErrorCode = OptionErrorCode(hostconfig.OptionErrorCodeInvalid) OptionErrorCodeUnknownEnum OptionErrorCode = OptionErrorCode(hostconfig.OptionErrorCodeUnknownEnum) OptionErrorCodeNotPositive OptionErrorCode = OptionErrorCode(hostconfig.OptionErrorCodeNotPositive) OptionErrorCodeAboveBound OptionErrorCode = OptionErrorCode(hostconfig.OptionErrorCodeAboveBound) OptionErrorCodeHeartbeatMargin OptionErrorCode = OptionErrorCode(hostconfig.OptionErrorCodeHeartbeatMargin) OptionErrorCodeClaimMargin OptionErrorCode = OptionErrorCode(hostconfig.OptionErrorCodeClaimMargin) OptionErrorCodeDedicatedFixed OptionErrorCode = OptionErrorCode(hostconfig.OptionErrorCodeDedicatedFixed) OptionErrorCodeDedicatedCap OptionErrorCode = OptionErrorCode(hostconfig.OptionErrorCodeDedicatedCap) OptionErrorCodePooledFixed OptionErrorCode = OptionErrorCode(hostconfig.OptionErrorCodePooledFixed) )
type Options ¶
type Options struct {
// HostID identifies this Host to Factory and in HostLink bindings.
HostID sessionwire.HostID
// InternalEndpoint is the credential-free WebSocket address Factory dials.
InternalEndpoint sessionwire.InternalEndpoint
// IsolationClass is advertised with capacity so Factory can place
// cross-tenant work correctly, AND IT IS THIS HOST'S POOLED ADMISSION RULE.
//
// THERE IS NO TenantID BESIDE IT, and that is human gate H8, answered
// 2026-09-04: a Host advertising cross_tenant_isolated may hold several
// tenants resident; one advertising tenant_exclusive is exclusive by
// PLACEMENT, not by construction. The admission ledger holds the local
// backstop.
IsolationClass sessionwire.HostIsolationClass
// Department is the immutable set of launch targets this Host serves.
Department *department.Department
// SessionStore, Workspaces, Clock and Auth are Host's collaborators.
SessionStore SessionStore
Workspaces WorkspaceProvider
Clock Clock
Auth AuthVerifier
// Placement is the admission model this Host runs under.
Placement sessionwire.HostPlacement
// Capacity is how many sessions this Host may hold resident. Dedicated
// placement requires exactly one.
Capacity uint64
// FixedSessionID binds a dedicated Host to one session for its lifetime. It
// is REQUIRED for dedicated placement and REJECTED for pooled.
FixedSessionID sessionwire.SessionID
// WarmTTL is how long a released session stays warm before drain.
WarmTTL time.Duration
// RegistryHeartbeat and RegistryExpiry are the advertisement lifetime.
RegistryHeartbeat time.Duration
RegistryExpiry time.Duration
// ClaimTTL and ApplyDeadline bound command application.
ClaimTTL time.Duration
ApplyDeadline time.Duration
// CommandQueueSize is the inbound command buffer.
CommandQueueSize int
// ReconcileInterval and ReconcileBatch bound reconciliation.
ReconcileInterval time.Duration
ReconcileBatch int
}
Options configures a Host. Every field is required unless its documentation says otherwise; nothing here is discovered, and there is no package-global default Host to fall back on.
type Registrar ¶
type Registrar interface {
Register(context.Context) ([]department.Registration, error)
}
Registrar produces the Department registrations one deployment serves.
IT IS CALLED ONCE, AT STARTUP, AND ITS RESULT IS IMMUTABLE. Department.New validates the registrations and fixes them for the life of the process, so a Registrar that answered differently later would be answering a question nobody asks again. It takes a context because building a launch target may require I/O — reading a model catalogue, resolving a runtime build — and a startup that can block must be cancellable.
type RegistrarFunc ¶
type RegistrarFunc func(context.Context) ([]department.Registration, error)
RegistrarFunc adapts a function to Registrar.
func (RegistrarFunc) Register ¶
func (f RegistrarFunc) Register(ctx context.Context) ([]department.Registration, error)
Register calls f.
type Residency ¶ added in v0.2.0
type Residency struct {
TenantID sessionwire.TenantID
SessionID sessionwire.SessionID
AgentID sessionwire.AgentID
RuntimeCompatibilityID string
// LeaseEpoch is this Host's residency grant: the value a bind presents.
LeaseEpoch uint64
// JournalEpoch is the RUNTIME's grant, read from the launched runtime and
// never derived from LeaseEpoch; JournalEpochHeld is the half to branch
// on, since a headless runtime legitimately holds none.
JournalEpoch uint64
JournalEpochHeld bool
// Attached reports whether THIS call established the residency. False
// means the session was already resident and this call took nothing.
Attached bool
}
Residency is what an attach reports.
type RigSessionIDs ¶ added in v0.2.0
type RigSessionIDs func(context.Context, sessionwire.TenantID, sessionwire.SessionID) (uuid.UUID, error)
RigSessionIDs answers Harness's own identity for a session, which no released record holds. It is REQUIRED, and the reason is narrower than "restores need it": the store adapter refuses a hydration of ANY session that has a catalog record and no answer here, in both modes — and in production every session a Host is asked to attach has one, because Factory creates the record before it places. A Host composed without this could attach only a session nobody had created. The product that recorded the identity is the only thing that can answer; a deployment with no such record answers with an error, which refuses the attach rather than handing Harness a zero identity.
type Service ¶ added in v0.2.0
type Service struct {
// contains filtered or unexported fields
}
Service is one composed Host: built, then started, then stopped.
func Compose ¶ added in v0.2.0
func Compose(ctx context.Context, blueprint Composition) (*Service, error)
Compose validates the composition, opens the session store, builds the Department and every collaborator, and returns a Service with nothing running.
COMPOSE OPENS THE STORE ITSELF, and that is the whole reason Collaborators carries a Backend and not a *sessionstore.Store. Settlement refuses without a configured evidence reader, and the released store publishes no way to ask an open one whether it has one; a deployment that opened the store and forgot the reader would attach, list, claim, dispatch, and fail at every settlement, leaving each command applying with a real effect behind it. Opening here means the router built from JournalStores is installed on every store this composition can run on, so that failure is unrepresentable rather than documented. Compose closes the store on any later refusal.
func (*Service) Attach ¶ added in v0.2.0
Attach makes a session resident on this Host, in process.
It is the SAME entry point the hostlink.attach RPC reaches, so its semantics are the RPC's: serialized per session, idempotent on a resident session (Attached false, the existing epoch), refused with a HostLink class where placement should be re-run and with none where it should not.
func (*Service) Department ¶ added in v0.2.0
func (s *Service) Department() *department.Department
Department is the immutable set of launch targets this Service serves.
func (*Service) Handler ¶ added in v0.2.0
Handler serves HostLink at HostLinkPathPrefix + the tenant.
func (*Service) Live ¶ added in v0.2.0
Live reports whether this process should keep running: the liveness probe's answer. It stays true throughout and after a drain and turns false only when Stop has run, so a platform never kills a Host mid-checkpoint or before it has answered `drained` over HostLink.
func (*Service) MetricsHandler ¶ added in v0.2.0
MetricsHandler serves this Host's Prometheus series, and only this Host's: the registry behind it holds one collector rather than the default registry's process, Go and dependency series. It is a handler and not a prometheus.Collector so that client_golang's types stay out of this API.
func (*Service) Ready ¶ added in v0.2.0
Ready reports whether this Host is ACCEPTING: the readiness probe's answer. A draining Host is not ready from the instant its ledger flips.
func (*Service) Routes ¶ added in v0.2.0
Routes serves HostLink, the two probes and the metrics on one handler: HostLinkPathPrefix, /readyz (Ready), /healthz (Live) and /metrics. It is what Run mounts, exported so a binary that owns its listener can mount the same four routes beside its own.
func (*Service) Start ¶ added in v0.2.0
Start publishes this Host's advertisements and begins its heartbeat. The first publication is synchronous, so a Host whose directory refuses it fails here rather than running invisibly. A Service starts once.
func (*Service) Stop ¶ added in v0.2.0
func (s *Service) Stop(ctx context.Context) (DrainReport, error)
Stop drains this Host, waits for the drain to finish, closes every tenant transport, and then closes the session store Compose opened. The store is last because everything before it may still write.
type SessionStore ¶
type SessionStore interface {
// LoadSession returns the durable record for a session, or an error the
// caller can classify.
LoadSession(context.Context, sessionwire.TenantID, sessionwire.SessionID) ([]byte, error)
}
SessionStore is the durable session state Host reads and writes.
type WarmTimer ¶ added in v0.2.0
WarmTimer is one session's warm countdown, in time.Timer's own three methods.
type WorkspaceProvider ¶
type WorkspaceProvider interface {
// EnsureWorkspace makes a workspace available and returns its root.
EnsureWorkspace(context.Context, sessionwire.TenantID, sessionwire.SessionID) (string, error)
}
WorkspaceProvider materializes session workspaces.
It does NOT checkpoint them; see Checkpointer for that half. Nor does it release them: the composition needs the release half too, which is Workspaces, and it is Workspaces a composition takes.
type Workspaces ¶ added in v0.2.0
type Workspaces interface {
EnsureWorkspace(context.Context, sessionwire.TenantID, sessionwire.SessionID) (string, error)
// ReleaseWorkspace drops the local materialization. It never deletes
// durable state.
ReleaseWorkspace(context.Context, sessionwire.TenantID, sessionwire.SessionID) error
}
Workspaces materializes and releases session workspaces. It is WorkspaceProvider plus the release half the composition's warm release and drain need; a value satisfying it satisfies WorkspaceProvider too.
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
host
command
Command host runs one headless Department runtime host.
|
Command host runs one headless Department runtime host. |
|
Package department defines the immutable set of launch targets a Host serves.
|
Package department defines the immutable set of launch targets a Host serves. |
|
internal
|
|
|
commands
Applying an admitted command is §10.4's durable protocol around ONE call into a runtime, and this file is that protocol.
|
Applying an admitted command is §10.4's durable protocol around ONE call into a runtime, and this file is that protocol. |
|
compose
Package compose is Host's composition root: it builds the Department runtime, the residency manager, the command consumers, the live event relay, the per-tenant HostLink servers, the metrics and the drain into one running service, with an explicit start and stop order.
|
Package compose is Host's composition root: it builds the Department runtime, the residency manager, the command consumers, the live event relay, the per-tenant HostLink servers, the metrics and the drain into one running service, with an explicit start and stop order. |
|
harnessadapter
Package harnessadapter binds Host's department seams to the released github.com/looprig/harness v0.33.0 rig and session API.
|
Package harnessadapter binds Host's department seams to the released github.com/looprig/harness v0.33.0 rig and session API. |
|
lifecycle
Package lifecycle owns this Host's drain: the single-owner state machine that stops admission, releases every resident session in order, and reports when the Host is drained.
|
Package lifecycle owns this Host's drain: the single-owner state machine that stops admission, releases every resident session in order, and reports when the Host is drained. |
|
modfiles
Package modfiles enumerates Go source files owned by this module while excluding structural directories and nested repository or module boundaries.
|
Package modfiles enumerates Go source files owned by this module while excluding structural directories and nested repository or module boundaries. |
|
modfiles/cmd/modfiles
command
|
|
|
realtime/hostlink
Package hostlink owns the authenticated realtime server used by Factory to reach one Host.
|
Package hostlink owns the authenticated realtime server used by Factory to reach one Host. |
|
registry
Package registry indexes the sessions a Host currently holds resident.
|
Package registry indexes the sessions a Host currently holds resident. |
|
residency
Package residency creates and restores sessions under the durable session lease, in one fixed order, and releases everything it took when any step of that order fails.
|
Package residency creates and restores sessions under the durable session lease, in one fixed order, and releases everything it took when any step of that order fails. |
|
service
Package service derives what a Host publishes about itself, and relays what its resident sessions have already committed.
|
Package service derives what a Host publishes about itself, and relays what its resident sessions have already committed. |
|
sessionstoreadapter
Package sessionstoreadapter binds Host's narrow local store seams to the released github.com/looprig/sessionstore v0.7.0 Store.
|
Package sessionstoreadapter binds Host's narrow local store seams to the released github.com/looprig/sessionstore v0.7.0 Store. |
|
settlement
Package settlement holds the end-to-end proof that one command APPLIES and SETTLES across the three modules that had to release for it to be possible.
|
Package settlement holds the end-to-end proof that one command APPLIES and SETTLES across the three modules that had to release for it to be possible. |
|
testkit
Package testkit holds test doubles shared by this module's tests.
|
Package testkit holds test doubles shared by this module's tests. |