@sidequest/engine 1.0.0-next.10

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.
Files changed (81) hide show
  1. package/dist/engine.cjs +189 -0
  2. package/dist/engine.cjs.map +1 -0
  3. package/dist/engine.d.ts +122 -0
  4. package/dist/engine.js +187 -0
  5. package/dist/engine.js.map +1 -0
  6. package/dist/execution/dispatcher.cjs +90 -0
  7. package/dist/execution/dispatcher.cjs.map +1 -0
  8. package/dist/execution/dispatcher.d.ts +44 -0
  9. package/dist/execution/dispatcher.js +88 -0
  10. package/dist/execution/dispatcher.js.map +1 -0
  11. package/dist/execution/executor-manager.cjs +151 -0
  12. package/dist/execution/executor-manager.cjs.map +1 -0
  13. package/dist/execution/executor-manager.d.ts +51 -0
  14. package/dist/execution/executor-manager.js +149 -0
  15. package/dist/execution/executor-manager.js.map +1 -0
  16. package/dist/execution/queue-manager.cjs +43 -0
  17. package/dist/execution/queue-manager.cjs.map +1 -0
  18. package/dist/execution/queue-manager.d.ts +23 -0
  19. package/dist/execution/queue-manager.js +41 -0
  20. package/dist/execution/queue-manager.js.map +1 -0
  21. package/dist/index.cjs +38 -0
  22. package/dist/index.cjs.map +1 -0
  23. package/dist/index.d.ts +16 -0
  24. package/dist/index.js +17 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/job/constants.cjs +30 -0
  27. package/dist/job/constants.cjs.map +1 -0
  28. package/dist/job/constants.d.ts +20 -0
  29. package/dist/job/constants.js +28 -0
  30. package/dist/job/constants.js.map +1 -0
  31. package/dist/job/job-builder.cjs +153 -0
  32. package/dist/job/job-builder.cjs.map +1 -0
  33. package/dist/job/job-builder.d.ts +115 -0
  34. package/dist/job/job-builder.js +151 -0
  35. package/dist/job/job-builder.js.map +1 -0
  36. package/dist/job/job-transitioner.cjs +36 -0
  37. package/dist/job/job-transitioner.cjs.map +1 -0
  38. package/dist/job/job-transitioner.d.ts +21 -0
  39. package/dist/job/job-transitioner.js +34 -0
  40. package/dist/job/job-transitioner.js.map +1 -0
  41. package/dist/job/job.cjs +250 -0
  42. package/dist/job/job.cjs.map +1 -0
  43. package/dist/job/job.d.ts +178 -0
  44. package/dist/job/job.js +248 -0
  45. package/dist/job/job.js.map +1 -0
  46. package/dist/queue/grant-queue-config.cjs +49 -0
  47. package/dist/queue/grant-queue-config.cjs.map +1 -0
  48. package/dist/queue/grant-queue-config.d.ts +32 -0
  49. package/dist/queue/grant-queue-config.js +46 -0
  50. package/dist/queue/grant-queue-config.js.map +1 -0
  51. package/dist/routines/cleanup-finished-job.cjs +17 -0
  52. package/dist/routines/cleanup-finished-job.cjs.map +1 -0
  53. package/dist/routines/cleanup-finished-job.d.ts +10 -0
  54. package/dist/routines/cleanup-finished-job.js +15 -0
  55. package/dist/routines/cleanup-finished-job.js.map +1 -0
  56. package/dist/routines/release-stale-jobs.cjs +28 -0
  57. package/dist/routines/release-stale-jobs.cjs.map +1 -0
  58. package/dist/routines/release-stale-jobs.d.ts +12 -0
  59. package/dist/routines/release-stale-jobs.js +26 -0
  60. package/dist/routines/release-stale-jobs.js.map +1 -0
  61. package/dist/shared-runner/runner-pool.cjs +46 -0
  62. package/dist/shared-runner/runner-pool.cjs.map +1 -0
  63. package/dist/shared-runner/runner-pool.d.ts +28 -0
  64. package/dist/shared-runner/runner-pool.js +44 -0
  65. package/dist/shared-runner/runner-pool.js.map +1 -0
  66. package/dist/shared-runner/runner.cjs +39 -0
  67. package/dist/shared-runner/runner.cjs.map +1 -0
  68. package/dist/shared-runner/runner.d.ts +10 -0
  69. package/dist/shared-runner/runner.js +35 -0
  70. package/dist/shared-runner/runner.js.map +1 -0
  71. package/dist/utils/shutdown.cjs +53 -0
  72. package/dist/utils/shutdown.cjs.map +1 -0
  73. package/dist/utils/shutdown.d.ts +9 -0
  74. package/dist/utils/shutdown.js +50 -0
  75. package/dist/utils/shutdown.js.map +1 -0
  76. package/dist/workers/main.cjs +153 -0
  77. package/dist/workers/main.cjs.map +1 -0
  78. package/dist/workers/main.d.ts +39 -0
  79. package/dist/workers/main.js +151 -0
  80. package/dist/workers/main.js.map +1 -0
  81. package/package.json +30 -0
