Documentation
¶
Overview ¶
Package await is CSF's wait primitive: one typed operation that waits for a condition from a closed set, up to a required deadline, and reports what it saw. The CSF service serves it over MCP and HTTP, csf await is its thin client, and csf serve -detach and csf stop return through it.
Every wait polls through eventually.Until on the granted clock, so a spec moves time itself. A condition reads only the capabilities the binary grants; a condition whose capability is missing is refused, never waited on.
Index ¶
Constants ¶
const ( AwaitTool = "Await" AwaitPath = "/api/await" )
The await operation: one MCP tool on the CSF service and one HTTP route on the host's router; csf await is a client of the route.
const HostRecordFile = "harness.json"
HostRecordFile is the host record csf serve writes under its state directory once it is ready, and removes as it stops.
Variables ¶
var ( ErrUnknownCondition = errors.New("await: unknown condition") ErrNoDeadline = errors.New("await: a positive deadline is required") ErrMissingOperand = errors.New("await: the condition is missing an operand") ErrInvalidOption = errors.New("await: invalid option") )
The refusals: each is a misuse the caller fixes, wrapped with what was wrong.
Functions ¶
Types ¶
type Awaiter ¶
type Awaiter struct {
// contains filtered or unexported fields
}
Awaiter waits for conditions with the capabilities its binary granted.
func NewAwaiter ¶
NewAwaiter validates the whole option set before building the awaiter.
func (*Awaiter) Await ¶
Await waits for the request's condition until its deadline and reports the outcome. Only a misuse is an error; a deadline reached is a result.
type Condition ¶
type Condition string
Condition names one thing a wait can wait for. The set is closed.
const ( // ConditionHarnessReady holds once the host has written its record: it // listens, its database is healthy and its open runs are resumed. ConditionHarnessReady Condition = "harness-ready" // ConditionHarnessStopped holds once the host process has exited. ConditionHarnessStopped Condition = "harness-stopped" // ConditionSessionPhase holds once a session is in the named phase. ConditionSessionPhase Condition = "session-phase" // ConditionTurnFinished holds once a session has no turn running and none // queued, at or after the named turn. ConditionTurnFinished Condition = "turn-finished" // ConditionPullRequestMerged holds once a pull request is merged. ConditionPullRequestMerged Condition = "pull-request-merged" // ConditionURLStatus holds once a URL answers GET with the named status. ConditionURLStatus Condition = "url-status" // ConditionLoadBelow holds once the one-minute load average is below the // named level. ConditionLoadBelow Condition = "load-below" )
The conditions, as csf await and the operation spell them.
func Conditions ¶
func Conditions() []Condition
Conditions lists the closed set of conditions, sorted.
type HostRecord ¶
type HostRecord struct {
PID int `json:"pid"`
Endpoint string `json:"endpoint"`
Listen []string `json:"listen"`
StartedAt time.Time `json:"started_at"`
}
HostRecord is the host record: the host process, where it listens and when it started.
func ReadHostRecord ¶
func ReadHostRecord(state iofs.IFiles) (HostRecord, bool, error)
ReadHostRecord reads the host record from the state directory, reporting whether one exists.
type Option ¶
Option grants an Awaiter one capability.
func WithClock ¶
func WithClock(clock eventually.IClock) Option
WithClock grants the clock every deadline is read on. It is required.
func WithHTTPClient ¶
func WithHTTPClient(client iohttp.IHTTPClient) Option
WithHTTPClient grants the client url-status sends its GET through.
func WithHostState ¶
WithHostState grants the host's state directory, which holds the host record harness-ready and harness-stopped read.
func WithLauncher ¶
WithLauncher grants the launcher gh runs through for pull-request-merged.
func WithProcessTable ¶
WithProcessTable grants the process table, as /proc: whether a process runs, and the load average.
func WithSessionState ¶
func WithSessionState(sessions SessionState) Option
WithSessionState grants the read of a session's state.
type Outcome ¶
type Outcome string
Outcome is how a wait ended.
const ( // OutcomeMet is a condition that held before the deadline. OutcomeMet Outcome = "met" // OutcomeDeadline is a deadline reached with the condition not held. OutcomeDeadline Outcome = "deadline" // OutcomeUnreachable is a condition that can no longer hold: the process // awaited exited, the session ended in another phase, the pull request // was closed. OutcomeUnreachable Outcome = "unreachable" )
type Request ¶
type Request struct {
Condition Condition `` /* 142-byte string literal not displayed */
Deadline string `json:"deadline" jsonschema:"how long to wait at most, a Go duration such as 90s or 10m; required"`
// PID names the host process for harness-ready and harness-stopped;
// zero means the one the host record names.
PID int `json:"pid,omitempty" jsonschema:"harness-ready, harness-stopped: the host process; default the one the host record names"`
// Assignment names the session for session-phase and turn-finished.
Assignment string `json:"assignment,omitempty" jsonschema:"session-phase, turn-finished: the session's assignment identifier"`
// Phase is the session phase awaited, such as OPEN or RUNNING.
Phase string `json:"phase,omitempty" jsonschema:"session-phase: STARTING, RUNNING, OPEN, CANCELING, CANCELED, FAILED or CLOSED"`
// Turn is the turn that must have finished; zero means the latest.
Turn uint32 `json:"turn,omitempty" jsonschema:"turn-finished: the turn that must have finished; default the latest"`
// PullRequest is the pull request's URL, or its number with Repository.
PullRequest string `json:"pull_request,omitempty" jsonschema:"pull-request-merged: the pull request's URL, or its number with repository"`
Repository string `json:"repository,omitempty" jsonschema:"pull-request-merged: OWNER/NAME when pull_request is a number"`
// URL and Status name the GET and the status it must answer.
URL string `json:"url,omitempty" jsonschema:"url-status: the URL to GET"`
Status int `json:"status,omitempty" jsonschema:"url-status: the HTTP status awaited; default 200"`
// Load is the level the one-minute load average must fall below.
Load float64 `json:"load,omitempty" jsonschema:"load-below: the one-minute load average must fall below this"`
}
Request is one wait: the condition, its deadline and the operands the condition reads. Only the operands of the named condition are read.
type Result ¶
type Result struct {
Condition Condition `json:"condition"`
Outcome Outcome `json:"outcome"`
ElapsedMS int64 `json:"elapsed_ms"`
Polls int `json:"polls"`
Observation string `json:"observation"`
}
Result is what a wait reports: the condition, how it ended, how long it took and the last thing it observed.
type SessionState ¶
type SessionState func(ctx context.Context, assignment string) (*harnessv1.AgentSessionState, error)
SessionState reads one session's state by its assignment identifier.