@nikx/dory-worker 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/src/worker.ts ADDED
@@ -0,0 +1,64 @@
1
+ import { Worker } from "bullmq";
2
+ import IORedis from "ioredis";
3
+ import type { WorkerConfig } from "./config";
4
+ import { processRunJob } from "./processor";
5
+ import { logger } from "./logger";
6
+
7
+ export const RUN_EXECUTION_QUEUE = "run-execution";
8
+
9
+ export function createRedisConnection(config: WorkerConfig): IORedis {
10
+ const conn = config.redisUrl
11
+ ? new IORedis(config.redisUrl, { maxRetriesPerRequest: null })
12
+ : new IORedis({
13
+ host: config.redisHost,
14
+ port: config.redisPort,
15
+ password: config.redisPassword,
16
+ maxRetriesPerRequest: null,
17
+ });
18
+
19
+ conn.on("connect", () => logger.info("Redis connected"));
20
+ conn.on("error", (err: Error) => logger.error(`Redis error: ${err.message}`));
21
+ conn.on("reconnecting", () => logger.warn("Redis reconnecting..."));
22
+
23
+ return conn;
24
+ }
25
+
26
+ export function createWorker(config: WorkerConfig, redis: IORedis): Worker {
27
+ const worker = new Worker(
28
+ RUN_EXECUTION_QUEUE,
29
+ (job) => processRunJob(config, job),
30
+ {
31
+ connection: redis,
32
+ concurrency: config.maxConcurrentRuns,
33
+ lockDuration: 300_000, // 5 min — containers can be long-running
34
+ stalledInterval: 30_000, // check for stalled jobs every 30 s
35
+ maxStalledCount: 2, // re-queue once, then fail
36
+ },
37
+ );
38
+
39
+ worker.on("completed", (job) => {
40
+ logger.info(`Job ${job.id} completed`);
41
+ });
42
+
43
+ worker.on("failed", (job, err) => {
44
+ logger.error(`Job ${job?.id ?? "unknown"} failed: ${err.message}`);
45
+ });
46
+
47
+ worker.on("stalled", (jobId: string) => {
48
+ logger.warn(`Job ${jobId} stalled — BullMQ will re-queue or fail it`);
49
+ });
50
+
51
+ worker.on("error", (err: Error) => {
52
+ // Suppress the well-known "Missing lock" race condition — BullMQ stalled-job
53
+ // detection will recover the job automatically.
54
+ if (err.message?.includes("Missing lock")) {
55
+ logger.warn(
56
+ `Lock expired before retry could be scheduled — job will be recovered. (${err.message})`,
57
+ );
58
+ return;
59
+ }
60
+ logger.error(`Worker error: ${err.message}`);
61
+ });
62
+
63
+ return worker;
64
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "commonjs",
5
+ "lib": ["ES2022"],
6
+ "outDir": "dist",
7
+ "rootDir": "src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "resolveJsonModule": true,
12
+ "declaration": true,
13
+ "declarationMap": true,
14
+ "sourceMap": true
15
+ },
16
+ "include": ["src/**/*"],
17
+ "exclude": ["node_modules", "dist"]
18
+ }