@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.
- package/dist/engine.cjs +189 -0
- package/dist/engine.cjs.map +1 -0
- package/dist/engine.d.ts +122 -0
- package/dist/engine.js +187 -0
- package/dist/engine.js.map +1 -0
- package/dist/execution/dispatcher.cjs +90 -0
- package/dist/execution/dispatcher.cjs.map +1 -0
- package/dist/execution/dispatcher.d.ts +44 -0
- package/dist/execution/dispatcher.js +88 -0
- package/dist/execution/dispatcher.js.map +1 -0
- package/dist/execution/executor-manager.cjs +151 -0
- package/dist/execution/executor-manager.cjs.map +1 -0
- package/dist/execution/executor-manager.d.ts +51 -0
- package/dist/execution/executor-manager.js +149 -0
- package/dist/execution/executor-manager.js.map +1 -0
- package/dist/execution/queue-manager.cjs +43 -0
- package/dist/execution/queue-manager.cjs.map +1 -0
- package/dist/execution/queue-manager.d.ts +23 -0
- package/dist/execution/queue-manager.js +41 -0
- package/dist/execution/queue-manager.js.map +1 -0
- package/dist/index.cjs +38 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/job/constants.cjs +30 -0
- package/dist/job/constants.cjs.map +1 -0
- package/dist/job/constants.d.ts +20 -0
- package/dist/job/constants.js +28 -0
- package/dist/job/constants.js.map +1 -0
- package/dist/job/job-builder.cjs +153 -0
- package/dist/job/job-builder.cjs.map +1 -0
- package/dist/job/job-builder.d.ts +115 -0
- package/dist/job/job-builder.js +151 -0
- package/dist/job/job-builder.js.map +1 -0
- package/dist/job/job-transitioner.cjs +36 -0
- package/dist/job/job-transitioner.cjs.map +1 -0
- package/dist/job/job-transitioner.d.ts +21 -0
- package/dist/job/job-transitioner.js +34 -0
- package/dist/job/job-transitioner.js.map +1 -0
- package/dist/job/job.cjs +250 -0
- package/dist/job/job.cjs.map +1 -0
- package/dist/job/job.d.ts +178 -0
- package/dist/job/job.js +248 -0
- package/dist/job/job.js.map +1 -0
- package/dist/queue/grant-queue-config.cjs +49 -0
- package/dist/queue/grant-queue-config.cjs.map +1 -0
- package/dist/queue/grant-queue-config.d.ts +32 -0
- package/dist/queue/grant-queue-config.js +46 -0
- package/dist/queue/grant-queue-config.js.map +1 -0
- package/dist/routines/cleanup-finished-job.cjs +17 -0
- package/dist/routines/cleanup-finished-job.cjs.map +1 -0
- package/dist/routines/cleanup-finished-job.d.ts +10 -0
- package/dist/routines/cleanup-finished-job.js +15 -0
- package/dist/routines/cleanup-finished-job.js.map +1 -0
- package/dist/routines/release-stale-jobs.cjs +28 -0
- package/dist/routines/release-stale-jobs.cjs.map +1 -0
- package/dist/routines/release-stale-jobs.d.ts +12 -0
- package/dist/routines/release-stale-jobs.js +26 -0
- package/dist/routines/release-stale-jobs.js.map +1 -0
- package/dist/shared-runner/runner-pool.cjs +46 -0
- package/dist/shared-runner/runner-pool.cjs.map +1 -0
- package/dist/shared-runner/runner-pool.d.ts +28 -0
- package/dist/shared-runner/runner-pool.js +44 -0
- package/dist/shared-runner/runner-pool.js.map +1 -0
- package/dist/shared-runner/runner.cjs +39 -0
- package/dist/shared-runner/runner.cjs.map +1 -0
- package/dist/shared-runner/runner.d.ts +10 -0
- package/dist/shared-runner/runner.js +35 -0
- package/dist/shared-runner/runner.js.map +1 -0
- package/dist/utils/shutdown.cjs +53 -0
- package/dist/utils/shutdown.cjs.map +1 -0
- package/dist/utils/shutdown.d.ts +9 -0
- package/dist/utils/shutdown.js +50 -0
- package/dist/utils/shutdown.js.map +1 -0
- package/dist/workers/main.cjs +153 -0
- package/dist/workers/main.cjs.map +1 -0
- package/dist/workers/main.d.ts +39 -0
- package/dist/workers/main.js +151 -0
- package/dist/workers/main.js.map +1 -0
- package/package.json +30 -0
package/dist/engine.cjs
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var backend = require('@sidequest/backend');
|
|
4
|
+
var core = require('@sidequest/core');
|
|
5
|
+
var child_process = require('child_process');
|
|
6
|
+
var os = require('os');
|
|
7
|
+
var path = require('path');
|
|
8
|
+
var constants = require('./job/constants.cjs');
|
|
9
|
+
var jobBuilder = require('./job/job-builder.cjs');
|
|
10
|
+
var grantQueueConfig = require('./queue/grant-queue-config.cjs');
|
|
11
|
+
var shutdown = require('./utils/shutdown.cjs');
|
|
12
|
+
|
|
13
|
+
const workerPath = path.resolve(__dirname, "workers", "main.js");
|
|
14
|
+
/**
|
|
15
|
+
* The main engine for managing job queues and workers in Sidequest.
|
|
16
|
+
*/
|
|
17
|
+
class Engine {
|
|
18
|
+
/**
|
|
19
|
+
* Backend instance used by the engine.
|
|
20
|
+
* This is initialized when the engine is configured or started.
|
|
21
|
+
*/
|
|
22
|
+
backend;
|
|
23
|
+
/**
|
|
24
|
+
* Current configuration of the engine.
|
|
25
|
+
* This is set when the engine is configured or started.
|
|
26
|
+
* It contains all the necessary settings for the engine to operate, such as backend, queues, logger options, and job defaults.
|
|
27
|
+
*/
|
|
28
|
+
config;
|
|
29
|
+
/**
|
|
30
|
+
* Main worker process that runs the Sidequest engine.
|
|
31
|
+
* This is created when the engine is started and handles job processing.
|
|
32
|
+
*/
|
|
33
|
+
mainWorker;
|
|
34
|
+
/**
|
|
35
|
+
* Flag indicating whether the engine is currently shutting down.
|
|
36
|
+
* This is used to prevent multiple shutdown attempts and ensure graceful shutdown behavior.
|
|
37
|
+
*/
|
|
38
|
+
shuttingDown = false;
|
|
39
|
+
/**
|
|
40
|
+
* Configures the Sidequest engine with the provided configuration.
|
|
41
|
+
* @param config Optional configuration object.
|
|
42
|
+
* @returns The resolved configuration.
|
|
43
|
+
*/
|
|
44
|
+
async configure(config) {
|
|
45
|
+
if (this.config) {
|
|
46
|
+
core.logger("Engine").debug("Sidequest already configured");
|
|
47
|
+
return this.config;
|
|
48
|
+
}
|
|
49
|
+
this.config = {
|
|
50
|
+
queues: config?.queues ?? [],
|
|
51
|
+
backend: {
|
|
52
|
+
driver: config?.backend?.driver ?? "@sidequest/sqlite-backend",
|
|
53
|
+
config: config?.backend?.config ?? "./sidequest.sqlite",
|
|
54
|
+
},
|
|
55
|
+
cleanupFinishedJobsIntervalMin: config?.cleanupFinishedJobsIntervalMin ?? 60,
|
|
56
|
+
cleanupFinishedJobsOlderThan: config?.cleanupFinishedJobsOlderThan ?? 30 * 24 * 60 * 60 * 1000,
|
|
57
|
+
releaseStaleJobsIntervalMin: config?.releaseStaleJobsIntervalMin ?? 60,
|
|
58
|
+
maxConcurrentJobs: config?.maxConcurrentJobs ?? 10,
|
|
59
|
+
skipMigration: config?.skipMigration ?? false,
|
|
60
|
+
logger: {
|
|
61
|
+
level: config?.logger?.level ?? "info",
|
|
62
|
+
json: config?.logger?.json ?? false,
|
|
63
|
+
},
|
|
64
|
+
gracefulShutdown: config?.gracefulShutdown ?? true,
|
|
65
|
+
minThreads: config?.minThreads ?? os.cpus().length,
|
|
66
|
+
maxThreads: config?.maxThreads ?? os.cpus().length * 2,
|
|
67
|
+
releaseStaleJobsMaxStaleMs: config?.releaseStaleJobsMaxStaleMs ?? backend.MISC_FALLBACK.maxStaleMs, // 10 minutes
|
|
68
|
+
releaseStaleJobsMaxClaimedMs: config?.releaseStaleJobsMaxClaimedMs ?? backend.MISC_FALLBACK.maxClaimedMs, // 1 minute
|
|
69
|
+
jobDefaults: {
|
|
70
|
+
queue: config?.jobDefaults?.queue ?? constants.JOB_BUILDER_FALLBACK.queue,
|
|
71
|
+
maxAttempts: config?.jobDefaults?.maxAttempts ?? constants.JOB_BUILDER_FALLBACK.maxAttempts,
|
|
72
|
+
availableAt: config?.jobDefaults?.availableAt ?? constants.JOB_BUILDER_FALLBACK.availableAt,
|
|
73
|
+
timeout: config?.jobDefaults?.timeout ?? constants.JOB_BUILDER_FALLBACK.timeout,
|
|
74
|
+
uniqueness: config?.jobDefaults?.uniqueness ?? constants.JOB_BUILDER_FALLBACK.uniqueness,
|
|
75
|
+
},
|
|
76
|
+
queueDefaults: {
|
|
77
|
+
concurrency: config?.queueDefaults?.concurrency ?? backend.QUEUE_FALLBACK.concurrency,
|
|
78
|
+
priority: config?.queueDefaults?.priority ?? backend.QUEUE_FALLBACK.priority,
|
|
79
|
+
state: config?.queueDefaults?.state ?? backend.QUEUE_FALLBACK.state,
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
if (this.config.logger) {
|
|
83
|
+
core.configureLogger(this.config.logger);
|
|
84
|
+
}
|
|
85
|
+
core.logger("Engine").debug(`Configuring Sidequest engine: ${JSON.stringify(this.config)}`);
|
|
86
|
+
this.backend = await backend.createBackendFromDriver(this.config.backend);
|
|
87
|
+
if (!this.config.skipMigration) {
|
|
88
|
+
await this.backend.migrate();
|
|
89
|
+
}
|
|
90
|
+
if (this.config.queues) {
|
|
91
|
+
for (const queue of this.config.queues) {
|
|
92
|
+
await grantQueueConfig.grantQueueConfig(this.backend, queue, this.config.queueDefaults);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return this.config;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Starts the Sidequest engine and worker process.
|
|
99
|
+
* @param config Optional configuration object.
|
|
100
|
+
*/
|
|
101
|
+
async start(config) {
|
|
102
|
+
await this.configure(config);
|
|
103
|
+
core.logger("Engine").info(`Starting Sidequest using backend ${this.config.backend.driver}`);
|
|
104
|
+
return new Promise((resolve, reject) => {
|
|
105
|
+
const timeout = setTimeout(() => {
|
|
106
|
+
reject(new Error("Timeout on starting sidequest fork!"));
|
|
107
|
+
}, 5000);
|
|
108
|
+
if (!this.mainWorker) {
|
|
109
|
+
const runWorker = () => {
|
|
110
|
+
core.logger("Engine").debug("Starting main worker...");
|
|
111
|
+
this.mainWorker = child_process.fork(workerPath);
|
|
112
|
+
core.logger("Engine").debug(`Worker PID: ${this.mainWorker.pid}`);
|
|
113
|
+
this.mainWorker.on("message", (msg) => {
|
|
114
|
+
if (msg === "ready") {
|
|
115
|
+
core.logger("Engine").debug("Main worker is ready");
|
|
116
|
+
this.mainWorker?.send({ type: "start", sidequestConfig: this.config });
|
|
117
|
+
clearTimeout(timeout);
|
|
118
|
+
resolve();
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
this.mainWorker.on("exit", () => {
|
|
122
|
+
if (!this.shuttingDown) {
|
|
123
|
+
core.logger("Engine").error("Sidequest main exited, creating new...");
|
|
124
|
+
runWorker();
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
runWorker();
|
|
129
|
+
shutdown.gracefulShutdown(this.close.bind(this), "Engine", this.config.gracefulShutdown);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Gets the current engine configuration.
|
|
135
|
+
* @returns The current configuration, if set.
|
|
136
|
+
*/
|
|
137
|
+
getConfig() {
|
|
138
|
+
return this.config;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Gets the backend instance in use by the engine.
|
|
142
|
+
* @returns The backend instance, if set.
|
|
143
|
+
*/
|
|
144
|
+
getBackend() {
|
|
145
|
+
return this.backend;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Closes the engine and releases resources.
|
|
149
|
+
*/
|
|
150
|
+
async close() {
|
|
151
|
+
if (!this.shuttingDown) {
|
|
152
|
+
this.shuttingDown = true;
|
|
153
|
+
core.logger("Engine").debug("Closing Sidequest engine...");
|
|
154
|
+
if (this.mainWorker) {
|
|
155
|
+
this.mainWorker.send({ type: "shutdown" });
|
|
156
|
+
await new Promise((resolve) => {
|
|
157
|
+
this.mainWorker.on("exit", resolve);
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
await this.backend?.close();
|
|
161
|
+
this.config = undefined;
|
|
162
|
+
this.backend = undefined;
|
|
163
|
+
this.mainWorker = undefined;
|
|
164
|
+
// Reset the shutting down flag after closing
|
|
165
|
+
// This allows the engine to be reconfigured or restarted later
|
|
166
|
+
shutdown.clearGracefulShutdown();
|
|
167
|
+
core.logger("Engine").debug("Sidequest engine closed.");
|
|
168
|
+
this.shuttingDown = false;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Builds a job using the provided job class.
|
|
173
|
+
* @param JobClass The job class constructor.
|
|
174
|
+
* @returns A new JobBuilder instance for the job class.
|
|
175
|
+
*/
|
|
176
|
+
build(JobClass) {
|
|
177
|
+
if (!this.config || !this.backend) {
|
|
178
|
+
throw new Error("Engine not configured. Call engine.configure() or engine.start() first.");
|
|
179
|
+
}
|
|
180
|
+
if (this.shuttingDown) {
|
|
181
|
+
throw new Error("Engine is shutting down, cannot build job.");
|
|
182
|
+
}
|
|
183
|
+
core.logger("Engine").debug(`Building job for class: ${JobClass.name}`);
|
|
184
|
+
return new jobBuilder.JobBuilder(this.backend, JobClass, this.config.jobDefaults);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
exports.Engine = Engine;
|
|
189
|
+
//# sourceMappingURL=engine.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.cjs","sources":["../src/engine.ts"],"sourcesContent":[null],"names":["logger","cpus","MISC_FALLBACK","JOB_BUILDER_FALLBACK","QUEUE_FALLBACK","configureLogger","createBackendFromDriver","grantQueueConfig","fork","gracefulShutdown","clearGracefulShutdown","JobBuilder"],"mappings":"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"}
|
package/dist/engine.d.ts
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { BackendConfig, NewQueueData, Backend } from '@sidequest/backend';
|
|
2
|
+
import { LoggerOptions } from '@sidequest/core';
|
|
3
|
+
import { JobClassType } from './job/job.js';
|
|
4
|
+
import { JobBuilderDefaults, JobBuilder } from './job/job-builder.js';
|
|
5
|
+
import { QueueDefaults } from './queue/grant-queue-config.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Configuration options for the Sidequest engine.
|
|
9
|
+
*/
|
|
10
|
+
interface EngineConfig {
|
|
11
|
+
/** Backend configuration. Defaults to `@sidequest/sqlite-backend` and `./sidequest.sqlite` file */
|
|
12
|
+
backend?: BackendConfig;
|
|
13
|
+
/** List of queue configurations. Defaults to `[]` */
|
|
14
|
+
queues?: NewQueueData[];
|
|
15
|
+
/** Logger configuration options. Defaults to `info` and no json */
|
|
16
|
+
logger?: LoggerOptions;
|
|
17
|
+
/** Maximum number of concurrent jobs. Defaults to `10` */
|
|
18
|
+
maxConcurrentJobs?: number;
|
|
19
|
+
/** Whether to skip migration when starting the engine. Defaults to `false` */
|
|
20
|
+
skipMigration?: boolean;
|
|
21
|
+
/** Frequency in minutes for releasing stale jobs. Set to false to disable. Defaults to 60 min */
|
|
22
|
+
releaseStaleJobsIntervalMin?: number | false;
|
|
23
|
+
/** Maximum age in milliseconds a running job must be to be considered a stale job. Defaults to 10 minutes */
|
|
24
|
+
releaseStaleJobsMaxStaleMs?: number;
|
|
25
|
+
/** Maximum age in milliseconds a claimed job must be to be considered stale. Defaults to 1 minute */
|
|
26
|
+
releaseStaleJobsMaxClaimedMs?: number;
|
|
27
|
+
/** Frequency in minutes for cleaning up finished jobs. Set to false to disable. Defaults to 60 min */
|
|
28
|
+
cleanupFinishedJobsIntervalMin?: number | false;
|
|
29
|
+
/** Time in milliseconds to clean up finished jobs older than this value. Defaults to 30 days */
|
|
30
|
+
cleanupFinishedJobsOlderThan?: number;
|
|
31
|
+
/** Whether to enable graceful shutdown handling. Defaults to `true` */
|
|
32
|
+
gracefulShutdown?: boolean;
|
|
33
|
+
/** Minimum number of worker threads to use. Defaults to number of CPUs */
|
|
34
|
+
minThreads?: number;
|
|
35
|
+
/** Maximum number of worker threads to use. Defaults to `minThreads * 2` */
|
|
36
|
+
maxThreads?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Default job builder configuration.
|
|
39
|
+
* This allows setting default values for job properties like queue, timeout, uniqueness, etc.
|
|
40
|
+
* If not provided during job build, defaults will be used.
|
|
41
|
+
*
|
|
42
|
+
* @see {@link JobBuilderDefaults} for more details
|
|
43
|
+
*/
|
|
44
|
+
jobDefaults?: JobBuilderDefaults;
|
|
45
|
+
/**
|
|
46
|
+
* Default queue configuration.
|
|
47
|
+
* This allows setting default values for queue properties like concurrency, priority, etc.
|
|
48
|
+
* If not provided during queue creation, defaults will be used.
|
|
49
|
+
*
|
|
50
|
+
* @see {@link QueueDefaults} for more details
|
|
51
|
+
*/
|
|
52
|
+
queueDefaults?: QueueDefaults;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Non-nullable version of the EngineConfig type.
|
|
56
|
+
* Ensures all properties are defined and not null.
|
|
57
|
+
*
|
|
58
|
+
* @see {@link EngineConfig} for the original type.
|
|
59
|
+
*/
|
|
60
|
+
type NonNullableEngineConfig = {
|
|
61
|
+
[P in keyof EngineConfig]-?: NonNullable<EngineConfig[P]>;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* The main engine for managing job queues and workers in Sidequest.
|
|
65
|
+
*/
|
|
66
|
+
declare class Engine {
|
|
67
|
+
/**
|
|
68
|
+
* Backend instance used by the engine.
|
|
69
|
+
* This is initialized when the engine is configured or started.
|
|
70
|
+
*/
|
|
71
|
+
private backend?;
|
|
72
|
+
/**
|
|
73
|
+
* Current configuration of the engine.
|
|
74
|
+
* This is set when the engine is configured or started.
|
|
75
|
+
* It contains all the necessary settings for the engine to operate, such as backend, queues, logger options, and job defaults.
|
|
76
|
+
*/
|
|
77
|
+
private config?;
|
|
78
|
+
/**
|
|
79
|
+
* Main worker process that runs the Sidequest engine.
|
|
80
|
+
* This is created when the engine is started and handles job processing.
|
|
81
|
+
*/
|
|
82
|
+
private mainWorker?;
|
|
83
|
+
/**
|
|
84
|
+
* Flag indicating whether the engine is currently shutting down.
|
|
85
|
+
* This is used to prevent multiple shutdown attempts and ensure graceful shutdown behavior.
|
|
86
|
+
*/
|
|
87
|
+
private shuttingDown;
|
|
88
|
+
/**
|
|
89
|
+
* Configures the Sidequest engine with the provided configuration.
|
|
90
|
+
* @param config Optional configuration object.
|
|
91
|
+
* @returns The resolved configuration.
|
|
92
|
+
*/
|
|
93
|
+
configure(config?: EngineConfig): Promise<NonNullableEngineConfig>;
|
|
94
|
+
/**
|
|
95
|
+
* Starts the Sidequest engine and worker process.
|
|
96
|
+
* @param config Optional configuration object.
|
|
97
|
+
*/
|
|
98
|
+
start(config: EngineConfig): Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* Gets the current engine configuration.
|
|
101
|
+
* @returns The current configuration, if set.
|
|
102
|
+
*/
|
|
103
|
+
getConfig(): NonNullableEngineConfig | undefined;
|
|
104
|
+
/**
|
|
105
|
+
* Gets the backend instance in use by the engine.
|
|
106
|
+
* @returns The backend instance, if set.
|
|
107
|
+
*/
|
|
108
|
+
getBackend(): Backend | undefined;
|
|
109
|
+
/**
|
|
110
|
+
* Closes the engine and releases resources.
|
|
111
|
+
*/
|
|
112
|
+
close(): Promise<void>;
|
|
113
|
+
/**
|
|
114
|
+
* Builds a job using the provided job class.
|
|
115
|
+
* @param JobClass The job class constructor.
|
|
116
|
+
* @returns A new JobBuilder instance for the job class.
|
|
117
|
+
*/
|
|
118
|
+
build<T extends JobClassType>(JobClass: T): JobBuilder<T>;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export { Engine };
|
|
122
|
+
export type { EngineConfig, NonNullableEngineConfig };
|
package/dist/engine.js
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { QUEUE_FALLBACK, MISC_FALLBACK, createBackendFromDriver } from '@sidequest/backend';
|
|
2
|
+
import { logger, configureLogger } from '@sidequest/core';
|
|
3
|
+
import { fork } from 'child_process';
|
|
4
|
+
import { cpus } from 'os';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { JOB_BUILDER_FALLBACK } from './job/constants.js';
|
|
7
|
+
import { JobBuilder } from './job/job-builder.js';
|
|
8
|
+
import { grantQueueConfig } from './queue/grant-queue-config.js';
|
|
9
|
+
import { gracefulShutdown, clearGracefulShutdown } from './utils/shutdown.js';
|
|
10
|
+
|
|
11
|
+
const workerPath = path.resolve(import.meta.dirname, "workers", "main.js");
|
|
12
|
+
/**
|
|
13
|
+
* The main engine for managing job queues and workers in Sidequest.
|
|
14
|
+
*/
|
|
15
|
+
class Engine {
|
|
16
|
+
/**
|
|
17
|
+
* Backend instance used by the engine.
|
|
18
|
+
* This is initialized when the engine is configured or started.
|
|
19
|
+
*/
|
|
20
|
+
backend;
|
|
21
|
+
/**
|
|
22
|
+
* Current configuration of the engine.
|
|
23
|
+
* This is set when the engine is configured or started.
|
|
24
|
+
* It contains all the necessary settings for the engine to operate, such as backend, queues, logger options, and job defaults.
|
|
25
|
+
*/
|
|
26
|
+
config;
|
|
27
|
+
/**
|
|
28
|
+
* Main worker process that runs the Sidequest engine.
|
|
29
|
+
* This is created when the engine is started and handles job processing.
|
|
30
|
+
*/
|
|
31
|
+
mainWorker;
|
|
32
|
+
/**
|
|
33
|
+
* Flag indicating whether the engine is currently shutting down.
|
|
34
|
+
* This is used to prevent multiple shutdown attempts and ensure graceful shutdown behavior.
|
|
35
|
+
*/
|
|
36
|
+
shuttingDown = false;
|
|
37
|
+
/**
|
|
38
|
+
* Configures the Sidequest engine with the provided configuration.
|
|
39
|
+
* @param config Optional configuration object.
|
|
40
|
+
* @returns The resolved configuration.
|
|
41
|
+
*/
|
|
42
|
+
async configure(config) {
|
|
43
|
+
if (this.config) {
|
|
44
|
+
logger("Engine").debug("Sidequest already configured");
|
|
45
|
+
return this.config;
|
|
46
|
+
}
|
|
47
|
+
this.config = {
|
|
48
|
+
queues: config?.queues ?? [],
|
|
49
|
+
backend: {
|
|
50
|
+
driver: config?.backend?.driver ?? "@sidequest/sqlite-backend",
|
|
51
|
+
config: config?.backend?.config ?? "./sidequest.sqlite",
|
|
52
|
+
},
|
|
53
|
+
cleanupFinishedJobsIntervalMin: config?.cleanupFinishedJobsIntervalMin ?? 60,
|
|
54
|
+
cleanupFinishedJobsOlderThan: config?.cleanupFinishedJobsOlderThan ?? 30 * 24 * 60 * 60 * 1000,
|
|
55
|
+
releaseStaleJobsIntervalMin: config?.releaseStaleJobsIntervalMin ?? 60,
|
|
56
|
+
maxConcurrentJobs: config?.maxConcurrentJobs ?? 10,
|
|
57
|
+
skipMigration: config?.skipMigration ?? false,
|
|
58
|
+
logger: {
|
|
59
|
+
level: config?.logger?.level ?? "info",
|
|
60
|
+
json: config?.logger?.json ?? false,
|
|
61
|
+
},
|
|
62
|
+
gracefulShutdown: config?.gracefulShutdown ?? true,
|
|
63
|
+
minThreads: config?.minThreads ?? cpus().length,
|
|
64
|
+
maxThreads: config?.maxThreads ?? cpus().length * 2,
|
|
65
|
+
releaseStaleJobsMaxStaleMs: config?.releaseStaleJobsMaxStaleMs ?? MISC_FALLBACK.maxStaleMs, // 10 minutes
|
|
66
|
+
releaseStaleJobsMaxClaimedMs: config?.releaseStaleJobsMaxClaimedMs ?? MISC_FALLBACK.maxClaimedMs, // 1 minute
|
|
67
|
+
jobDefaults: {
|
|
68
|
+
queue: config?.jobDefaults?.queue ?? JOB_BUILDER_FALLBACK.queue,
|
|
69
|
+
maxAttempts: config?.jobDefaults?.maxAttempts ?? JOB_BUILDER_FALLBACK.maxAttempts,
|
|
70
|
+
availableAt: config?.jobDefaults?.availableAt ?? JOB_BUILDER_FALLBACK.availableAt,
|
|
71
|
+
timeout: config?.jobDefaults?.timeout ?? JOB_BUILDER_FALLBACK.timeout,
|
|
72
|
+
uniqueness: config?.jobDefaults?.uniqueness ?? JOB_BUILDER_FALLBACK.uniqueness,
|
|
73
|
+
},
|
|
74
|
+
queueDefaults: {
|
|
75
|
+
concurrency: config?.queueDefaults?.concurrency ?? QUEUE_FALLBACK.concurrency,
|
|
76
|
+
priority: config?.queueDefaults?.priority ?? QUEUE_FALLBACK.priority,
|
|
77
|
+
state: config?.queueDefaults?.state ?? QUEUE_FALLBACK.state,
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
if (this.config.logger) {
|
|
81
|
+
configureLogger(this.config.logger);
|
|
82
|
+
}
|
|
83
|
+
logger("Engine").debug(`Configuring Sidequest engine: ${JSON.stringify(this.config)}`);
|
|
84
|
+
this.backend = await createBackendFromDriver(this.config.backend);
|
|
85
|
+
if (!this.config.skipMigration) {
|
|
86
|
+
await this.backend.migrate();
|
|
87
|
+
}
|
|
88
|
+
if (this.config.queues) {
|
|
89
|
+
for (const queue of this.config.queues) {
|
|
90
|
+
await grantQueueConfig(this.backend, queue, this.config.queueDefaults);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return this.config;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Starts the Sidequest engine and worker process.
|
|
97
|
+
* @param config Optional configuration object.
|
|
98
|
+
*/
|
|
99
|
+
async start(config) {
|
|
100
|
+
await this.configure(config);
|
|
101
|
+
logger("Engine").info(`Starting Sidequest using backend ${this.config.backend.driver}`);
|
|
102
|
+
return new Promise((resolve, reject) => {
|
|
103
|
+
const timeout = setTimeout(() => {
|
|
104
|
+
reject(new Error("Timeout on starting sidequest fork!"));
|
|
105
|
+
}, 5000);
|
|
106
|
+
if (!this.mainWorker) {
|
|
107
|
+
const runWorker = () => {
|
|
108
|
+
logger("Engine").debug("Starting main worker...");
|
|
109
|
+
this.mainWorker = fork(workerPath);
|
|
110
|
+
logger("Engine").debug(`Worker PID: ${this.mainWorker.pid}`);
|
|
111
|
+
this.mainWorker.on("message", (msg) => {
|
|
112
|
+
if (msg === "ready") {
|
|
113
|
+
logger("Engine").debug("Main worker is ready");
|
|
114
|
+
this.mainWorker?.send({ type: "start", sidequestConfig: this.config });
|
|
115
|
+
clearTimeout(timeout);
|
|
116
|
+
resolve();
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
this.mainWorker.on("exit", () => {
|
|
120
|
+
if (!this.shuttingDown) {
|
|
121
|
+
logger("Engine").error("Sidequest main exited, creating new...");
|
|
122
|
+
runWorker();
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
};
|
|
126
|
+
runWorker();
|
|
127
|
+
gracefulShutdown(this.close.bind(this), "Engine", this.config.gracefulShutdown);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Gets the current engine configuration.
|
|
133
|
+
* @returns The current configuration, if set.
|
|
134
|
+
*/
|
|
135
|
+
getConfig() {
|
|
136
|
+
return this.config;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Gets the backend instance in use by the engine.
|
|
140
|
+
* @returns The backend instance, if set.
|
|
141
|
+
*/
|
|
142
|
+
getBackend() {
|
|
143
|
+
return this.backend;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Closes the engine and releases resources.
|
|
147
|
+
*/
|
|
148
|
+
async close() {
|
|
149
|
+
if (!this.shuttingDown) {
|
|
150
|
+
this.shuttingDown = true;
|
|
151
|
+
logger("Engine").debug("Closing Sidequest engine...");
|
|
152
|
+
if (this.mainWorker) {
|
|
153
|
+
this.mainWorker.send({ type: "shutdown" });
|
|
154
|
+
await new Promise((resolve) => {
|
|
155
|
+
this.mainWorker.on("exit", resolve);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
await this.backend?.close();
|
|
159
|
+
this.config = undefined;
|
|
160
|
+
this.backend = undefined;
|
|
161
|
+
this.mainWorker = undefined;
|
|
162
|
+
// Reset the shutting down flag after closing
|
|
163
|
+
// This allows the engine to be reconfigured or restarted later
|
|
164
|
+
clearGracefulShutdown();
|
|
165
|
+
logger("Engine").debug("Sidequest engine closed.");
|
|
166
|
+
this.shuttingDown = false;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Builds a job using the provided job class.
|
|
171
|
+
* @param JobClass The job class constructor.
|
|
172
|
+
* @returns A new JobBuilder instance for the job class.
|
|
173
|
+
*/
|
|
174
|
+
build(JobClass) {
|
|
175
|
+
if (!this.config || !this.backend) {
|
|
176
|
+
throw new Error("Engine not configured. Call engine.configure() or engine.start() first.");
|
|
177
|
+
}
|
|
178
|
+
if (this.shuttingDown) {
|
|
179
|
+
throw new Error("Engine is shutting down, cannot build job.");
|
|
180
|
+
}
|
|
181
|
+
logger("Engine").debug(`Building job for class: ${JobClass.name}`);
|
|
182
|
+
return new JobBuilder(this.backend, JobClass, this.config.jobDefaults);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export { Engine };
|
|
187
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sources":["../src/engine.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var core = require('@sidequest/core');
|
|
4
|
+
|
|
5
|
+
const sleepDelay = 100;
|
|
6
|
+
/**
|
|
7
|
+
* Dispatcher for managing job execution and queue polling.
|
|
8
|
+
*/
|
|
9
|
+
class Dispatcher {
|
|
10
|
+
backend;
|
|
11
|
+
queueManager;
|
|
12
|
+
executorManager;
|
|
13
|
+
/** Indicates if the dispatcher is currently running */
|
|
14
|
+
isRunning = false;
|
|
15
|
+
/**
|
|
16
|
+
* Creates a new Dispatcher.
|
|
17
|
+
* @param backend The backend instance.
|
|
18
|
+
* @param queueManager The queue manager instance.
|
|
19
|
+
* @param executorManager The executor manager instance.
|
|
20
|
+
*/
|
|
21
|
+
constructor(backend, queueManager, executorManager) {
|
|
22
|
+
this.backend = backend;
|
|
23
|
+
this.queueManager = queueManager;
|
|
24
|
+
this.executorManager = executorManager;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Main loop for polling queues and dispatching jobs.
|
|
28
|
+
* @private
|
|
29
|
+
*/
|
|
30
|
+
async listen() {
|
|
31
|
+
while (this.isRunning) {
|
|
32
|
+
const queues = await this.queueManager.getActiveQueuesWithRunnableJobs();
|
|
33
|
+
let shouldSleep = true;
|
|
34
|
+
for (const queue of queues) {
|
|
35
|
+
const availableSlots = this.executorManager.availableSlotsByQueue(queue);
|
|
36
|
+
if (availableSlots <= 0) {
|
|
37
|
+
core.logger("Dispatcher").debug(`Queue ${queue.name} limit reached!`);
|
|
38
|
+
await this.sleep(sleepDelay);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const globalSlots = this.executorManager.availableSlotsGlobal();
|
|
42
|
+
if (globalSlots <= 0) {
|
|
43
|
+
core.logger("Dispatcher").debug(`Global concurrency limit reached!`);
|
|
44
|
+
await this.sleep(sleepDelay);
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const jobs = await this.backend.claimPendingJob(queue.name, availableSlots);
|
|
48
|
+
if (jobs.length > 0) {
|
|
49
|
+
// if a job was found on any queue do not sleep
|
|
50
|
+
shouldSleep = false;
|
|
51
|
+
}
|
|
52
|
+
for (const job of jobs) {
|
|
53
|
+
// does not await for job execution.
|
|
54
|
+
void this.executorManager.execute(queue, job);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (shouldSleep) {
|
|
58
|
+
await this.sleep(sleepDelay);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Sleeps for the given delay in milliseconds.
|
|
64
|
+
* @param delay The delay in milliseconds.
|
|
65
|
+
* @returns A promise that resolves after the delay.
|
|
66
|
+
* @private
|
|
67
|
+
*/
|
|
68
|
+
sleep(delay) {
|
|
69
|
+
return new Promise((r) => setTimeout(r, delay));
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Starts the dispatcher loop.
|
|
73
|
+
*/
|
|
74
|
+
start() {
|
|
75
|
+
core.logger("Dispatcher").debug(`Starting dispatcher...`);
|
|
76
|
+
this.isRunning = true;
|
|
77
|
+
void this.listen();
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Stops the dispatcher and waits for all active jobs to finish.
|
|
81
|
+
* @returns A promise that resolves when all jobs are finished.
|
|
82
|
+
*/
|
|
83
|
+
async stop() {
|
|
84
|
+
this.isRunning = false;
|
|
85
|
+
await this.executorManager.destroy();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
exports.Dispatcher = Dispatcher;
|
|
90
|
+
//# sourceMappingURL=dispatcher.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatcher.cjs","sources":["../../src/execution/dispatcher.ts"],"sourcesContent":[null],"names":["logger"],"mappings":";;;;AAKA,MAAM,UAAU,GAAG,GAAG;AAEtB;;AAEG;MACU,UAAU,CAAA;AAWX,IAAA,OAAA;AACA,IAAA,YAAA;AACA,IAAA,eAAA;;IAXF,SAAS,GAAG,KAAK;AAEzB;;;;;AAKG;AACH,IAAA,WAAA,CACU,OAAgB,EAChB,YAA0B,EAC1B,eAAgC,EAAA;QAFhC,IAAA,CAAA,OAAO,GAAP,OAAO;QACP,IAAA,CAAA,YAAY,GAAZ,YAAY;QACZ,IAAA,CAAA,eAAe,GAAf,eAAe;IACtB;AAEH;;;AAGG;AACK,IAAA,MAAM,MAAM,GAAA;AAClB,QAAA,OAAO,IAAI,CAAC,SAAS,EAAE;YACrB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,+BAA+B,EAAE;YAExE,IAAI,WAAW,GAAG,IAAI;AAEtB,YAAA,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;gBAC1B,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,qBAAqB,CAAC,KAAK,CAAC;AACxE,gBAAA,IAAI,cAAc,IAAI,CAAC,EAAE;AACvB,oBAAAA,WAAM,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,CAAA,MAAA,EAAS,KAAK,CAAC,IAAI,CAAA,eAAA,CAAiB,CAAC;AAChE,oBAAA,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;oBAC5B;gBACF;gBAEA,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,oBAAoB,EAAE;AAC/D,gBAAA,IAAI,WAAW,IAAI,CAAC,EAAE;oBACpBA,WAAM,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,CAAA,iCAAA,CAAmC,CAAC;AAC/D,oBAAA,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;oBAC5B;gBACF;AAEA,gBAAA,MAAM,IAAI,GAAc,MAAM,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,cAAc,CAAC;AAEtF,gBAAA,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;;oBAEnB,WAAW,GAAG,KAAK;gBACrB;AAEA,gBAAA,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;;oBAEtB,KAAK,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;gBAC/C;YACF;YAEA,IAAI,WAAW,EAAE;AACf,gBAAA,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;YAC9B;QACF;IACF;AAEA;;;;;AAKG;AACK,IAAA,KAAK,CAAC,KAAa,EAAA;AACzB,QAAA,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACjD;AAEA;;AAEG;IACH,KAAK,GAAA;QACHA,WAAM,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,CAAA,sBAAA,CAAwB,CAAC;AACpD,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI;AACrB,QAAA,KAAK,IAAI,CAAC,MAAM,EAAE;IACpB;AAEA;;;AAGG;AACH,IAAA,MAAM,IAAI,GAAA;AACR,QAAA,IAAI,CAAC,SAAS,GAAG,KAAK;AACtB,QAAA,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE;IACtC;AACD;;;;"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Backend } from '@sidequest/backend';
|
|
2
|
+
import { ExecutorManager } from './executor-manager.js';
|
|
3
|
+
import { QueueManager } from './queue-manager.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Dispatcher for managing job execution and queue polling.
|
|
7
|
+
*/
|
|
8
|
+
declare class Dispatcher {
|
|
9
|
+
private backend;
|
|
10
|
+
private queueManager;
|
|
11
|
+
private executorManager;
|
|
12
|
+
/** Indicates if the dispatcher is currently running */
|
|
13
|
+
private isRunning;
|
|
14
|
+
/**
|
|
15
|
+
* Creates a new Dispatcher.
|
|
16
|
+
* @param backend The backend instance.
|
|
17
|
+
* @param queueManager The queue manager instance.
|
|
18
|
+
* @param executorManager The executor manager instance.
|
|
19
|
+
*/
|
|
20
|
+
constructor(backend: Backend, queueManager: QueueManager, executorManager: ExecutorManager);
|
|
21
|
+
/**
|
|
22
|
+
* Main loop for polling queues and dispatching jobs.
|
|
23
|
+
* @private
|
|
24
|
+
*/
|
|
25
|
+
private listen;
|
|
26
|
+
/**
|
|
27
|
+
* Sleeps for the given delay in milliseconds.
|
|
28
|
+
* @param delay The delay in milliseconds.
|
|
29
|
+
* @returns A promise that resolves after the delay.
|
|
30
|
+
* @private
|
|
31
|
+
*/
|
|
32
|
+
private sleep;
|
|
33
|
+
/**
|
|
34
|
+
* Starts the dispatcher loop.
|
|
35
|
+
*/
|
|
36
|
+
start(): void;
|
|
37
|
+
/**
|
|
38
|
+
* Stops the dispatcher and waits for all active jobs to finish.
|
|
39
|
+
* @returns A promise that resolves when all jobs are finished.
|
|
40
|
+
*/
|
|
41
|
+
stop(): Promise<void>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export { Dispatcher };
|