feat(workspace): persist runtime worker projection
This commit is contained in:
@@ -232,6 +232,8 @@ export type SubscriptionWorkerIds = Array<SubscriptionWorkerId>;
|
||||
|
||||
export type SubscriptionWorkerState = "idle" | "running" | "paused" | "stopped";
|
||||
|
||||
export type SubscriptionWorkerAvailability = "observed" | "unavailable";
|
||||
|
||||
export type EventSubscriptionSelector = { "topic": "runtime_workers" } | { "topic": "worker_lifecycle", worker_ids: SubscriptionWorkerIds, } | { "topic": "worker_protocol", worker_id: SubscriptionWorkerId, runtime_id?: string | null, } | { "topic": "workspace_workers" } | { "topic": "workspace_workdirs" };
|
||||
|
||||
export type SubscriptionWorker = { worker_id: SubscriptionWorkerId,
|
||||
@@ -245,6 +247,11 @@ runtime_id?: string | null,
|
||||
* Workspace-facing projections must populate it before publishing the Worker.
|
||||
*/
|
||||
resource_key?: string | null,
|
||||
/**
|
||||
* Freshness of the Runtime-backed observation carried by this projection.
|
||||
* `Unavailable` preserves catalog membership without claiming that execution stopped.
|
||||
*/
|
||||
availability: SubscriptionWorkerAvailability,
|
||||
/**
|
||||
* Producer-owned monotonic revision for this Worker subject.
|
||||
*/
|
||||
|
||||
@@ -2,8 +2,10 @@ import type { WorkerStateSnapshot } from "$lib/generated/protocol";
|
||||
|
||||
export function liveWorkerState(worker: {
|
||||
state: string;
|
||||
availability?: "observed" | "unavailable";
|
||||
worker_state?: WorkerStateSnapshot | null;
|
||||
}): string {
|
||||
if (worker.availability === "unavailable") return "unknown";
|
||||
const state = worker.worker_state?.state;
|
||||
if (!state) {
|
||||
if (worker.state === "missing" || worker.state === "stopped") {
|
||||
|
||||
@@ -20,10 +20,12 @@ function worker(
|
||||
workerId: string,
|
||||
revision: number,
|
||||
hasRunningInternalWorkers = false,
|
||||
availability: 'observed' | 'unavailable' = 'observed',
|
||||
): SubscriptionWorker {
|
||||
return {
|
||||
worker_id: workerId,
|
||||
runtime_id: runtimeId,
|
||||
availability,
|
||||
subject_revision: revision,
|
||||
state: 'idle',
|
||||
has_running_internal_workers: hasRunningInternalWorkers,
|
||||
@@ -42,12 +44,23 @@ Deno.test('Worker list state uses the authoritative live snapshot separately fro
|
||||
};
|
||||
assertEquals(liveWorkerState(active), 'paused');
|
||||
|
||||
const unavailable = worker('runtime-a', 'worker-2', 1);
|
||||
const unavailable = worker('runtime-a', 'worker-2', 1, false, 'unavailable');
|
||||
unavailable.worker_state = {
|
||||
last_command_id: 2,
|
||||
state: { kind: 'busy', state: { kind: 'run', state: 'running' } },
|
||||
};
|
||||
assertEquals(liveWorkerState(unavailable), 'unknown');
|
||||
assertEquals(
|
||||
liveWorkerState({ ...unavailable, state: 'missing' }),
|
||||
liveWorkerState({
|
||||
...unavailable,
|
||||
availability: 'observed',
|
||||
worker_state: null,
|
||||
state: 'missing',
|
||||
}),
|
||||
'missing',
|
||||
);
|
||||
unavailable.availability = 'observed';
|
||||
unavailable.worker_state = null;
|
||||
unavailable.state = 'stopped';
|
||||
assertEquals(liveWorkerState(unavailable), 'stopped');
|
||||
});
|
||||
|
||||
@@ -100,7 +100,7 @@ function projectWorker(worker: SubscriptionWorker): SidebarWorker {
|
||||
display_hint: 'Workspace-authorized Runtime Worker',
|
||||
},
|
||||
capabilities: {
|
||||
can_stop: worker.state !== 'stopped',
|
||||
can_stop: worker.availability !== 'unavailable' && worker.state !== 'stopped',
|
||||
can_spawn_followup: false,
|
||||
},
|
||||
repository_key: worker.repository_key ?? null,
|
||||
|
||||
Reference in New Issue
Block a user