Add persistent Run control stream
This commit is contained in:
@@ -2,6 +2,12 @@ package protocol
|
||||
|
||||
import "time"
|
||||
|
||||
const (
|
||||
RunControlEventTypeReady = "control.ready"
|
||||
RunControlEventTypeHeartbeat = "control.heartbeat"
|
||||
RunControlEventTypeJobChanged = "job.changed"
|
||||
)
|
||||
|
||||
type RunCapacityReport struct {
|
||||
MaxJobs int `json:"maxJobs"`
|
||||
RunningJobs int `json:"runningJobs"`
|
||||
@@ -60,6 +66,20 @@ type RunHeartbeatResponse struct {
|
||||
ServerTime time.Time `json:"serverTime"`
|
||||
}
|
||||
|
||||
type RunControlStreamRequest struct {
|
||||
RunEndpointID string `json:"runEndpointId"`
|
||||
SessionToken string `json:"sessionToken"`
|
||||
LastEventSeq uint64 `json:"lastEventSeq,omitempty"`
|
||||
}
|
||||
|
||||
type RunControlEvent struct {
|
||||
RunEndpointID string `json:"runEndpointId"`
|
||||
Sequence uint64 `json:"sequence"`
|
||||
Type string `json:"type"`
|
||||
ServerTime time.Time `json:"serverTime"`
|
||||
RetrySeconds int `json:"retrySeconds,omitempty"`
|
||||
}
|
||||
|
||||
type RunLifecycleReportRequest struct {
|
||||
RunEndpointID string `json:"runEndpointId"`
|
||||
SessionToken string `json:"sessionToken"`
|
||||
|
||||
@@ -6,6 +6,7 @@ Control is the lightweight high-priority channel between run and platform.
|
||||
|
||||
- `POST /api/v1/run/control/hello`: registers run metadata and receives a platform-issued session token.
|
||||
- `POST /api/v1/run/control/heartbeat`: reports status, capacity, and capability fingerprint using the active session token.
|
||||
- `POST /api/v1/run/control/events`: opens a signed `text/event-stream` control channel. Platform sends small wake events such as `control.ready`, `control.heartbeat`, and `job.changed`; Run then claims durable jobs through the job channel.
|
||||
|
||||
## Payloads
|
||||
|
||||
@@ -13,12 +14,15 @@ Control is the lightweight high-priority channel between run and platform.
|
||||
- `RunHelloResponse`: session token, server time, polling hints, and feature flags.
|
||||
- `RunHeartbeatRequest`: session token, version, status, capacity, and current capability fingerprint.
|
||||
- `RunHeartbeatResponse`: accepted status, next heartbeat interval, and optional capability refresh request.
|
||||
- `RunControlStreamRequest`: run ID, session token, and the last event sequence observed by Run.
|
||||
- `RunControlEvent`: run ID, monotonic endpoint-local sequence, event type, server time, and reconnect hint.
|
||||
- `RunCapabilityReport`: capability names and compact fingerprint metadata.
|
||||
- `RunCapacityReport`: max jobs, active jobs, queued jobs, and local resource summary.
|
||||
|
||||
## Rules
|
||||
|
||||
- Control payloads must be small.
|
||||
- Control events wake Run only; they must not carry job assignments or execution input.
|
||||
- Control must not carry logs, artifact chunks, or long job result bodies.
|
||||
- Control must have priority over job execution, log upload, and artifact transfer.
|
||||
- Heartbeat capacity summaries must remain metadata-only and must not mention or carry heavy channel payloads.
|
||||
|
||||
+3
-2
@@ -4,7 +4,7 @@ Jobs execute bounded server management work.
|
||||
|
||||
## Implemented Routes
|
||||
|
||||
- `POST /api/v1/run/jobs/claim`: claims one queued job for the registered run endpoint, optionally holding the request for a bounded wait window so Platform can wake Run immediately when work arrives.
|
||||
- `POST /api/v1/run/jobs/claim`: claims one queued job for the registered run endpoint. New workers are normally awakened by the persistent control event stream and claim without holding this request; older workers may still use a bounded `waitSeconds` long-poll fallback.
|
||||
- `POST /api/v1/run/jobs/ack`: acknowledges an active leased job before execution.
|
||||
- `POST /api/v1/run/jobs/progress`: reports bounded progress for an active leased job.
|
||||
- `POST /api/v1/run/jobs/result`: submits a bounded terminal result for an active leased job.
|
||||
@@ -17,7 +17,7 @@ Jobs execute bounded server management work.
|
||||
|
||||
## Payloads
|
||||
|
||||
- `RunJobClaimRequest`: session token, run ID, capacity, supported capabilities, and optional `waitSeconds` for long-poll claim waiting.
|
||||
- `RunJobClaimRequest`: session token, run ID, capacity, supported capabilities, and optional `waitSeconds` for legacy long-poll claim waiting.
|
||||
- `RunJobClaimResponse`: optional job assignment with identity, capability, server instance, logical target key, scoped input ref, idempotency key, per-job attempt, max attempts, raw one-use lease token, ack deadline, execution lease deadline, and polling hint. Platform persists only the lease hash.
|
||||
- `RunJobAckRequest`: job ID, run ID, session token, lease token, attempt, and bounded message.
|
||||
- `RunJobProgressRequest`: job ID, run ID, session token, lease token, attempt, percent, sequence, and bounded message.
|
||||
@@ -78,6 +78,7 @@ The executor resolves lifecycle action templates under the scoped server workspa
|
||||
- Job payloads must not include logs, artifact chunks, raw host paths, raw credentials, direct sockets, or large inline result bodies.
|
||||
- Process stdout/stderr must be redacted and written to the log spool rather than embedded in progress/result bodies.
|
||||
- Job ack/progress/result/cancel/reconcile calls are lightweight lifecycle metadata and must be able to complete while artifact/file transfer work is active or retrying.
|
||||
- Persistent control events are hints only. Run must still claim, ack, execute, and complete durable jobs through this job channel so retries, leases, and idempotency stay platform-authoritative.
|
||||
- Dependency adapters and update downloads run in the job worker while control heartbeat, cancellation polling, log spool upload, and artifact upload retain independent bounded loops.
|
||||
- Terminal results must remain idempotent under log and artifact retry pressure and must reference artifacts by safe `artifact://...` refs rather than embedding transfer payloads.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user