bunqueue 1.0.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/LICENSE +21 -0
- package/README.md +640 -0
- package/dist/application/dlqManager.d.ts +19 -0
- package/dist/application/dlqManager.d.ts.map +1 -0
- package/dist/application/dlqManager.js +44 -0
- package/dist/application/dlqManager.js.map +1 -0
- package/dist/application/eventsManager.d.ts +28 -0
- package/dist/application/eventsManager.d.ts.map +1 -0
- package/dist/application/eventsManager.js +59 -0
- package/dist/application/eventsManager.js.map +1 -0
- package/dist/application/jobLogsManager.d.ts +20 -0
- package/dist/application/jobLogsManager.d.ts.map +1 -0
- package/dist/application/jobLogsManager.js +28 -0
- package/dist/application/jobLogsManager.js.map +1 -0
- package/dist/application/metricsExporter.d.ts +24 -0
- package/dist/application/metricsExporter.d.ts.map +1 -0
- package/dist/application/metricsExporter.js +80 -0
- package/dist/application/metricsExporter.js.map +1 -0
- package/dist/application/operations/ack.d.ts +48 -0
- package/dist/application/operations/ack.d.ts.map +1 -0
- package/dist/application/operations/ack.js +109 -0
- package/dist/application/operations/ack.js.map +1 -0
- package/dist/application/operations/index.d.ts +10 -0
- package/dist/application/operations/index.d.ts.map +1 -0
- package/dist/application/operations/index.js +10 -0
- package/dist/application/operations/index.js.map +1 -0
- package/dist/application/operations/jobManagement.d.ts +32 -0
- package/dist/application/operations/jobManagement.d.ts.map +1 -0
- package/dist/application/operations/jobManagement.js +122 -0
- package/dist/application/operations/jobManagement.js.map +1 -0
- package/dist/application/operations/pull.d.ts +36 -0
- package/dist/application/operations/pull.d.ts.map +1 -0
- package/dist/application/operations/pull.js +109 -0
- package/dist/application/operations/pull.js.map +1 -0
- package/dist/application/operations/push.d.ts +36 -0
- package/dist/application/operations/push.d.ts.map +1 -0
- package/dist/application/operations/push.js +94 -0
- package/dist/application/operations/push.js.map +1 -0
- package/dist/application/operations/queryOperations.d.ts +33 -0
- package/dist/application/operations/queryOperations.d.ts.map +1 -0
- package/dist/application/operations/queryOperations.js +57 -0
- package/dist/application/operations/queryOperations.js.map +1 -0
- package/dist/application/operations/queueControl.d.ts +32 -0
- package/dist/application/operations/queueControl.d.ts.map +1 -0
- package/dist/application/operations/queueControl.js +72 -0
- package/dist/application/operations/queueControl.js.map +1 -0
- package/dist/application/queueManager.d.ts +113 -0
- package/dist/application/queueManager.d.ts.map +1 -0
- package/dist/application/queueManager.js +406 -0
- package/dist/application/queueManager.js.map +1 -0
- package/dist/application/webhookManager.d.ts +35 -0
- package/dist/application/webhookManager.d.ts.map +1 -0
- package/dist/application/webhookManager.js +109 -0
- package/dist/application/webhookManager.js.map +1 -0
- package/dist/application/workerManager.d.ts +48 -0
- package/dist/application/workerManager.d.ts.map +1 -0
- package/dist/application/workerManager.js +121 -0
- package/dist/application/workerManager.js.map +1 -0
- package/dist/domain/queue/index.d.ts +6 -0
- package/dist/domain/queue/index.d.ts.map +1 -0
- package/dist/domain/queue/index.js +6 -0
- package/dist/domain/queue/index.js.map +1 -0
- package/dist/domain/queue/priorityQueue.d.ts +45 -0
- package/dist/domain/queue/priorityQueue.d.ts.map +1 -0
- package/dist/domain/queue/priorityQueue.js +203 -0
- package/dist/domain/queue/priorityQueue.js.map +1 -0
- package/dist/domain/queue/shard.d.ts +98 -0
- package/dist/domain/queue/shard.d.ts.map +1 -0
- package/dist/domain/queue/shard.js +245 -0
- package/dist/domain/queue/shard.js.map +1 -0
- package/dist/domain/types/command.d.ts +270 -0
- package/dist/domain/types/command.d.ts.map +1 -0
- package/dist/domain/types/command.js +6 -0
- package/dist/domain/types/command.js.map +1 -0
- package/dist/domain/types/cron.d.ts +32 -0
- package/dist/domain/types/cron.d.ts.map +1 -0
- package/dist/domain/types/cron.js +31 -0
- package/dist/domain/types/cron.js.map +1 -0
- package/dist/domain/types/index.d.ts +9 -0
- package/dist/domain/types/index.d.ts.map +1 -0
- package/dist/domain/types/index.js +9 -0
- package/dist/domain/types/index.js.map +1 -0
- package/dist/domain/types/job.d.ts +94 -0
- package/dist/domain/types/job.d.ts.map +1 -0
- package/dist/domain/types/job.js +81 -0
- package/dist/domain/types/job.js.map +1 -0
- package/dist/domain/types/queue.d.ts +86 -0
- package/dist/domain/types/queue.d.ts.map +1 -0
- package/dist/domain/types/queue.js +84 -0
- package/dist/domain/types/queue.js.map +1 -0
- package/dist/domain/types/response.d.ts +158 -0
- package/dist/domain/types/response.d.ts.map +1 -0
- package/dist/domain/types/response.js +86 -0
- package/dist/domain/types/response.js.map +1 -0
- package/dist/domain/types/webhook.d.ts +33 -0
- package/dist/domain/types/webhook.d.ts.map +1 -0
- package/dist/domain/types/webhook.js +20 -0
- package/dist/domain/types/webhook.js.map +1 -0
- package/dist/domain/types/worker.d.ts +27 -0
- package/dist/domain/types/worker.d.ts.map +1 -0
- package/dist/domain/types/worker.js +27 -0
- package/dist/domain/types/worker.js.map +1 -0
- package/dist/infrastructure/persistence/index.d.ts +6 -0
- package/dist/infrastructure/persistence/index.d.ts.map +1 -0
- package/dist/infrastructure/persistence/index.js +6 -0
- package/dist/infrastructure/persistence/index.js.map +1 -0
- package/dist/infrastructure/persistence/schema.d.ts +14 -0
- package/dist/infrastructure/persistence/schema.d.ts.map +1 -0
- package/dist/infrastructure/persistence/schema.js +123 -0
- package/dist/infrastructure/persistence/schema.js.map +1 -0
- package/dist/infrastructure/persistence/sqlite.d.ts +42 -0
- package/dist/infrastructure/persistence/sqlite.d.ts.map +1 -0
- package/dist/infrastructure/persistence/sqlite.js +164 -0
- package/dist/infrastructure/persistence/sqlite.js.map +1 -0
- package/dist/infrastructure/persistence/statements.d.ts +55 -0
- package/dist/infrastructure/persistence/statements.d.ts.map +1 -0
- package/dist/infrastructure/persistence/statements.js +42 -0
- package/dist/infrastructure/persistence/statements.js.map +1 -0
- package/dist/infrastructure/scheduler/cronParser.d.ts +44 -0
- package/dist/infrastructure/scheduler/cronParser.d.ts.map +1 -0
- package/dist/infrastructure/scheduler/cronParser.js +90 -0
- package/dist/infrastructure/scheduler/cronParser.js.map +1 -0
- package/dist/infrastructure/scheduler/cronScheduler.d.ts +68 -0
- package/dist/infrastructure/scheduler/cronScheduler.d.ts.map +1 -0
- package/dist/infrastructure/scheduler/cronScheduler.js +172 -0
- package/dist/infrastructure/scheduler/cronScheduler.js.map +1 -0
- package/dist/infrastructure/scheduler/index.d.ts +6 -0
- package/dist/infrastructure/scheduler/index.d.ts.map +1 -0
- package/dist/infrastructure/scheduler/index.js +6 -0
- package/dist/infrastructure/scheduler/index.js.map +1 -0
- package/dist/infrastructure/server/handler.d.ts +13 -0
- package/dist/infrastructure/server/handler.d.ts.map +1 -0
- package/dist/infrastructure/server/handler.js +167 -0
- package/dist/infrastructure/server/handler.js.map +1 -0
- package/dist/infrastructure/server/handlers/advanced.d.ts +68 -0
- package/dist/infrastructure/server/handlers/advanced.d.ts.map +1 -0
- package/dist/infrastructure/server/handlers/advanced.js +99 -0
- package/dist/infrastructure/server/handlers/advanced.js.map +1 -0
- package/dist/infrastructure/server/handlers/core.d.ts +36 -0
- package/dist/infrastructure/server/handlers/core.d.ts.map +1 -0
- package/dist/infrastructure/server/handlers/core.js +82 -0
- package/dist/infrastructure/server/handlers/core.js.map +1 -0
- package/dist/infrastructure/server/handlers/cron.d.ts +20 -0
- package/dist/infrastructure/server/handlers/cron.d.ts.map +1 -0
- package/dist/infrastructure/server/handlers/cron.js +56 -0
- package/dist/infrastructure/server/handlers/cron.js.map +1 -0
- package/dist/infrastructure/server/handlers/dlq.d.ts +20 -0
- package/dist/infrastructure/server/handlers/dlq.d.ts.map +1 -0
- package/dist/infrastructure/server/handlers/dlq.js +31 -0
- package/dist/infrastructure/server/handlers/dlq.js.map +1 -0
- package/dist/infrastructure/server/handlers/index.d.ts +7 -0
- package/dist/infrastructure/server/handlers/index.d.ts.map +1 -0
- package/dist/infrastructure/server/handlers/index.js +7 -0
- package/dist/infrastructure/server/handlers/index.js.map +1 -0
- package/dist/infrastructure/server/handlers/management.d.ts +36 -0
- package/dist/infrastructure/server/handlers/management.d.ts.map +1 -0
- package/dist/infrastructure/server/handlers/management.js +75 -0
- package/dist/infrastructure/server/handlers/management.js.map +1 -0
- package/dist/infrastructure/server/handlers/monitoring.d.ts +18 -0
- package/dist/infrastructure/server/handlers/monitoring.d.ts.map +1 -0
- package/dist/infrastructure/server/handlers/monitoring.js +102 -0
- package/dist/infrastructure/server/handlers/monitoring.js.map +1 -0
- package/dist/infrastructure/server/handlers/query.d.ts +32 -0
- package/dist/infrastructure/server/handlers/query.d.ts.map +1 -0
- package/dist/infrastructure/server/handlers/query.js +61 -0
- package/dist/infrastructure/server/handlers/query.js.map +1 -0
- package/dist/infrastructure/server/http.d.ts +43 -0
- package/dist/infrastructure/server/http.d.ts.map +1 -0
- package/dist/infrastructure/server/http.js +344 -0
- package/dist/infrastructure/server/http.js.map +1 -0
- package/dist/infrastructure/server/index.d.ts +8 -0
- package/dist/infrastructure/server/index.d.ts.map +1 -0
- package/dist/infrastructure/server/index.js +8 -0
- package/dist/infrastructure/server/index.js.map +1 -0
- package/dist/infrastructure/server/protocol.d.ts +44 -0
- package/dist/infrastructure/server/protocol.d.ts.map +1 -0
- package/dist/infrastructure/server/protocol.js +129 -0
- package/dist/infrastructure/server/protocol.js.map +1 -0
- package/dist/infrastructure/server/rateLimiter.d.ts +31 -0
- package/dist/infrastructure/server/rateLimiter.d.ts.map +1 -0
- package/dist/infrastructure/server/rateLimiter.js +79 -0
- package/dist/infrastructure/server/rateLimiter.js.map +1 -0
- package/dist/infrastructure/server/tcp.d.ts +36 -0
- package/dist/infrastructure/server/tcp.d.ts.map +1 -0
- package/dist/infrastructure/server/tcp.js +101 -0
- package/dist/infrastructure/server/tcp.js.map +1 -0
- package/dist/infrastructure/server/types.d.ts +11 -0
- package/dist/infrastructure/server/types.d.ts.map +1 -0
- package/dist/infrastructure/server/types.js +5 -0
- package/dist/infrastructure/server/types.js.map +1 -0
- package/dist/main.d.ts +6 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +111 -0
- package/dist/main.js.map +1 -0
- package/dist/shared/hash.d.ts +30 -0
- package/dist/shared/hash.d.ts.map +1 -0
- package/dist/shared/hash.js +69 -0
- package/dist/shared/hash.js.map +1 -0
- package/dist/shared/index.d.ts +6 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/index.js +6 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/lock.d.ts +70 -0
- package/dist/shared/lock.d.ts.map +1 -0
- package/dist/shared/lock.js +207 -0
- package/dist/shared/lock.js.map +1 -0
- package/dist/shared/logger.d.ts +38 -0
- package/dist/shared/logger.d.ts.map +1 -0
- package/dist/shared/logger.js +74 -0
- package/dist/shared/logger.js.map +1 -0
- package/dist/shared/serialization.d.ts +23 -0
- package/dist/shared/serialization.d.ts.map +1 -0
- package/dist/shared/serialization.js +63 -0
- package/dist/shared/serialization.js.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Job Management Operations
|
|
3
|
+
* Cancel, update progress, change priority, promote, move to delayed, discard
|
|
4
|
+
*/
|
|
5
|
+
import { shardIndex } from '../../shared/hash';
|
|
6
|
+
/** Cancel a job (remove from queue) */
|
|
7
|
+
export async function cancelJob(jobId, ctx) {
|
|
8
|
+
const location = ctx.jobIndex.get(jobId);
|
|
9
|
+
if (!location)
|
|
10
|
+
return false;
|
|
11
|
+
if (location.type === 'queue') {
|
|
12
|
+
const shard = ctx.shards[location.shardIdx];
|
|
13
|
+
const job = shard.getQueue(location.queueName).remove(jobId);
|
|
14
|
+
if (job) {
|
|
15
|
+
if (job.uniqueKey)
|
|
16
|
+
shard.releaseUniqueKey(location.queueName, job.uniqueKey);
|
|
17
|
+
ctx.jobIndex.delete(jobId);
|
|
18
|
+
ctx.storage?.deleteJob(jobId);
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
/** Update job progress */
|
|
25
|
+
export async function updateJobProgress(jobId, progress, ctx, message) {
|
|
26
|
+
const location = ctx.jobIndex.get(jobId);
|
|
27
|
+
if (location?.type !== 'processing')
|
|
28
|
+
return false;
|
|
29
|
+
const job = ctx.processingShards[location.shardIdx].get(jobId);
|
|
30
|
+
if (!job)
|
|
31
|
+
return false;
|
|
32
|
+
job.progress = Math.max(0, Math.min(100, progress));
|
|
33
|
+
if (message !== undefined)
|
|
34
|
+
job.progressMessage = message;
|
|
35
|
+
ctx.webhookManager
|
|
36
|
+
.trigger('job.progress', String(jobId), job.queue, { progress: job.progress })
|
|
37
|
+
.catch(() => {
|
|
38
|
+
// Ignore webhook errors
|
|
39
|
+
});
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
/** Update job data */
|
|
43
|
+
export async function updateJobData(jobId, data, ctx) {
|
|
44
|
+
const location = ctx.jobIndex.get(jobId);
|
|
45
|
+
if (!location)
|
|
46
|
+
return false;
|
|
47
|
+
if (location.type === 'queue') {
|
|
48
|
+
const job = ctx.shards[location.shardIdx].getQueue(location.queueName).find(jobId);
|
|
49
|
+
if (job) {
|
|
50
|
+
job.data = data;
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else if (location.type === 'processing') {
|
|
55
|
+
const job = ctx.processingShards[location.shardIdx].get(jobId);
|
|
56
|
+
if (job) {
|
|
57
|
+
job.data = data;
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
/** Change job priority */
|
|
64
|
+
export async function changeJobPriority(jobId, priority, ctx) {
|
|
65
|
+
const location = ctx.jobIndex.get(jobId);
|
|
66
|
+
if (location?.type !== 'queue')
|
|
67
|
+
return false;
|
|
68
|
+
const q = ctx.shards[location.shardIdx].getQueue(location.queueName);
|
|
69
|
+
return q.updatePriority(jobId, priority);
|
|
70
|
+
}
|
|
71
|
+
/** Promote delayed job to waiting */
|
|
72
|
+
export async function promoteJob(jobId, ctx) {
|
|
73
|
+
const location = ctx.jobIndex.get(jobId);
|
|
74
|
+
if (location?.type !== 'queue')
|
|
75
|
+
return false;
|
|
76
|
+
const q = ctx.shards[location.shardIdx].getQueue(location.queueName);
|
|
77
|
+
const job = q.find(jobId);
|
|
78
|
+
if (!job || job.runAt <= Date.now())
|
|
79
|
+
return false;
|
|
80
|
+
job.runAt = Date.now();
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
/** Move active job back to delayed */
|
|
84
|
+
export async function moveJobToDelayed(jobId, delay, ctx) {
|
|
85
|
+
const location = ctx.jobIndex.get(jobId);
|
|
86
|
+
if (location?.type !== 'processing')
|
|
87
|
+
return false;
|
|
88
|
+
const procShard = ctx.processingShards[location.shardIdx];
|
|
89
|
+
const job = procShard.get(jobId);
|
|
90
|
+
if (!job)
|
|
91
|
+
return false;
|
|
92
|
+
procShard.delete(jobId);
|
|
93
|
+
job.runAt = Date.now() + delay;
|
|
94
|
+
job.startedAt = null;
|
|
95
|
+
const idx = shardIndex(job.queue);
|
|
96
|
+
ctx.shards[idx].getQueue(job.queue).push(job);
|
|
97
|
+
ctx.jobIndex.set(jobId, { type: 'queue', shardIdx: idx, queueName: job.queue });
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
/** Discard job to DLQ */
|
|
101
|
+
export async function discardJob(jobId, ctx) {
|
|
102
|
+
const location = ctx.jobIndex.get(jobId);
|
|
103
|
+
if (!location)
|
|
104
|
+
return false;
|
|
105
|
+
let job = null;
|
|
106
|
+
if (location.type === 'queue') {
|
|
107
|
+
job = ctx.shards[location.shardIdx].getQueue(location.queueName).remove(jobId);
|
|
108
|
+
}
|
|
109
|
+
else if (location.type === 'processing') {
|
|
110
|
+
job = ctx.processingShards[location.shardIdx].get(jobId) ?? null;
|
|
111
|
+
if (job)
|
|
112
|
+
ctx.processingShards[location.shardIdx].delete(jobId);
|
|
113
|
+
}
|
|
114
|
+
if (job) {
|
|
115
|
+
const idx = shardIndex(job.queue);
|
|
116
|
+
ctx.shards[idx].addToDlq(job);
|
|
117
|
+
ctx.jobIndex.set(jobId, { type: 'dlq', queueName: job.queue });
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=jobManagement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobManagement.js","sourceRoot":"","sources":["../../../src/application/operations/jobManagement.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pull Operations
|
|
3
|
+
* Job pull logic with timeout support
|
|
4
|
+
*/
|
|
5
|
+
import { type Job, type JobId } from '../../domain/types/job';
|
|
6
|
+
import type { JobLocation, EventType } from '../../domain/types/queue';
|
|
7
|
+
import type { Shard } from '../../domain/queue/shard';
|
|
8
|
+
import type { SqliteStorage } from '../../infrastructure/persistence/sqlite';
|
|
9
|
+
import { RWLock } from '../../shared/lock';
|
|
10
|
+
/** Pull operation context */
|
|
11
|
+
export interface PullContext {
|
|
12
|
+
storage: SqliteStorage | null;
|
|
13
|
+
shards: Shard[];
|
|
14
|
+
shardLocks: RWLock[];
|
|
15
|
+
processingShards: Map<JobId, Job>[];
|
|
16
|
+
processingLocks: RWLock[];
|
|
17
|
+
jobIndex: Map<JobId, JobLocation>;
|
|
18
|
+
totalPulled: {
|
|
19
|
+
value: bigint;
|
|
20
|
+
};
|
|
21
|
+
broadcast: (event: {
|
|
22
|
+
eventType: EventType;
|
|
23
|
+
queue: string;
|
|
24
|
+
jobId: JobId;
|
|
25
|
+
timestamp: number;
|
|
26
|
+
}) => void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Pull next job from queue
|
|
30
|
+
*/
|
|
31
|
+
export declare function pullJob(queue: string, timeoutMs: number, ctx: PullContext): Promise<Job | null>;
|
|
32
|
+
/**
|
|
33
|
+
* Pull multiple jobs from queue
|
|
34
|
+
*/
|
|
35
|
+
export declare function pullJobBatch(queue: string, count: number, timeoutMs: number, ctx: PullContext): Promise<Job[]>;
|
|
36
|
+
//# sourceMappingURL=pull.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../../src/application/operations/pull.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,KAAK,EAAsB,MAAM,wBAAwB,CAAC;AAClF,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,MAAM,EAAiB,MAAM,mBAAmB,CAAC;AAG1D,6BAA6B;AAC7B,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,gBAAgB,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC;IACpC,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,EAAE,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAClC,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/B,SAAS,EAAE,CAAC,KAAK,EAAE;QACjB,SAAS,EAAE,SAAS,CAAC;QACrB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,KAAK,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB,KAAK,IAAI,CAAC;CACZ;AAED;;GAEG;AACH,wBAAsB,OAAO,CAC3B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAsCrB;AA8DD;;GAEG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,GAAG,EAAE,CAAC,CAahB"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pull Operations
|
|
3
|
+
* Job pull logic with timeout support
|
|
4
|
+
*/
|
|
5
|
+
import { isExpired, isReady } from '../../domain/types/job';
|
|
6
|
+
import { withWriteLock } from '../../shared/lock';
|
|
7
|
+
import { shardIndex, processingShardIndex } from '../../shared/hash';
|
|
8
|
+
/**
|
|
9
|
+
* Pull next job from queue
|
|
10
|
+
*/
|
|
11
|
+
export async function pullJob(queue, timeoutMs, ctx) {
|
|
12
|
+
const deadline = timeoutMs > 0 ? Date.now() + timeoutMs : 0;
|
|
13
|
+
const idx = shardIndex(queue);
|
|
14
|
+
while (true) {
|
|
15
|
+
const job = await tryPullFromShard(queue, idx, ctx);
|
|
16
|
+
if (job) {
|
|
17
|
+
// Move to processing
|
|
18
|
+
const procIdx = processingShardIndex(job.id);
|
|
19
|
+
await withWriteLock(ctx.processingLocks[procIdx], () => {
|
|
20
|
+
ctx.processingShards[procIdx].set(job.id, job);
|
|
21
|
+
});
|
|
22
|
+
ctx.jobIndex.set(job.id, { type: 'processing', shardIdx: procIdx });
|
|
23
|
+
// Persist state change
|
|
24
|
+
ctx.storage?.markActive(job.id, job.startedAt);
|
|
25
|
+
// Update metrics
|
|
26
|
+
ctx.totalPulled.value++;
|
|
27
|
+
ctx.broadcast({
|
|
28
|
+
eventType: 'pulled',
|
|
29
|
+
queue,
|
|
30
|
+
jobId: job.id,
|
|
31
|
+
timestamp: Date.now(),
|
|
32
|
+
});
|
|
33
|
+
return job;
|
|
34
|
+
}
|
|
35
|
+
// No job available, check timeout
|
|
36
|
+
if (deadline === 0 || Date.now() >= deadline) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
// Wait briefly and retry
|
|
40
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Try to pull a job from a specific shard
|
|
45
|
+
*/
|
|
46
|
+
async function tryPullFromShard(queue, idx, ctx) {
|
|
47
|
+
return await withWriteLock(ctx.shardLocks[idx], () => {
|
|
48
|
+
const shard = ctx.shards[idx];
|
|
49
|
+
const state = shard.getState(queue);
|
|
50
|
+
// Check if paused
|
|
51
|
+
if (state.paused)
|
|
52
|
+
return null;
|
|
53
|
+
// Check rate limit
|
|
54
|
+
if (!shard.tryAcquireRateLimit(queue))
|
|
55
|
+
return null;
|
|
56
|
+
// Check concurrency
|
|
57
|
+
if (!shard.tryAcquireConcurrency(queue))
|
|
58
|
+
return null;
|
|
59
|
+
const q = shard.getQueue(queue);
|
|
60
|
+
const now = Date.now();
|
|
61
|
+
// Find ready job
|
|
62
|
+
while (true) {
|
|
63
|
+
const job = q.peek();
|
|
64
|
+
if (!job)
|
|
65
|
+
break;
|
|
66
|
+
// Skip expired jobs
|
|
67
|
+
if (isExpired(job, now)) {
|
|
68
|
+
q.pop();
|
|
69
|
+
ctx.jobIndex.delete(job.id);
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
// Check if ready
|
|
73
|
+
if (!isReady(job, now))
|
|
74
|
+
break;
|
|
75
|
+
// Check FIFO group
|
|
76
|
+
if (job.groupId && shard.isGroupActive(queue, job.groupId)) {
|
|
77
|
+
// Skip, will retry
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
// Dequeue
|
|
81
|
+
q.pop();
|
|
82
|
+
// Mark group active
|
|
83
|
+
if (job.groupId) {
|
|
84
|
+
shard.activateGroup(queue, job.groupId);
|
|
85
|
+
}
|
|
86
|
+
// Update job
|
|
87
|
+
job.startedAt = now;
|
|
88
|
+
job.lastHeartbeat = now;
|
|
89
|
+
return job;
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Pull multiple jobs from queue
|
|
96
|
+
*/
|
|
97
|
+
export async function pullJobBatch(queue, count, timeoutMs, ctx) {
|
|
98
|
+
const jobs = [];
|
|
99
|
+
const deadline = timeoutMs > 0 ? Date.now() + timeoutMs : 0;
|
|
100
|
+
for (let i = 0; i < count; i++) {
|
|
101
|
+
const remaining = deadline > 0 ? Math.max(0, deadline - Date.now()) : 0;
|
|
102
|
+
const job = await pullJob(queue, remaining, ctx);
|
|
103
|
+
if (!job)
|
|
104
|
+
break;
|
|
105
|
+
jobs.push(job);
|
|
106
|
+
}
|
|
107
|
+
return jobs;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=pull.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull.js","sourceRoot":"","sources":["../../../src/application/operations/pull.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Push Operations
|
|
3
|
+
* Job push and batch push logic
|
|
4
|
+
*/
|
|
5
|
+
import { type Job, type JobId, type JobInput } from '../../domain/types/job';
|
|
6
|
+
import type { JobLocation, EventType } from '../../domain/types/queue';
|
|
7
|
+
import type { Shard } from '../../domain/queue/shard';
|
|
8
|
+
import type { SqliteStorage } from '../../infrastructure/persistence/sqlite';
|
|
9
|
+
import { RWLock } from '../../shared/lock';
|
|
10
|
+
/** Push operation context */
|
|
11
|
+
export interface PushContext {
|
|
12
|
+
storage: SqliteStorage | null;
|
|
13
|
+
shards: Shard[];
|
|
14
|
+
shardLocks: RWLock[];
|
|
15
|
+
completedJobs: Set<JobId>;
|
|
16
|
+
customIdMap: Map<string, JobId>;
|
|
17
|
+
jobIndex: Map<JobId, JobLocation>;
|
|
18
|
+
totalPushed: {
|
|
19
|
+
value: bigint;
|
|
20
|
+
};
|
|
21
|
+
broadcast: (event: {
|
|
22
|
+
eventType: EventType;
|
|
23
|
+
queue: string;
|
|
24
|
+
jobId: JobId;
|
|
25
|
+
timestamp: number;
|
|
26
|
+
}) => void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Push a single job to queue
|
|
30
|
+
*/
|
|
31
|
+
export declare function pushJob(queue: string, input: JobInput, ctx: PushContext): Promise<Job>;
|
|
32
|
+
/**
|
|
33
|
+
* Push multiple jobs to queue
|
|
34
|
+
*/
|
|
35
|
+
export declare function pushJobBatch(queue: string, inputs: JobInput[], ctx: PushContext): Promise<JobId[]>;
|
|
36
|
+
//# sourceMappingURL=push.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../../src/application/operations/push.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,KAAK,EAAE,KAAK,QAAQ,EAAoB,MAAM,wBAAwB,CAAC;AAC/F,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,MAAM,EAAiB,MAAM,mBAAmB,CAAC;AAG1D,6BAA6B;AAC7B,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,aAAa,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IAC1B,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAChC,QAAQ,EAAE,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAClC,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/B,SAAS,EAAE,CAAC,KAAK,EAAE;QACjB,SAAS,EAAE,SAAS,CAAC;QACrB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,KAAK,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB,KAAK,IAAI,CAAC;CACZ;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAgE5F;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,QAAQ,EAAE,EAClB,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,KAAK,EAAE,CAAC,CAiClB"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Push Operations
|
|
3
|
+
* Job push and batch push logic
|
|
4
|
+
*/
|
|
5
|
+
import { createJob, jobId } from '../../domain/types/job';
|
|
6
|
+
import { withWriteLock } from '../../shared/lock';
|
|
7
|
+
import { shardIndex } from '../../shared/hash';
|
|
8
|
+
/**
|
|
9
|
+
* Push a single job to queue
|
|
10
|
+
*/
|
|
11
|
+
export async function pushJob(queue, input, ctx) {
|
|
12
|
+
// Generate ID (use storage or fallback to timestamp-based ID)
|
|
13
|
+
const id = ctx.storage?.nextJobId() ?? jobId(BigInt(Date.now() * 1000 + Math.floor(Math.random() * 1000)));
|
|
14
|
+
// Handle custom ID idempotency
|
|
15
|
+
if (input.customId) {
|
|
16
|
+
const existing = ctx.customIdMap.get(input.customId);
|
|
17
|
+
if (existing) {
|
|
18
|
+
const location = ctx.jobIndex.get(existing);
|
|
19
|
+
if (location) {
|
|
20
|
+
// Return existing job ID - caller should fetch the job
|
|
21
|
+
throw new Error(`Job with customId ${input.customId} already exists`);
|
|
22
|
+
}
|
|
23
|
+
ctx.customIdMap.delete(input.customId);
|
|
24
|
+
}
|
|
25
|
+
ctx.customIdMap.set(input.customId, id);
|
|
26
|
+
}
|
|
27
|
+
// Create job
|
|
28
|
+
const now = Date.now();
|
|
29
|
+
const job = createJob(id, queue, input, now);
|
|
30
|
+
// Check dependencies
|
|
31
|
+
const needsWaitingDeps = job.dependsOn.length > 0 && !job.dependsOn.every((depId) => ctx.completedJobs.has(depId));
|
|
32
|
+
// Insert into shard
|
|
33
|
+
const idx = shardIndex(queue);
|
|
34
|
+
await withWriteLock(ctx.shardLocks[idx], () => {
|
|
35
|
+
const shard = ctx.shards[idx];
|
|
36
|
+
// Check unique key
|
|
37
|
+
if (job.uniqueKey && !shard.isUniqueAvailable(queue, job.uniqueKey)) {
|
|
38
|
+
// Rollback custom ID
|
|
39
|
+
if (input.customId) {
|
|
40
|
+
ctx.customIdMap.delete(input.customId);
|
|
41
|
+
}
|
|
42
|
+
throw new Error('Duplicate unique_key');
|
|
43
|
+
}
|
|
44
|
+
if (job.uniqueKey) {
|
|
45
|
+
shard.registerUniqueKey(queue, job.uniqueKey);
|
|
46
|
+
}
|
|
47
|
+
// Insert based on state
|
|
48
|
+
if (needsWaitingDeps) {
|
|
49
|
+
shard.waitingDeps.set(job.id, job);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
shard.getQueue(queue).push(job);
|
|
53
|
+
shard.notify();
|
|
54
|
+
}
|
|
55
|
+
// Index job
|
|
56
|
+
ctx.jobIndex.set(job.id, { type: 'queue', shardIdx: idx, queueName: queue });
|
|
57
|
+
});
|
|
58
|
+
// Persist
|
|
59
|
+
ctx.storage?.insertJob(job);
|
|
60
|
+
// Update metrics & notify
|
|
61
|
+
ctx.totalPushed.value++;
|
|
62
|
+
ctx.broadcast({ eventType: 'pushed', queue, jobId: id, timestamp: now });
|
|
63
|
+
return job;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Push multiple jobs to queue
|
|
67
|
+
*/
|
|
68
|
+
export async function pushJobBatch(queue, inputs, ctx) {
|
|
69
|
+
const jobs = [];
|
|
70
|
+
const now = Date.now();
|
|
71
|
+
// Generate all jobs
|
|
72
|
+
for (const input of inputs) {
|
|
73
|
+
const id = ctx.storage?.nextJobId() ??
|
|
74
|
+
jobId(BigInt(Date.now() * 1000 + Math.floor(Math.random() * 1000)));
|
|
75
|
+
jobs.push(createJob(id, queue, input, now));
|
|
76
|
+
}
|
|
77
|
+
// Insert into shard
|
|
78
|
+
const idx = shardIndex(queue);
|
|
79
|
+
await withWriteLock(ctx.shardLocks[idx], () => {
|
|
80
|
+
const shard = ctx.shards[idx];
|
|
81
|
+
const q = shard.getQueue(queue);
|
|
82
|
+
for (const job of jobs) {
|
|
83
|
+
q.push(job);
|
|
84
|
+
ctx.jobIndex.set(job.id, { type: 'queue', shardIdx: idx, queueName: queue });
|
|
85
|
+
}
|
|
86
|
+
shard.notify();
|
|
87
|
+
});
|
|
88
|
+
// Persist batch
|
|
89
|
+
ctx.storage?.insertJobsBatch(jobs);
|
|
90
|
+
// Update metrics
|
|
91
|
+
ctx.totalPushed.value += BigInt(jobs.length);
|
|
92
|
+
return jobs.map((j) => j.id);
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=push.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../../src/application/operations/push.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query Operations
|
|
3
|
+
* Get job, get result, get progress
|
|
4
|
+
*/
|
|
5
|
+
import type { Job, JobId } from '../../domain/types/job';
|
|
6
|
+
import type { JobLocation } from '../../domain/types/queue';
|
|
7
|
+
import type { Shard } from '../../domain/queue/shard';
|
|
8
|
+
import type { SqliteStorage } from '../../infrastructure/persistence/sqlite';
|
|
9
|
+
import { type RWLock } from '../../shared/lock';
|
|
10
|
+
/** Context for query operations */
|
|
11
|
+
export interface QueryContext {
|
|
12
|
+
storage: SqliteStorage | null;
|
|
13
|
+
shards: Shard[];
|
|
14
|
+
shardLocks: RWLock[];
|
|
15
|
+
processingShards: Map<JobId, Job>[];
|
|
16
|
+
processingLocks: RWLock[];
|
|
17
|
+
jobIndex: Map<JobId, JobLocation>;
|
|
18
|
+
completedJobs: Set<JobId>;
|
|
19
|
+
jobResults: Map<JobId, unknown>;
|
|
20
|
+
customIdMap: Map<string, JobId>;
|
|
21
|
+
}
|
|
22
|
+
/** Get job by ID */
|
|
23
|
+
export declare function getJob(jobId: JobId, ctx: QueryContext): Promise<Job | null>;
|
|
24
|
+
/** Get job result */
|
|
25
|
+
export declare function getJobResult(jobId: JobId, ctx: QueryContext): unknown;
|
|
26
|
+
/** Get job by custom ID */
|
|
27
|
+
export declare function getJobByCustomId(customId: string, ctx: QueryContext): Job | null;
|
|
28
|
+
/** Get job progress */
|
|
29
|
+
export declare function getJobProgress(jobId: JobId, ctx: QueryContext): {
|
|
30
|
+
progress: number;
|
|
31
|
+
message: string | null;
|
|
32
|
+
} | null;
|
|
33
|
+
//# sourceMappingURL=queryOperations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryOperations.d.ts","sourceRoot":"","sources":["../../../src/application/operations/queryOperations.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,mBAAmB,CAAC;AAE9D,mCAAmC;AACnC,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,gBAAgB,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC;IACpC,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,EAAE,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAClC,aAAa,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IAC1B,UAAU,EAAE,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAChC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;CACjC;AAED,oBAAoB;AACpB,wBAAsB,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAmBjF;AAED,qBAAqB;AACrB,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAErE;AAED,2BAA2B;AAC3B,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,GAAG,GAAG,IAAI,CAchF;AAED,uBAAuB;AACvB,wBAAgB,cAAc,CAC5B,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,YAAY,GAChB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,CAQrD"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query Operations
|
|
3
|
+
* Get job, get result, get progress
|
|
4
|
+
*/
|
|
5
|
+
import { withReadLock } from '../../shared/lock';
|
|
6
|
+
/** Get job by ID */
|
|
7
|
+
export async function getJob(jobId, ctx) {
|
|
8
|
+
const location = ctx.jobIndex.get(jobId);
|
|
9
|
+
if (!location)
|
|
10
|
+
return null;
|
|
11
|
+
switch (location.type) {
|
|
12
|
+
case 'queue': {
|
|
13
|
+
return await withReadLock(ctx.shardLocks[location.shardIdx], () => {
|
|
14
|
+
return ctx.shards[location.shardIdx].getQueue(location.queueName).find(jobId);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
case 'processing': {
|
|
18
|
+
return await withReadLock(ctx.processingLocks[location.shardIdx], () => {
|
|
19
|
+
return ctx.processingShards[location.shardIdx].get(jobId) ?? null;
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
case 'completed':
|
|
23
|
+
case 'dlq':
|
|
24
|
+
return ctx.storage?.getJob(jobId) ?? null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/** Get job result */
|
|
28
|
+
export function getJobResult(jobId, ctx) {
|
|
29
|
+
return ctx.jobResults.get(jobId) ?? ctx.storage?.getResult(jobId);
|
|
30
|
+
}
|
|
31
|
+
/** Get job by custom ID */
|
|
32
|
+
export function getJobByCustomId(customId, ctx) {
|
|
33
|
+
const jobId = ctx.customIdMap.get(customId);
|
|
34
|
+
if (!jobId)
|
|
35
|
+
return null;
|
|
36
|
+
const location = ctx.jobIndex.get(jobId);
|
|
37
|
+
if (!location)
|
|
38
|
+
return null;
|
|
39
|
+
if (location.type === 'queue') {
|
|
40
|
+
return ctx.shards[location.shardIdx].getQueue(location.queueName).find(jobId);
|
|
41
|
+
}
|
|
42
|
+
if (location.type === 'processing') {
|
|
43
|
+
return ctx.processingShards[location.shardIdx].get(jobId) ?? null;
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
/** Get job progress */
|
|
48
|
+
export function getJobProgress(jobId, ctx) {
|
|
49
|
+
const location = ctx.jobIndex.get(jobId);
|
|
50
|
+
if (location?.type !== 'processing')
|
|
51
|
+
return null;
|
|
52
|
+
const job = ctx.processingShards[location.shardIdx].get(jobId);
|
|
53
|
+
if (!job)
|
|
54
|
+
return null;
|
|
55
|
+
return { progress: job.progress, message: job.progressMessage };
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=queryOperations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryOperations.js","sourceRoot":"","sources":["../../../src/application/operations/queryOperations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Queue Control Operations
|
|
3
|
+
* Pause, resume, drain, obliterate, clean, list queues
|
|
4
|
+
*/
|
|
5
|
+
import type { JobId } from '../../domain/types/job';
|
|
6
|
+
import type { Shard } from '../../domain/queue/shard';
|
|
7
|
+
/** Context for queue control operations */
|
|
8
|
+
export interface QueueControlContext {
|
|
9
|
+
shards: Shard[];
|
|
10
|
+
jobIndex: Map<JobId, {
|
|
11
|
+
type: string;
|
|
12
|
+
shardIdx?: number;
|
|
13
|
+
queueName?: string;
|
|
14
|
+
}>;
|
|
15
|
+
}
|
|
16
|
+
/** Pause a queue */
|
|
17
|
+
export declare function pauseQueue(queue: string, ctx: QueueControlContext): void;
|
|
18
|
+
/** Resume a queue */
|
|
19
|
+
export declare function resumeQueue(queue: string, ctx: QueueControlContext): void;
|
|
20
|
+
/** Check if queue is paused */
|
|
21
|
+
export declare function isQueuePaused(queue: string, ctx: QueueControlContext): boolean;
|
|
22
|
+
/** Drain all waiting jobs from queue */
|
|
23
|
+
export declare function drainQueue(queue: string, ctx: QueueControlContext): number;
|
|
24
|
+
/** Remove all queue data */
|
|
25
|
+
export declare function obliterateQueue(queue: string, ctx: QueueControlContext): void;
|
|
26
|
+
/** List all queue names */
|
|
27
|
+
export declare function listAllQueues(ctx: QueueControlContext): string[];
|
|
28
|
+
/** Clean old jobs from queue */
|
|
29
|
+
export declare function cleanQueue(queue: string, graceMs: number, ctx: QueueControlContext, state?: string, limit?: number): number;
|
|
30
|
+
/** Get count of jobs in queue */
|
|
31
|
+
export declare function getQueueCount(queue: string, ctx: QueueControlContext): number;
|
|
32
|
+
//# sourceMappingURL=queueControl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queueControl.d.ts","sourceRoot":"","sources":["../../../src/application/operations/queueControl.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAGtD,2CAA2C;AAC3C,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,QAAQ,EAAE,GAAG,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/E;AAED,oBAAoB;AACpB,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,mBAAmB,GAAG,IAAI,CAGxE;AAED,qBAAqB;AACrB,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,mBAAmB,GAAG,IAAI,CAGzE;AAED,+BAA+B;AAC/B,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAG9E;AAED,wCAAwC;AACxC,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,mBAAmB,GAAG,MAAM,CAG1E;AAED,4BAA4B;AAC5B,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,mBAAmB,GAAG,IAAI,CAG7E;AAED,2BAA2B;AAC3B,wBAAgB,aAAa,CAAC,GAAG,EAAE,mBAAmB,GAAG,MAAM,EAAE,CAQhE;AAED,gCAAgC;AAChC,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,mBAAmB,EACxB,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,MAAM,CA0BR;AAED,iCAAiC;AACjC,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,mBAAmB,GAAG,MAAM,CAI7E"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Queue Control Operations
|
|
3
|
+
* Pause, resume, drain, obliterate, clean, list queues
|
|
4
|
+
*/
|
|
5
|
+
import { shardIndex, SHARD_COUNT } from '../../shared/hash';
|
|
6
|
+
/** Pause a queue */
|
|
7
|
+
export function pauseQueue(queue, ctx) {
|
|
8
|
+
const idx = shardIndex(queue);
|
|
9
|
+
ctx.shards[idx].pause(queue);
|
|
10
|
+
}
|
|
11
|
+
/** Resume a queue */
|
|
12
|
+
export function resumeQueue(queue, ctx) {
|
|
13
|
+
const idx = shardIndex(queue);
|
|
14
|
+
ctx.shards[idx].resume(queue);
|
|
15
|
+
}
|
|
16
|
+
/** Check if queue is paused */
|
|
17
|
+
export function isQueuePaused(queue, ctx) {
|
|
18
|
+
const idx = shardIndex(queue);
|
|
19
|
+
return ctx.shards[idx].isPaused(queue);
|
|
20
|
+
}
|
|
21
|
+
/** Drain all waiting jobs from queue */
|
|
22
|
+
export function drainQueue(queue, ctx) {
|
|
23
|
+
const idx = shardIndex(queue);
|
|
24
|
+
return ctx.shards[idx].drain(queue);
|
|
25
|
+
}
|
|
26
|
+
/** Remove all queue data */
|
|
27
|
+
export function obliterateQueue(queue, ctx) {
|
|
28
|
+
const idx = shardIndex(queue);
|
|
29
|
+
ctx.shards[idx].obliterate(queue);
|
|
30
|
+
}
|
|
31
|
+
/** List all queue names */
|
|
32
|
+
export function listAllQueues(ctx) {
|
|
33
|
+
const queues = new Set();
|
|
34
|
+
for (let i = 0; i < SHARD_COUNT; i++) {
|
|
35
|
+
for (const name of ctx.shards[i].getQueueNames()) {
|
|
36
|
+
queues.add(name);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return Array.from(queues);
|
|
40
|
+
}
|
|
41
|
+
/** Clean old jobs from queue */
|
|
42
|
+
export function cleanQueue(queue, graceMs, ctx, state, limit) {
|
|
43
|
+
const idx = shardIndex(queue);
|
|
44
|
+
const shard = ctx.shards[idx];
|
|
45
|
+
const now = Date.now();
|
|
46
|
+
const maxJobs = limit ?? 1000;
|
|
47
|
+
let cleaned = 0;
|
|
48
|
+
if (!state || state === 'waiting' || state === 'delayed') {
|
|
49
|
+
const q = shard.getQueue(queue);
|
|
50
|
+
const toRemove = [];
|
|
51
|
+
for (const job of q.values()) {
|
|
52
|
+
if (now - job.createdAt > graceMs) {
|
|
53
|
+
toRemove.push(job.id);
|
|
54
|
+
if (toRemove.length >= maxJobs)
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
for (const id of toRemove) {
|
|
59
|
+
q.remove(id);
|
|
60
|
+
ctx.jobIndex.delete(id);
|
|
61
|
+
cleaned++;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return cleaned;
|
|
65
|
+
}
|
|
66
|
+
/** Get count of jobs in queue */
|
|
67
|
+
export function getQueueCount(queue, ctx) {
|
|
68
|
+
const idx = shardIndex(queue);
|
|
69
|
+
const q = ctx.shards[idx].getQueue(queue);
|
|
70
|
+
return q.size;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=queueControl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queueControl.js","sourceRoot":"","sources":["../../../src/application/operations/queueControl.ts"],"names":[],"mappings":"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"}
|