@@ -0,0 +1,153 @@
1
+ 'use strict';
2
+
3
+ var core = require('@sidequest/core');
4
+ var cron = require('node-cron');
5
+ var engine = require('../engine.cjs');
6
+ var dispatcher = require('../execution/dispatcher.cjs');
7
+ var executorManager = require('../execution/executor-manager.cjs');
8
+ var queueManager = require('../execution/queue-manager.cjs');
9
+ var cleanupFinishedJob = require('../routines/cleanup-finished-job.cjs');
10
+ var releaseStaleJobs = require('../routines/release-stale-jobs.cjs');
11
+ var shutdown = require('../utils/shutdown.cjs');
12
+
13
+ class MainWorker {
14
+ shuttingDown = false;
15
+ dispatcher;
16
+ engine = new engine.Engine();
17
+ backend;
18
+ /**
19
+ * Starts a Sidequest worker process with the given configuration.
20
+ * @param sidequestConfig The Sidequest configuration for the worker.
21
+ */
22
+ async runWorker(sidequestConfig) {
23
+ if (!this.shuttingDown) {
24
+ try {
25
+ const nonNullConfig = await this.engine.configure(sidequestConfig);
26
+ this.backend = this.engine.getBackend();
27
+ this.dispatcher = new dispatcher.Dispatcher(this.backend, new queueManager.QueueManager(this.backend, nonNullConfig.queues), new executorManager.ExecutorManager(this.backend, nonNullConfig.maxConcurrentJobs, nonNullConfig.minThreads, nonNullConfig.maxThreads));
28
+ this.dispatcher.start();
29
+ await this.startCron(nonNullConfig.releaseStaleJobsIntervalMin, nonNullConfig.releaseStaleJobsMaxStaleMs, nonNullConfig.releaseStaleJobsMaxClaimedMs, nonNullConfig.cleanupFinishedJobsIntervalMin, nonNullConfig.cleanupFinishedJobsOlderThan);
30
+ }
31
+ catch (error) {
32
+ core.logger("Worker").error(error);
33
+ process.exit(1);
34
+ }
35
+ }
36
+ else {
37
+ core.logger("Worker").warn("Worker is already shutting down, ignoring run signal.");
38
+ }
39
+ }
40
+ /**
41
+ * Gracefully shuts down the worker and releases resources.
42
+ */
43
+ async shutdown() {
44
+ if (!this.shuttingDown) {
45
+ this.shuttingDown = true;
46
+ await this.dispatcher?.stop();
47
+ await this.engine.close();
48
+ }
49
+ }
50
+ /**
51
+ * Starts cron job for releasing stale jobs.
52
+ * Also executes the task immediately.
53
+ */
54
+ async startAndExecuteStaleJobsReleaseCron(intervalMin, maxStaleMs, maxClaimedMs) {
55
+ if (!this.backend) {
56
+ throw new Error("Backend is not initialized. Cannot start stale jobs release cron.");
57
+ }
58
+ core.logger("Worker").debug(`Starting stale jobs release cron with interval: ${intervalMin} minutes`);
59
+ const releaseTask = cron.schedule(`*/${intervalMin} * * * *`, async () => {
60
+ try {
61
+ core.logger("Worker").debug("Running stale jobs release task");
62
+ await releaseStaleJobs.releaseStaleJobs(this.backend, maxStaleMs, maxClaimedMs);
63
+ }
64
+ catch (error) {
65
+ core.logger("Worker").error("Error on running ReleaseStaleJob!", error);
66
+ }
67
+ });
68
+ return releaseTask.execute();
69
+ }
70
+ /**
71
+ * Starts cron job for cleaning up finished jobs.
72
+ * Also executes the task immediately.
73
+ */
74
+ async startAndExecuteFinishedJobsCleanupCron(intervalMin, cutoffMs) {
75
+ if (!this.backend) {
76
+ throw new Error("Backend is not initialized. Cannot start finished jobs cleanup cron.");
77
+ }
78
+ core.logger("Worker").debug(`Starting finished jobs cleanup cron with interval: ${intervalMin} minutes`);
79
+ const cleanupTask = cron.schedule(`*/${intervalMin} * * * *`, async () => {
80
+ try {
81
+ core.logger("Worker").debug("Running finished jobs cleanup task");
82
+ await cleanupFinishedJob.cleanupFinishedJobs(this.backend, cutoffMs);
83
+ }
84
+ catch (error) {
85
+ core.logger("Worker").error("Error on running CleanupJob!", error);
86
+ }
87
+ });
88
+ return cleanupTask.execute();
89
+ }
90
+ /**
91
+ * Starts cron jobs for releasing stale jobs and cleaning up finished jobs.
92
+ *
93
+ * @param staleIntervalMin Interval in minutes for releasing stale jobs, or false to disable.
94
+ * @param maxStaleMs Maximum age in milliseconds for stale jobs.
95
+ * @param maxClaimedMs Maximum age in milliseconds for claimed jobs.
96
+ * @param cleanupIntervalMin Interval in minutes for cleaning up finished jobs, or false to disable
97
+ * @param cleanupCutoffMs Maximum age in milliseconds for finished jobs to be cleaned up.
98
+ */
99
+ async startCron(staleIntervalMin, maxStaleMs, maxClaimedMs, cleanupIntervalMin, cleanupCutoffMs) {
100
+ core.logger("Worker").debug("Starting cron jobs");
101
+ const promises = [];
102
+ if (staleIntervalMin !== false) {
103
+ promises.push(this.startAndExecuteStaleJobsReleaseCron(staleIntervalMin, maxStaleMs, maxClaimedMs));
104
+ }
105
+ if (cleanupIntervalMin !== false) {
106
+ promises.push(this.startAndExecuteFinishedJobsCleanupCron(cleanupIntervalMin, cleanupCutoffMs));
107
+ }
108
+ await Promise.all(promises).catch((error) => {
109
+ core.logger("Worker").error(error);
110
+ });
111
+ }
112
+ }
113
+ const isChildProcess = !!process.send;
114
+ if (isChildProcess) {
115
+ const worker = new MainWorker();
116
+ process.on("message",
117
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
118
+ async ({ type, sidequestConfig }) => {
119
+ if (type === "start") {
120
+ if (!sidequestConfig) {
121
+ throw new Error("No Sidequest configuration provided to worker!");
122
+ }
123
+ if (!worker.shuttingDown) {
124
+ shutdown.gracefulShutdown(worker.shutdown.bind(worker), "Worker", sidequestConfig.gracefulShutdown);
125
+ core.logger("Worker").info("Starting worker with provided configuration...");
126
+ return await worker.runWorker(sidequestConfig);
127
+ }
128
+ else {
129
+ core.logger("Worker").warn("Worker is already shutting down, ignoring start signal.");
130
+ }
131
+ }
132
+ else if (type === "shutdown") {
133
+ if (!worker.shuttingDown) {
134
+ core.logger("Worker").info("Received shutdown message, shutting down worker...");
135
+ await worker.shutdown();
136
+ core.logger("Worker").info("Worker shutdown complete.");
137
+ process.exit(0);
138
+ }
139
+ else {
140
+ core.logger("Worker").debug("Worker is already shutting down, ignoring shutdown signal.");
141
+ }
142
+ }
143
+ });
144
+ process.on("disconnect", () => {
145
+ core.logger("Worker").error("Parent process disconnected, exiting...");
146
+ process.exit();
147
+ });
148
+ if (process.send)
149
+ process.send("ready");
150
+ }
151
+
152
+ exports.MainWorker = MainWorker;
153
+ //# sourceMappingURL=main.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.cjs","sources":["../../src/workers/main.ts"],"sourcesContent":[null],"names":["Engine","Dispatcher","QueueManager","ExecutorManager","logger","releaseStaleJobs","cleanupFinishedJobs","gracefulShutdown"],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { EngineConfig } from '../engine.js';
2
+
3
+ declare class MainWorker {
4
+ shuttingDown: boolean;
5
+ private dispatcher;
6
+ private engine;
7
+ private backend?;
8
+ /**
9
+ * Starts a Sidequest worker process with the given configuration.
10
+ * @param sidequestConfig The Sidequest configuration for the worker.
11
+ */
12
+ runWorker(sidequestConfig: EngineConfig): Promise<void>;
13
+ /**
14
+ * Gracefully shuts down the worker and releases resources.
15
+ */
16
+ shutdown(): Promise<void>;
17
+ /**
18
+ * Starts cron job for releasing stale jobs.
19
+ * Also executes the task immediately.
20
+ */
21
+ startAndExecuteStaleJobsReleaseCron(intervalMin: number, maxStaleMs: number, maxClaimedMs: number): Promise<unknown>;
22
+ /**
23
+ * Starts cron job for cleaning up finished jobs.
24
+ * Also executes the task immediately.
25
+ */
26
+ startAndExecuteFinishedJobsCleanupCron(intervalMin: number, cutoffMs: number): Promise<unknown>;
27
+ /**
28
+ * Starts cron jobs for releasing stale jobs and cleaning up finished jobs.
29
+ *
30
+ * @param staleIntervalMin Interval in minutes for releasing stale jobs, or false to disable.
31
+ * @param maxStaleMs Maximum age in milliseconds for stale jobs.
32
+ * @param maxClaimedMs Maximum age in milliseconds for claimed jobs.
33
+ * @param cleanupIntervalMin Interval in minutes for cleaning up finished jobs, or false to disable
34
+ * @param cleanupCutoffMs Maximum age in milliseconds for finished jobs to be cleaned up.
35
+ */
36
+ startCron(staleIntervalMin: number | false, maxStaleMs: number, maxClaimedMs: number, cleanupIntervalMin: number | false, cleanupCutoffMs: number): Promise<void>;
37
+ }
38
+
39
+ export { MainWorker };
@@ -0,0 +1,151 @@
1
+ import { logger } from '@sidequest/core';
2
+ import cron from 'node-cron';
3
+ import { Engine } from '../engine.js';
4
+ import { Dispatcher } from '../execution/dispatcher.js';
5
+ import { ExecutorManager } from '../execution/executor-manager.js';
6
+ import { QueueManager } from '../execution/queue-manager.js';
7
+ import { cleanupFinishedJobs } from '../routines/cleanup-finished-job.js';
8
+ import { releaseStaleJobs } from '../routines/release-stale-jobs.js';
9
+ import { gracefulShutdown } from '../utils/shutdown.js';
10
+
11
+ class MainWorker {
12
+ shuttingDown = false;
13
+ dispatcher;
14
+ engine = new Engine();
15
+ backend;
16
+ /**
17
+ * Starts a Sidequest worker process with the given configuration.
18
+ * @param sidequestConfig The Sidequest configuration for the worker.
19
+ */
20
+ async runWorker(sidequestConfig) {
21
+ if (!this.shuttingDown) {
22
+ try {
23
+ const nonNullConfig = await this.engine.configure(sidequestConfig);
24
+ this.backend = this.engine.getBackend();
25
+ this.dispatcher = new Dispatcher(this.backend, new QueueManager(this.backend, nonNullConfig.queues), new ExecutorManager(this.backend, nonNullConfig.maxConcurrentJobs, nonNullConfig.minThreads, nonNullConfig.maxThreads));
26
+ this.dispatcher.start();
27
+ await this.startCron(nonNullConfig.releaseStaleJobsIntervalMin, nonNullConfig.releaseStaleJobsMaxStaleMs, nonNullConfig.releaseStaleJobsMaxClaimedMs, nonNullConfig.cleanupFinishedJobsIntervalMin, nonNullConfig.cleanupFinishedJobsOlderThan);
28
+ }
29
+ catch (error) {
30
+ logger("Worker").error(error);
31
+ process.exit(1);
32
+ }
33
+ }
34
+ else {
35
+ logger("Worker").warn("Worker is already shutting down, ignoring run signal.");
36
+ }
37
+ }
38
+ /**
39
+ * Gracefully shuts down the worker and releases resources.
40
+ */
41
+ async shutdown() {
42
+ if (!this.shuttingDown) {
43
+ this.shuttingDown = true;
44
+ await this.dispatcher?.stop();
45
+ await this.engine.close();
46
+ }
47
+ }
48
+ /**
49
+ * Starts cron job for releasing stale jobs.
50
+ * Also executes the task immediately.
51
+ */
52
+ async startAndExecuteStaleJobsReleaseCron(intervalMin, maxStaleMs, maxClaimedMs) {
53
+ if (!this.backend) {
54
+ throw new Error("Backend is not initialized. Cannot start stale jobs release cron.");
55
+ }
56
+ logger("Worker").debug(`Starting stale jobs release cron with interval: ${intervalMin} minutes`);
57
+ const releaseTask = cron.schedule(`*/${intervalMin} * * * *`, async () => {
58
+ try {
59
+ logger("Worker").debug("Running stale jobs release task");
60
+ await releaseStaleJobs(this.backend, maxStaleMs, maxClaimedMs);
61
+ }
62
+ catch (error) {
63
+ logger("Worker").error("Error on running ReleaseStaleJob!", error);
64
+ }
65
+ });
66
+ return releaseTask.execute();
67
+ }
68
+ /**
69
+ * Starts cron job for cleaning up finished jobs.
70
+ * Also executes the task immediately.
71
+ */
72
+ async startAndExecuteFinishedJobsCleanupCron(intervalMin, cutoffMs) {
73
+ if (!this.backend) {
74
+ throw new Error("Backend is not initialized. Cannot start finished jobs cleanup cron.");
75
+ }
76
+ logger("Worker").debug(`Starting finished jobs cleanup cron with interval: ${intervalMin} minutes`);
77
+ const cleanupTask = cron.schedule(`*/${intervalMin} * * * *`, async () => {
78
+ try {
79
+ logger("Worker").debug("Running finished jobs cleanup task");
80
+ await cleanupFinishedJobs(this.backend, cutoffMs);
81
+ }
82
+ catch (error) {
83
+ logger("Worker").error("Error on running CleanupJob!", error);
84
+ }
85
+ });
86
+ return cleanupTask.execute();
87
+ }
88
+ /**
89
+ * Starts cron jobs for releasing stale jobs and cleaning up finished jobs.
90
+ *
91
+ * @param staleIntervalMin Interval in minutes for releasing stale jobs, or false to disable.
92
+ * @param maxStaleMs Maximum age in milliseconds for stale jobs.
93
+ * @param maxClaimedMs Maximum age in milliseconds for claimed jobs.
94
+ * @param cleanupIntervalMin Interval in minutes for cleaning up finished jobs, or false to disable
95
+ * @param cleanupCutoffMs Maximum age in milliseconds for finished jobs to be cleaned up.
96
+ */
97
+ async startCron(staleIntervalMin, maxStaleMs, maxClaimedMs, cleanupIntervalMin, cleanupCutoffMs) {
98
+ logger("Worker").debug("Starting cron jobs");
99
+ const promises = [];
100
+ if (staleIntervalMin !== false) {
101
+ promises.push(this.startAndExecuteStaleJobsReleaseCron(staleIntervalMin, maxStaleMs, maxClaimedMs));
102
+ }
103
+ if (cleanupIntervalMin !== false) {
104
+ promises.push(this.startAndExecuteFinishedJobsCleanupCron(cleanupIntervalMin, cleanupCutoffMs));
105
+ }
106
+ await Promise.all(promises).catch((error) => {
107
+ logger("Worker").error(error);
108
+ });
109
+ }
110
+ }
111
+ const isChildProcess = !!process.send;
112
+ if (isChildProcess) {
113
+ const worker = new MainWorker();
114
+ process.on("message",
115
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
116
+ async ({ type, sidequestConfig }) => {
117
+ if (type === "start") {
118
+ if (!sidequestConfig) {
119
+ throw new Error("No Sidequest configuration provided to worker!");
120
+ }
121
+ if (!worker.shuttingDown) {
122
+ gracefulShutdown(worker.shutdown.bind(worker), "Worker", sidequestConfig.gracefulShutdown);
123
+ logger("Worker").info("Starting worker with provided configuration...");
124
+ return await worker.runWorker(sidequestConfig);
125
+ }
126
+ else {
127
+ logger("Worker").warn("Worker is already shutting down, ignoring start signal.");
128
+ }
129
+ }
130
+ else if (type === "shutdown") {
131
+ if (!worker.shuttingDown) {
132
+ logger("Worker").info("Received shutdown message, shutting down worker...");
133
+ await worker.shutdown();
134
+ logger("Worker").info("Worker shutdown complete.");
135
+ process.exit(0);
136
+ }
137
+ else {
138
+ logger("Worker").debug("Worker is already shutting down, ignoring shutdown signal.");
139
+ }
140
+ }
141
+ });
142
+ process.on("disconnect", () => {
143
+ logger("Worker").error("Parent process disconnected, exiting...");
144
+ process.exit();
145
+ });
146
+ if (process.send)
147
+ process.send("ready");
148
+ }
149
+
150
+ export { MainWorker };
151
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sources":["../../src/workers/main.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@sidequest/engine",
3
+ "version": "1.0.0-next.10",
4
+ "type": "module",
5
+ "main": "./dist/index.cjs",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js",
11
+ "require": "./dist/index.cjs"
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "scripts": {
17
+ "build": "npx rollup -c",
18
+ "dev": "npx rollup -c -w",
19
+ "test:ci": "npx vitest run"
20
+ },
21
+ "license": "LGPL-3.0-or-later",
22
+ "dependencies": {
23
+ "@sidequest/backend": "1.0.0-next.10",
24
+ "@sidequest/core": "1.0.0-next.10",
25
+ "node-cron": "^4.1.1",
26
+ "piscina": "^5.1.2"
27
+ },
28
+ "packageManager": "yarn@4.9.2",
29
+ "stableVersion": "1.0.0-next.3"
30
+ }