@taskcast/core 0.1.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.d.ts +18 -3
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +48 -17
- package/dist/config.js.map +1 -1
- package/dist/engine.d.ts +20 -4
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +45 -22
- package/dist/engine.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/memory-adapters.d.ts +13 -1
- package/dist/memory-adapters.d.ts.map +1 -1
- package/dist/memory-adapters.js +85 -0
- package/dist/memory-adapters.js.map +1 -1
- package/dist/state-machine.d.ts +2 -0
- package/dist/state-machine.d.ts.map +1 -1
- package/dist/state-machine.js +12 -2
- package/dist/state-machine.js.map +1 -1
- package/dist/types.d.ts +76 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/worker-manager.d.ts +67 -0
- package/dist/worker-manager.d.ts.map +1 -0
- package/dist/worker-manager.js +312 -0
- package/dist/worker-manager.js.map +1 -0
- package/dist/worker-matching.d.ts +23 -0
- package/dist/worker-matching.d.ts.map +1 -0
- package/dist/worker-matching.js +50 -0
- package/dist/worker-matching.js.map +1 -0
- package/package.json +1 -1
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type TaskStatus = 'pending' | 'running' | 'completed' | 'failed' | 'timeout' | 'cancelled';
|
|
1
|
+
export type TaskStatus = 'pending' | 'assigned' | 'running' | 'paused' | 'blocked' | 'completed' | 'failed' | 'timeout' | 'cancelled';
|
|
2
2
|
export interface TaskError {
|
|
3
3
|
code?: string;
|
|
4
4
|
message: string;
|
|
@@ -31,7 +31,7 @@ export interface RetryConfig {
|
|
|
31
31
|
}
|
|
32
32
|
export type SeriesMode = 'keep-all' | 'accumulate' | 'latest';
|
|
33
33
|
export type Level = 'debug' | 'info' | 'warn' | 'error';
|
|
34
|
-
export type PermissionScope = 'task:create' | 'task:manage' | 'event:publish' | 'event:subscribe' | 'event:history' | 'webhook:create' | '*';
|
|
34
|
+
export type PermissionScope = 'task:create' | 'task:manage' | 'event:publish' | 'event:subscribe' | 'event:history' | 'webhook:create' | 'worker:connect' | 'worker:manage' | '*';
|
|
35
35
|
export interface CleanupRule {
|
|
36
36
|
name?: string;
|
|
37
37
|
match?: {
|
|
@@ -49,6 +49,45 @@ export interface CleanupRule {
|
|
|
49
49
|
seriesMode?: SeriesMode[];
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
|
+
export type AssignMode = 'external' | 'pull' | 'ws-offer' | 'ws-race';
|
|
53
|
+
export type DisconnectPolicy = 'reassign' | 'mark' | 'fail';
|
|
54
|
+
export type WorkerStatus = 'idle' | 'busy' | 'draining' | 'offline';
|
|
55
|
+
export interface TagMatcher {
|
|
56
|
+
all?: string[];
|
|
57
|
+
any?: string[];
|
|
58
|
+
none?: string[];
|
|
59
|
+
}
|
|
60
|
+
export interface WorkerMatchRule {
|
|
61
|
+
taskTypes?: string[];
|
|
62
|
+
tags?: TagMatcher;
|
|
63
|
+
}
|
|
64
|
+
export interface Worker {
|
|
65
|
+
id: string;
|
|
66
|
+
status: WorkerStatus;
|
|
67
|
+
matchRule: WorkerMatchRule;
|
|
68
|
+
capacity: number;
|
|
69
|
+
usedSlots: number;
|
|
70
|
+
weight: number;
|
|
71
|
+
connectionMode: 'pull' | 'websocket';
|
|
72
|
+
connectedAt: number;
|
|
73
|
+
lastHeartbeatAt: number;
|
|
74
|
+
metadata?: Record<string, unknown>;
|
|
75
|
+
}
|
|
76
|
+
export type WorkerAssignmentStatus = 'offered' | 'assigned' | 'running';
|
|
77
|
+
export interface WorkerAssignment {
|
|
78
|
+
taskId: string;
|
|
79
|
+
workerId: string;
|
|
80
|
+
cost: number;
|
|
81
|
+
assignedAt: number;
|
|
82
|
+
status: WorkerAssignmentStatus;
|
|
83
|
+
}
|
|
84
|
+
export interface WorkerAuditEvent {
|
|
85
|
+
id: string;
|
|
86
|
+
workerId: string;
|
|
87
|
+
timestamp: number;
|
|
88
|
+
action: 'connected' | 'disconnected' | 'updated' | 'task_assigned' | 'task_declined' | 'task_reclaimed' | 'draining' | 'heartbeat_timeout' | 'pull_request';
|
|
89
|
+
data?: Record<string, unknown>;
|
|
90
|
+
}
|
|
52
91
|
export interface Task {
|
|
53
92
|
id: string;
|
|
54
93
|
type?: string;
|
|
@@ -66,6 +105,11 @@ export interface Task {
|
|
|
66
105
|
cleanup?: {
|
|
67
106
|
rules: CleanupRule[];
|
|
68
107
|
};
|
|
108
|
+
tags?: string[];
|
|
109
|
+
assignMode?: AssignMode;
|
|
110
|
+
cost?: number;
|
|
111
|
+
assignedWorker?: string;
|
|
112
|
+
disconnectPolicy?: DisconnectPolicy;
|
|
69
113
|
}
|
|
70
114
|
export interface TaskEvent {
|
|
71
115
|
id: string;
|
|
@@ -121,12 +165,36 @@ export interface ShortTermStore {
|
|
|
121
165
|
getSeriesLatest(taskId: string, seriesId: string): Promise<TaskEvent | null>;
|
|
122
166
|
setSeriesLatest(taskId: string, seriesId: string, event: TaskEvent): Promise<void>;
|
|
123
167
|
replaceLastSeriesEvent(taskId: string, seriesId: string, event: TaskEvent): Promise<void>;
|
|
168
|
+
listTasks(filter: TaskFilter): Promise<Task[]>;
|
|
169
|
+
saveWorker(worker: Worker): Promise<void>;
|
|
170
|
+
getWorker(workerId: string): Promise<Worker | null>;
|
|
171
|
+
listWorkers(filter?: WorkerFilter): Promise<Worker[]>;
|
|
172
|
+
deleteWorker(workerId: string): Promise<void>;
|
|
173
|
+
claimTask(taskId: string, workerId: string, cost: number): Promise<boolean>;
|
|
174
|
+
addAssignment(assignment: WorkerAssignment): Promise<void>;
|
|
175
|
+
removeAssignment(taskId: string): Promise<void>;
|
|
176
|
+
getWorkerAssignments(workerId: string): Promise<WorkerAssignment[]>;
|
|
177
|
+
getTaskAssignment(taskId: string): Promise<WorkerAssignment | null>;
|
|
124
178
|
}
|
|
125
179
|
export interface LongTermStore {
|
|
126
180
|
saveTask(task: Task): Promise<void>;
|
|
127
181
|
getTask(taskId: string): Promise<Task | null>;
|
|
128
182
|
saveEvent(event: TaskEvent): Promise<void>;
|
|
129
183
|
getEvents(taskId: string, opts?: EventQueryOptions): Promise<TaskEvent[]>;
|
|
184
|
+
saveWorkerEvent(event: WorkerAuditEvent): Promise<void>;
|
|
185
|
+
getWorkerEvents(workerId: string, opts?: EventQueryOptions): Promise<WorkerAuditEvent[]>;
|
|
186
|
+
}
|
|
187
|
+
export interface TaskFilter {
|
|
188
|
+
status?: TaskStatus[];
|
|
189
|
+
types?: string[];
|
|
190
|
+
tags?: TagMatcher;
|
|
191
|
+
assignMode?: AssignMode[];
|
|
192
|
+
excludeTaskIds?: string[];
|
|
193
|
+
limit?: number;
|
|
194
|
+
}
|
|
195
|
+
export interface WorkerFilter {
|
|
196
|
+
status?: WorkerStatus[];
|
|
197
|
+
connectionMode?: ('pull' | 'websocket')[];
|
|
130
198
|
}
|
|
131
199
|
export interface ErrorContext {
|
|
132
200
|
operation: string;
|
|
@@ -140,5 +208,11 @@ export interface TaskcastHooks {
|
|
|
140
208
|
onWebhookFailed?(config: WebhookConfig, err: unknown): void;
|
|
141
209
|
onSSEConnect?(taskId: string, clientId: string): void;
|
|
142
210
|
onSSEDisconnect?(taskId: string, clientId: string, duration: number): void;
|
|
211
|
+
onTaskCreated?(task: Task): void;
|
|
212
|
+
onTaskTransitioned?(task: Task, from: TaskStatus, to: TaskStatus): void;
|
|
213
|
+
onWorkerConnected?(worker: Worker): void;
|
|
214
|
+
onWorkerDisconnected?(worker: Worker, reason: string): void;
|
|
215
|
+
onTaskAssigned?(task: Task, worker: Worker): void;
|
|
216
|
+
onTaskDeclined?(task: Task, worker: Worker, blacklisted: boolean): void;
|
|
143
217
|
}
|
|
144
218
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,UAAU,GAClB,SAAS,GACT,SAAS,GACT,WAAW,GACX,QAAQ,GACR,SAAS,GACT,WAAW,CAAA;AAEf,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAClC;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,KAAK,CAAC;QACX,KAAK,EAAE;YAAE,KAAK,EAAE,eAAe,EAAE,CAAA;SAAE,CAAA;QACnC,OAAO,EAAE;YACP,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;YAChC,GAAG,CAAC,EAAE,MAAM,EAAE,CAAA;SACf,CAAA;KACF,CAAC,CAAA;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE,eAAe,CAAA;IACxB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,KAAK,CAAC,EAAE,WAAW,CAAA;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,OAAO,GAAG,aAAa,GAAG,QAAQ,CAAA;IAC3C,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,YAAY,GAAG,QAAQ,CAAA;AAE7D,MAAM,MAAM,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;AAEvD,MAAM,MAAM,eAAe,GACvB,aAAa,GACb,aAAa,GACb,eAAe,GACf,iBAAiB,GACjB,eAAe,GACf,gBAAgB,GAChB,GAAG,CAAA;AAEP,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE;QACN,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;QACpB,MAAM,CAAC,EAAE,UAAU,EAAE,CAAA;KACtB,CAAA;IACD,OAAO,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAA;KACjB,CAAA;IACD,MAAM,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAA;IACjC,WAAW,CAAC,EAAE;QACZ,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;QAChB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAA;QAChB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,UAAU,CAAC,EAAE,UAAU,EAAE,CAAA;KAC1B,CAAA;CACF;AAED,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,UAAU,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,cAAc,CAAA;IAC3B,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAA;IAC1B,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,WAAW,EAAE,CAAA;KAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { Task, Worker, WorkerFilter, WorkerAssignment, BroadcastProvider, ShortTermStore, LongTermStore, TaskcastHooks, AssignMode, DisconnectPolicy, WorkerMatchRule } from './types.js';
|
|
2
|
+
import type { TaskEngine } from './engine.js';
|
|
3
|
+
export interface WorkerManagerOptions {
|
|
4
|
+
engine: TaskEngine;
|
|
5
|
+
shortTermStore: ShortTermStore;
|
|
6
|
+
broadcast: BroadcastProvider;
|
|
7
|
+
longTermStore?: LongTermStore;
|
|
8
|
+
hooks?: TaskcastHooks;
|
|
9
|
+
defaults?: WorkerManagerDefaults;
|
|
10
|
+
}
|
|
11
|
+
export interface WorkerManagerDefaults {
|
|
12
|
+
assignMode?: AssignMode;
|
|
13
|
+
heartbeatIntervalMs?: number;
|
|
14
|
+
heartbeatTimeoutMs?: number;
|
|
15
|
+
offerTimeoutMs?: number;
|
|
16
|
+
disconnectPolicy?: DisconnectPolicy;
|
|
17
|
+
disconnectGraceMs?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface WorkerRegistration {
|
|
20
|
+
id?: string;
|
|
21
|
+
matchRule: WorkerMatchRule;
|
|
22
|
+
capacity: number;
|
|
23
|
+
weight?: number;
|
|
24
|
+
connectionMode: Worker['connectionMode'];
|
|
25
|
+
metadata?: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
export interface WorkerUpdate {
|
|
28
|
+
weight?: number;
|
|
29
|
+
capacity?: number;
|
|
30
|
+
matchRule?: WorkerMatchRule;
|
|
31
|
+
status?: 'draining';
|
|
32
|
+
}
|
|
33
|
+
export interface DispatchResult {
|
|
34
|
+
matched: boolean;
|
|
35
|
+
workerId?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface ClaimResult {
|
|
38
|
+
success: boolean;
|
|
39
|
+
reason?: string;
|
|
40
|
+
}
|
|
41
|
+
export interface DeclineOptions {
|
|
42
|
+
blacklist?: boolean;
|
|
43
|
+
}
|
|
44
|
+
export declare class WorkerManager {
|
|
45
|
+
private opts;
|
|
46
|
+
private engine;
|
|
47
|
+
private shortTermStore;
|
|
48
|
+
private longTermStore?;
|
|
49
|
+
private hooks?;
|
|
50
|
+
constructor(opts: WorkerManagerOptions);
|
|
51
|
+
get heartbeatIntervalMs(): number;
|
|
52
|
+
private emitTaskAudit;
|
|
53
|
+
private emitWorkerAudit;
|
|
54
|
+
registerWorker(config: WorkerRegistration): Promise<Worker>;
|
|
55
|
+
unregisterWorker(workerId: string): Promise<void>;
|
|
56
|
+
updateWorker(workerId: string, update: WorkerUpdate): Promise<Worker | null>;
|
|
57
|
+
heartbeat(workerId: string): Promise<void>;
|
|
58
|
+
getWorker(workerId: string): Promise<Worker | null>;
|
|
59
|
+
listWorkers(filter?: WorkerFilter): Promise<Worker[]>;
|
|
60
|
+
dispatchTask(taskId: string): Promise<DispatchResult>;
|
|
61
|
+
claimTask(taskId: string, workerId: string): Promise<ClaimResult>;
|
|
62
|
+
declineTask(taskId: string, workerId: string, opts?: DeclineOptions): Promise<void>;
|
|
63
|
+
getWorkerTasks(workerId: string): Promise<WorkerAssignment[]>;
|
|
64
|
+
waitForTask(workerId: string, signal?: AbortSignal): Promise<Task>;
|
|
65
|
+
notifyNewTask(taskId: string): Promise<void>;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=worker-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-manager.d.ts","sourceRoot":"","sources":["../src/worker-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import { ulid } from 'ulidx';
|
|
2
|
+
import { matchesWorkerRule } from './worker-matching.js';
|
|
3
|
+
// ─── WorkerManager ──────────────────────────────────────────────────────────
|
|
4
|
+
export class WorkerManager {
|
|
5
|
+
opts;
|
|
6
|
+
engine;
|
|
7
|
+
shortTermStore;
|
|
8
|
+
longTermStore;
|
|
9
|
+
hooks;
|
|
10
|
+
constructor(opts) {
|
|
11
|
+
this.opts = opts;
|
|
12
|
+
this.engine = opts.engine;
|
|
13
|
+
this.shortTermStore = opts.shortTermStore;
|
|
14
|
+
if (opts.longTermStore)
|
|
15
|
+
this.longTermStore = opts.longTermStore;
|
|
16
|
+
if (opts.hooks)
|
|
17
|
+
this.hooks = opts.hooks;
|
|
18
|
+
}
|
|
19
|
+
get heartbeatIntervalMs() {
|
|
20
|
+
return this.opts.defaults?.heartbeatIntervalMs ?? 30_000;
|
|
21
|
+
}
|
|
22
|
+
// ─── Audit Helpers ──────────────────────────────────────────────────────
|
|
23
|
+
async emitTaskAudit(taskId, action, extra) {
|
|
24
|
+
try {
|
|
25
|
+
await this.opts.engine.publishEvent(taskId, {
|
|
26
|
+
type: 'taskcast:audit',
|
|
27
|
+
level: 'info',
|
|
28
|
+
data: { action, ...extra },
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// Task may be in terminal state or not found; audit is best-effort
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
emitWorkerAudit(action, workerId, data) {
|
|
36
|
+
if (!this.opts.longTermStore)
|
|
37
|
+
return;
|
|
38
|
+
const event = {
|
|
39
|
+
id: ulid(),
|
|
40
|
+
workerId,
|
|
41
|
+
timestamp: Date.now(),
|
|
42
|
+
action,
|
|
43
|
+
...(data !== undefined && { data }),
|
|
44
|
+
};
|
|
45
|
+
this.opts.longTermStore.saveWorkerEvent(event).catch(() => { });
|
|
46
|
+
}
|
|
47
|
+
// ─── Worker Registration & Lifecycle ────────────────────────────────────
|
|
48
|
+
async registerWorker(config) {
|
|
49
|
+
const now = Date.now();
|
|
50
|
+
const worker = {
|
|
51
|
+
id: config.id ?? ulid(),
|
|
52
|
+
status: 'idle',
|
|
53
|
+
matchRule: config.matchRule,
|
|
54
|
+
capacity: config.capacity,
|
|
55
|
+
usedSlots: 0,
|
|
56
|
+
weight: config.weight ?? 50,
|
|
57
|
+
connectionMode: config.connectionMode,
|
|
58
|
+
connectedAt: now,
|
|
59
|
+
lastHeartbeatAt: now,
|
|
60
|
+
...(config.metadata !== undefined && { metadata: config.metadata }),
|
|
61
|
+
};
|
|
62
|
+
await this.shortTermStore.saveWorker(worker);
|
|
63
|
+
this.emitWorkerAudit('connected', worker.id);
|
|
64
|
+
this.hooks?.onWorkerConnected?.(worker);
|
|
65
|
+
return worker;
|
|
66
|
+
}
|
|
67
|
+
async unregisterWorker(workerId) {
|
|
68
|
+
const worker = await this.shortTermStore.getWorker(workerId);
|
|
69
|
+
await this.shortTermStore.deleteWorker(workerId);
|
|
70
|
+
if (worker) {
|
|
71
|
+
this.emitWorkerAudit('disconnected', workerId, { reason: 'unregistered' });
|
|
72
|
+
this.hooks?.onWorkerDisconnected?.(worker, 'unregistered');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async updateWorker(workerId, update) {
|
|
76
|
+
const worker = await this.shortTermStore.getWorker(workerId);
|
|
77
|
+
if (!worker)
|
|
78
|
+
return null;
|
|
79
|
+
if (update.weight !== undefined)
|
|
80
|
+
worker.weight = update.weight;
|
|
81
|
+
if (update.capacity !== undefined)
|
|
82
|
+
worker.capacity = update.capacity;
|
|
83
|
+
if (update.matchRule !== undefined)
|
|
84
|
+
worker.matchRule = update.matchRule;
|
|
85
|
+
if (update.status !== undefined)
|
|
86
|
+
worker.status = update.status;
|
|
87
|
+
await this.shortTermStore.saveWorker(worker);
|
|
88
|
+
return worker;
|
|
89
|
+
}
|
|
90
|
+
async heartbeat(workerId) {
|
|
91
|
+
const worker = await this.shortTermStore.getWorker(workerId);
|
|
92
|
+
if (!worker)
|
|
93
|
+
return;
|
|
94
|
+
worker.lastHeartbeatAt = Date.now();
|
|
95
|
+
await this.shortTermStore.saveWorker(worker);
|
|
96
|
+
}
|
|
97
|
+
async getWorker(workerId) {
|
|
98
|
+
return this.shortTermStore.getWorker(workerId);
|
|
99
|
+
}
|
|
100
|
+
async listWorkers(filter) {
|
|
101
|
+
return this.shortTermStore.listWorkers(filter);
|
|
102
|
+
}
|
|
103
|
+
// ─── Task Dispatch ─────────────────────────────────────────────────────
|
|
104
|
+
async dispatchTask(taskId) {
|
|
105
|
+
const task = await this.engine.getTask(taskId);
|
|
106
|
+
if (!task || task.status !== 'pending') {
|
|
107
|
+
return { matched: false };
|
|
108
|
+
}
|
|
109
|
+
const blacklist = task.metadata?._blacklistedWorkers ?? [];
|
|
110
|
+
const workers = await this.shortTermStore.listWorkers({ status: ['idle', 'busy'] });
|
|
111
|
+
const taskCost = task.cost ?? 1;
|
|
112
|
+
const candidates = workers.filter((w) => {
|
|
113
|
+
if (blacklist.includes(w.id))
|
|
114
|
+
return false;
|
|
115
|
+
if (w.usedSlots + taskCost > w.capacity)
|
|
116
|
+
return false;
|
|
117
|
+
if (!matchesWorkerRule(task, w.matchRule))
|
|
118
|
+
return false;
|
|
119
|
+
return true;
|
|
120
|
+
});
|
|
121
|
+
if (candidates.length === 0) {
|
|
122
|
+
return { matched: false };
|
|
123
|
+
}
|
|
124
|
+
// Sort: weight desc → available slots desc → connectedAt asc
|
|
125
|
+
candidates.sort((a, b) => {
|
|
126
|
+
if (b.weight !== a.weight)
|
|
127
|
+
return b.weight - a.weight;
|
|
128
|
+
const aAvailable = a.capacity - a.usedSlots;
|
|
129
|
+
const bAvailable = b.capacity - b.usedSlots;
|
|
130
|
+
if (bAvailable !== aAvailable)
|
|
131
|
+
return bAvailable - aAvailable;
|
|
132
|
+
return a.connectedAt - b.connectedAt;
|
|
133
|
+
});
|
|
134
|
+
return { matched: true, workerId: candidates[0].id };
|
|
135
|
+
}
|
|
136
|
+
// ─── Task Claim ────────────────────────────────────────────────────────
|
|
137
|
+
async claimTask(taskId, workerId) {
|
|
138
|
+
const task = await this.engine.getTask(taskId);
|
|
139
|
+
if (!task) {
|
|
140
|
+
return { success: false, reason: 'Task not found' };
|
|
141
|
+
}
|
|
142
|
+
if (task.status !== 'pending') {
|
|
143
|
+
return { success: false, reason: `Task is not pending (status: ${task.status})` };
|
|
144
|
+
}
|
|
145
|
+
const cost = task.cost ?? 1;
|
|
146
|
+
const claimed = await this.shortTermStore.claimTask(taskId, workerId, cost);
|
|
147
|
+
if (!claimed) {
|
|
148
|
+
return { success: false, reason: 'Claim failed (concurrent modification)' };
|
|
149
|
+
}
|
|
150
|
+
// claimTask atomically sets status to 'assigned' and assignedWorker on the
|
|
151
|
+
// store. Re-read to get the authoritative state, then persist to longTermStore.
|
|
152
|
+
const updatedTask = (await this.shortTermStore.getTask(taskId));
|
|
153
|
+
if (this.longTermStore)
|
|
154
|
+
await this.longTermStore.saveTask(updatedTask);
|
|
155
|
+
// Emit audit events for the claim
|
|
156
|
+
this.emitWorkerAudit('task_assigned', workerId, { taskId });
|
|
157
|
+
await this.emitTaskAudit(taskId, 'assigned', { workerId });
|
|
158
|
+
// Create assignment record
|
|
159
|
+
const assignment = {
|
|
160
|
+
taskId,
|
|
161
|
+
workerId,
|
|
162
|
+
cost,
|
|
163
|
+
assignedAt: Date.now(),
|
|
164
|
+
status: 'assigned',
|
|
165
|
+
};
|
|
166
|
+
await this.shortTermStore.addAssignment(assignment);
|
|
167
|
+
// Update worker status (usedSlots already updated by claimTask)
|
|
168
|
+
const worker = await this.shortTermStore.getWorker(workerId);
|
|
169
|
+
if (worker) {
|
|
170
|
+
worker.status = worker.usedSlots >= worker.capacity ? 'busy' : 'idle';
|
|
171
|
+
await this.shortTermStore.saveWorker(worker);
|
|
172
|
+
this.hooks?.onTaskAssigned?.(updatedTask, worker);
|
|
173
|
+
}
|
|
174
|
+
return { success: true };
|
|
175
|
+
}
|
|
176
|
+
// ─── Task Decline ──────────────────────────────────────────────────────
|
|
177
|
+
async declineTask(taskId, workerId, opts) {
|
|
178
|
+
const assignment = await this.shortTermStore.getTaskAssignment(taskId);
|
|
179
|
+
if (!assignment || assignment.workerId !== workerId)
|
|
180
|
+
return;
|
|
181
|
+
// Remove assignment
|
|
182
|
+
await this.shortTermStore.removeAssignment(taskId);
|
|
183
|
+
// Restore worker capacity
|
|
184
|
+
const worker = await this.shortTermStore.getWorker(workerId);
|
|
185
|
+
if (worker) {
|
|
186
|
+
worker.usedSlots = Math.max(0, worker.usedSlots - assignment.cost);
|
|
187
|
+
worker.status = 'idle';
|
|
188
|
+
await this.shortTermStore.saveWorker(worker);
|
|
189
|
+
}
|
|
190
|
+
// Transition task back to pending
|
|
191
|
+
await this.engine.transitionTask(taskId, 'pending');
|
|
192
|
+
// Emit audit events for the decline
|
|
193
|
+
const blacklisted = opts?.blacklist ?? false;
|
|
194
|
+
this.emitWorkerAudit('task_declined', workerId, { taskId });
|
|
195
|
+
await this.emitTaskAudit(taskId, 'declined', { workerId, blacklisted });
|
|
196
|
+
// Clear assignedWorker
|
|
197
|
+
const task = await this.engine.getTask(taskId);
|
|
198
|
+
if (task) {
|
|
199
|
+
delete task.assignedWorker;
|
|
200
|
+
// Add to blacklist if requested
|
|
201
|
+
if (opts?.blacklist) {
|
|
202
|
+
const metadata = task.metadata ?? {};
|
|
203
|
+
const existing = metadata._blacklistedWorkers ?? [];
|
|
204
|
+
metadata._blacklistedWorkers = [...existing, workerId];
|
|
205
|
+
task.metadata = metadata;
|
|
206
|
+
}
|
|
207
|
+
await this.shortTermStore.saveTask(task);
|
|
208
|
+
if (this.longTermStore)
|
|
209
|
+
await this.longTermStore.saveTask(task);
|
|
210
|
+
if (worker) {
|
|
211
|
+
this.hooks?.onTaskDeclined?.(task, worker, blacklisted);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// ─── Worker Tasks ──────────────────────────────────────────────────────
|
|
216
|
+
async getWorkerTasks(workerId) {
|
|
217
|
+
return this.shortTermStore.getWorkerAssignments(workerId);
|
|
218
|
+
}
|
|
219
|
+
// ─── Pull Mode (Long-Poll) ─────────────────────────────────────────────
|
|
220
|
+
async waitForTask(workerId, signal) {
|
|
221
|
+
const worker = await this.shortTermStore.getWorker(workerId);
|
|
222
|
+
if (!worker)
|
|
223
|
+
throw new Error(`Worker not found: ${workerId}`);
|
|
224
|
+
// Check if already aborted
|
|
225
|
+
if (signal?.aborted) {
|
|
226
|
+
throw new Error('aborted');
|
|
227
|
+
}
|
|
228
|
+
// Check existing pending pull tasks
|
|
229
|
+
const pendingTasks = await this.shortTermStore.listTasks({ status: ['pending'], assignMode: ['pull'] });
|
|
230
|
+
const blacklist = new Set();
|
|
231
|
+
for (const task of pendingTasks) {
|
|
232
|
+
const taskBlacklist = task.metadata?._blacklistedWorkers ?? [];
|
|
233
|
+
if (taskBlacklist.includes(workerId))
|
|
234
|
+
continue;
|
|
235
|
+
if (!matchesWorkerRule(task, worker.matchRule))
|
|
236
|
+
continue;
|
|
237
|
+
const taskCost = task.cost ?? 1;
|
|
238
|
+
if (worker.usedSlots + taskCost > worker.capacity)
|
|
239
|
+
continue;
|
|
240
|
+
const result = await this.claimTask(task.id, workerId);
|
|
241
|
+
if (result.success) {
|
|
242
|
+
this.emitWorkerAudit('pull_request', workerId, { matched: true, taskId: task.id });
|
|
243
|
+
const claimed = await this.engine.getTask(task.id);
|
|
244
|
+
return claimed;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
// Wait for a new task notification via broadcast
|
|
248
|
+
return new Promise((resolve, reject) => {
|
|
249
|
+
let unsubscribe;
|
|
250
|
+
const cleanup = () => {
|
|
251
|
+
unsubscribe?.();
|
|
252
|
+
signal?.removeEventListener('abort', onAbort);
|
|
253
|
+
};
|
|
254
|
+
const onAbort = () => {
|
|
255
|
+
cleanup();
|
|
256
|
+
this.emitWorkerAudit('pull_request', workerId, { matched: false });
|
|
257
|
+
reject(new Error('aborted'));
|
|
258
|
+
};
|
|
259
|
+
if (signal) {
|
|
260
|
+
signal.addEventListener('abort', onAbort);
|
|
261
|
+
}
|
|
262
|
+
unsubscribe = this.opts.broadcast.subscribe('taskcast:worker:new-task', async (event) => {
|
|
263
|
+
const taskId = event.data;
|
|
264
|
+
try {
|
|
265
|
+
// Re-fetch the worker to get current state
|
|
266
|
+
const currentWorker = await this.shortTermStore.getWorker(workerId);
|
|
267
|
+
if (!currentWorker) {
|
|
268
|
+
cleanup();
|
|
269
|
+
reject(new Error(`Worker not found: ${workerId}`));
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
const task = await this.engine.getTask(taskId);
|
|
273
|
+
if (!task || task.status !== 'pending')
|
|
274
|
+
return;
|
|
275
|
+
if (task.assignMode !== 'pull')
|
|
276
|
+
return;
|
|
277
|
+
const taskBlacklist = task.metadata?._blacklistedWorkers ?? [];
|
|
278
|
+
if (taskBlacklist.includes(workerId))
|
|
279
|
+
return;
|
|
280
|
+
if (!matchesWorkerRule(task, currentWorker.matchRule))
|
|
281
|
+
return;
|
|
282
|
+
const taskCost = task.cost ?? 1;
|
|
283
|
+
if (currentWorker.usedSlots + taskCost > currentWorker.capacity)
|
|
284
|
+
return;
|
|
285
|
+
const result = await this.claimTask(taskId, workerId);
|
|
286
|
+
if (result.success) {
|
|
287
|
+
cleanup();
|
|
288
|
+
this.emitWorkerAudit('pull_request', workerId, { matched: true, taskId });
|
|
289
|
+
const claimed = await this.engine.getTask(taskId);
|
|
290
|
+
resolve(claimed);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
catch {
|
|
294
|
+
// Ignore errors from individual task checks
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
async notifyNewTask(taskId) {
|
|
300
|
+
const event = {
|
|
301
|
+
id: ulid(),
|
|
302
|
+
taskId: 'system',
|
|
303
|
+
index: 0,
|
|
304
|
+
timestamp: Date.now(),
|
|
305
|
+
type: 'taskcast:worker:new-task',
|
|
306
|
+
level: 'info',
|
|
307
|
+
data: taskId,
|
|
308
|
+
};
|
|
309
|
+
await this.opts.broadcast.publish('taskcast:worker:new-task', event);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
//# sourceMappingURL=worker-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-manager.js","sourceRoot":"","sources":["../src/worker-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Task, TagMatcher, WorkerMatchRule } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Checks if a set of task tags matches a TagMatcher.
|
|
4
|
+
*
|
|
5
|
+
* - `all`: every tag in `all` must exist in taskTags
|
|
6
|
+
* - `any`: at least one tag in `any` must exist in taskTags
|
|
7
|
+
* - `none`: none of the tags in `none` may exist in taskTags
|
|
8
|
+
* - Empty/undefined matcher matches everything
|
|
9
|
+
* - Undefined taskTags treated as empty array
|
|
10
|
+
* - Empty arrays in matcher fields are vacuous true
|
|
11
|
+
*/
|
|
12
|
+
export declare function matchesTag(taskTags: string[] | undefined, matcher: TagMatcher): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Checks if a task matches a WorkerMatchRule.
|
|
15
|
+
*
|
|
16
|
+
* - If rule has `taskTypes`: task.type must match using wildcard matching
|
|
17
|
+
* - If rule has `tags`: use matchesTag
|
|
18
|
+
* - Both conditions are AND'd
|
|
19
|
+
* - Empty/no rule matches everything
|
|
20
|
+
* - Task with no `type` does not match if rule has `taskTypes`
|
|
21
|
+
*/
|
|
22
|
+
export declare function matchesWorkerRule(task: Task, rule: WorkerMatchRule): boolean;
|
|
23
|
+
//# sourceMappingURL=worker-matching.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-matching.d.ts","sourceRoot":"","sources":["../src/worker-matching.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAGnE;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAgBvF;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAW5E"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { matchesType } from './filter.js';
|
|
2
|
+
/**
|
|
3
|
+
* Checks if a set of task tags matches a TagMatcher.
|
|
4
|
+
*
|
|
5
|
+
* - `all`: every tag in `all` must exist in taskTags
|
|
6
|
+
* - `any`: at least one tag in `any` must exist in taskTags
|
|
7
|
+
* - `none`: none of the tags in `none` may exist in taskTags
|
|
8
|
+
* - Empty/undefined matcher matches everything
|
|
9
|
+
* - Undefined taskTags treated as empty array
|
|
10
|
+
* - Empty arrays in matcher fields are vacuous true
|
|
11
|
+
*/
|
|
12
|
+
export function matchesTag(taskTags, matcher) {
|
|
13
|
+
const tags = taskTags ?? [];
|
|
14
|
+
if (matcher.all !== undefined && matcher.all.length > 0) {
|
|
15
|
+
if (!matcher.all.every((tag) => tags.includes(tag)))
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
if (matcher.any !== undefined && matcher.any.length > 0) {
|
|
19
|
+
if (!matcher.any.some((tag) => tags.includes(tag)))
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
if (matcher.none !== undefined && matcher.none.length > 0) {
|
|
23
|
+
if (matcher.none.some((tag) => tags.includes(tag)))
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Checks if a task matches a WorkerMatchRule.
|
|
30
|
+
*
|
|
31
|
+
* - If rule has `taskTypes`: task.type must match using wildcard matching
|
|
32
|
+
* - If rule has `tags`: use matchesTag
|
|
33
|
+
* - Both conditions are AND'd
|
|
34
|
+
* - Empty/no rule matches everything
|
|
35
|
+
* - Task with no `type` does not match if rule has `taskTypes`
|
|
36
|
+
*/
|
|
37
|
+
export function matchesWorkerRule(task, rule) {
|
|
38
|
+
if (rule.taskTypes !== undefined && rule.taskTypes.length > 0) {
|
|
39
|
+
if (task.type === undefined)
|
|
40
|
+
return false;
|
|
41
|
+
if (!matchesType(task.type, rule.taskTypes))
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
if (rule.tags !== undefined) {
|
|
45
|
+
if (!matchesTag(task.tags, rule.tags))
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=worker-matching.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-matching.js","sourceRoot":"","sources":["../src/worker-matching.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzC;;;;;;;;;GASG;AACH,MAAM,UAAU,UAAU,CAAC,QAA8B,EAAE,OAAmB;IAC5E,MAAM,IAAI,GAAG,QAAQ,IAAI,EAAE,CAAA;IAE3B,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAAE,OAAO,KAAK,CAAA;IACnE,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAAE,OAAO,KAAK,CAAA;IAClE,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1D,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAAE,OAAO,KAAK,CAAA;IAClE,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAU,EAAE,IAAqB;IACjE,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9D,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,KAAK,CAAA;QACzC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YAAE,OAAO,KAAK,CAAA;IAC3D,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC5B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAA;IACrD,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC"}
|