@redmix/jobs 0.0.1

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 (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3 -0
  3. package/dist/adapters/BaseAdapter/BaseAdapter.d.ts +64 -0
  4. package/dist/adapters/BaseAdapter/BaseAdapter.d.ts.map +1 -0
  5. package/dist/adapters/BaseAdapter/BaseAdapter.js +36 -0
  6. package/dist/adapters/PrismaAdapter/PrismaAdapter.d.ts +68 -0
  7. package/dist/adapters/PrismaAdapter/PrismaAdapter.d.ts.map +1 -0
  8. package/dist/adapters/PrismaAdapter/PrismaAdapter.js +189 -0
  9. package/dist/adapters/PrismaAdapter/errors.d.ts +8 -0
  10. package/dist/adapters/PrismaAdapter/errors.d.ts.map +1 -0
  11. package/dist/adapters/PrismaAdapter/errors.js +33 -0
  12. package/dist/bins/rw-jobs-worker.d.ts +13 -0
  13. package/dist/bins/rw-jobs-worker.d.ts.map +1 -0
  14. package/dist/bins/rw-jobs-worker.js +126 -0
  15. package/dist/bins/rw-jobs.d.ts +20 -0
  16. package/dist/bins/rw-jobs.d.ts.map +1 -0
  17. package/dist/bins/rw-jobs.js +248 -0
  18. package/dist/consts.d.ts +26 -0
  19. package/dist/consts.d.ts.map +1 -0
  20. package/dist/consts.js +81 -0
  21. package/dist/core/Executor.d.ts +29 -0
  22. package/dist/core/Executor.d.ts.map +1 -0
  23. package/dist/core/Executor.js +95 -0
  24. package/dist/core/JobManager.d.ts +20 -0
  25. package/dist/core/JobManager.d.ts.map +1 -0
  26. package/dist/core/JobManager.js +78 -0
  27. package/dist/core/Scheduler.d.ts +27 -0
  28. package/dist/core/Scheduler.d.ts.map +1 -0
  29. package/dist/core/Scheduler.js +91 -0
  30. package/dist/core/Worker.d.ts +49 -0
  31. package/dist/core/Worker.d.ts.map +1 -0
  32. package/dist/core/Worker.js +143 -0
  33. package/dist/errors.d.ts +104 -0
  34. package/dist/errors.d.ts.map +1 -0
  35. package/dist/errors.js +156 -0
  36. package/dist/index.d.ts +8 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +43 -0
  39. package/dist/loaders.d.ts +13 -0
  40. package/dist/loaders.d.ts.map +1 -0
  41. package/dist/loaders.js +71 -0
  42. package/dist/setupEnv.d.ts +2 -0
  43. package/dist/setupEnv.d.ts.map +1 -0
  44. package/dist/setupEnv.js +34 -0
  45. package/dist/types.d.ts +175 -0
  46. package/dist/types.d.ts.map +1 -0
  47. package/dist/types.js +16 -0
  48. package/dist/util.d.ts +2 -0
  49. package/dist/util.d.ts.map +1 -0
  50. package/dist/util.js +31 -0
  51. package/package.json +58 -0
@@ -0,0 +1,248 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+ var rw_jobs_exports = {};
31
+ __export(rw_jobs_exports, {
32
+ buildNumWorkers: () => buildNumWorkers,
33
+ clearQueue: () => clearQueue,
34
+ startWorkers: () => startWorkers,
35
+ stopWorkers: () => stopWorkers
36
+ });
37
+ module.exports = __toCommonJS(rw_jobs_exports);
38
+ var import_node_child_process = require("node:child_process");
39
+ var import_node_console = __toESM(require("node:console"));
40
+ var import_node_path = __toESM(require("node:path"));
41
+ var import_node_process = __toESM(require("node:process"));
42
+ var import_node_timers = require("node:timers");
43
+ var import_helpers = require("yargs/helpers");
44
+ var import_yargs = __toESM(require("yargs/yargs"));
45
+ var import_consts = require("../consts.js");
46
+ var import_loaders = require("../loaders.js");
47
+ var import_setupEnv = require("../setupEnv.js");
48
+ (0, import_setupEnv.setupEnv)();
49
+ import_node_process.default.title = "rw-jobs";
50
+ const WORKER_PATH = import_node_path.default.join(__dirname, "rw-jobs-worker.js");
51
+ const parseArgs = (argv) => {
52
+ const commandString = (0, import_helpers.hideBin)(argv);
53
+ if (commandString.length === 1 && commandString[0] === "jobs") {
54
+ commandString.shift();
55
+ }
56
+ const parsed = (0, import_yargs.default)(commandString).usage(
57
+ "Starts the RedwoodJob runner to process background jobs\n\nUsage: rw jobs <command> [options]"
58
+ ).command("work", "Start a worker and process jobs").command("workoff", "Start a worker and exit after all jobs processed").command("start", "Start workers in daemon mode").command("stop", "Stop any daemonized job workers").command("restart", "Stop and start any daemonized job workers").command("clear", "Clear the job queue").demandCommand(1, "You must specify a mode to start in").example(
59
+ "rw jobs work",
60
+ "Start the job workers using the job config and work on jobs until manually stopped"
61
+ ).example(
62
+ "rw jobs start",
63
+ "Start the job workers using the job config and detach, running in daemon mode"
64
+ ).help().parse(commandString, (_err, _argv, output) => {
65
+ if (output) {
66
+ const newOutput = output.replaceAll("rw-jobs.js", "rw jobs");
67
+ import_node_console.default.log(newOutput);
68
+ }
69
+ });
70
+ return { command: parsed._[0] };
71
+ };
72
+ const buildNumWorkers = (config) => {
73
+ const workers = [];
74
+ config.map((worker, index) => {
75
+ for (let id = 0; id < worker.count; id++) {
76
+ workers.push([index, id]);
77
+ }
78
+ });
79
+ return workers;
80
+ };
81
+ const startWorkers = ({
82
+ numWorkers,
83
+ detach = false,
84
+ workoff = false,
85
+ logger
86
+ }) => {
87
+ logger.warn(`Starting ${numWorkers.length} worker(s)...`);
88
+ return numWorkers.map(([index, id]) => {
89
+ const workerArgs = ["--index", index.toString(), "--id", id.toString()];
90
+ if (workoff) {
91
+ workerArgs.push("--workoff");
92
+ }
93
+ const worker = (0, import_node_child_process.fork)(WORKER_PATH, workerArgs, {
94
+ detached: detach,
95
+ stdio: detach ? "ignore" : "inherit",
96
+ env: import_node_process.default.env
97
+ });
98
+ if (detach) {
99
+ worker.unref();
100
+ } else {
101
+ worker.on("exit", (_code) => {
102
+ });
103
+ }
104
+ return worker;
105
+ });
106
+ };
107
+ const stopWorkers = async ({
108
+ numWorkers,
109
+ signal = "SIGINT",
110
+ logger
111
+ }) => {
112
+ logger.warn(
113
+ `Stopping ${numWorkers.length} worker(s) gracefully (${signal})...`
114
+ );
115
+ const processIds = await findWorkerProcesses();
116
+ if (processIds.length === 0) {
117
+ logger.warn(`No running workers found.`);
118
+ return;
119
+ }
120
+ for (const processId of processIds) {
121
+ logger.info(`Stopping process id ${processId}...`);
122
+ import_node_process.default.kill(processId, signal);
123
+ while ((await findWorkerProcesses(processId)).length) {
124
+ await new Promise((resolve) => (0, import_node_timers.setTimeout)(resolve, 250));
125
+ }
126
+ }
127
+ };
128
+ const clearQueue = ({ logger }) => {
129
+ logger.warn(`Starting worker to clear job queue...`);
130
+ (0, import_node_child_process.fork)(WORKER_PATH, ["--clear", "--index", "0", "--id", "0"]);
131
+ };
132
+ const signalSetup = ({
133
+ workers,
134
+ logger
135
+ }) => {
136
+ let sigtermCount = 0;
137
+ import_node_process.default.on("SIGINT", () => {
138
+ sigtermCount++;
139
+ let message = "SIGINT received: shutting down workers gracefully (press Ctrl-C again to exit immediately)...";
140
+ if (sigtermCount > 1) {
141
+ message = "SIGINT received again, exiting immediately...";
142
+ }
143
+ logger.info(message);
144
+ workers.forEach((worker) => {
145
+ if (sigtermCount > 1) {
146
+ worker.kill("SIGTERM");
147
+ } else {
148
+ worker.kill("SIGINT");
149
+ }
150
+ });
151
+ });
152
+ };
153
+ const findWorkerProcesses = async (id) => {
154
+ return new Promise(function(resolve, reject) {
155
+ const platform = import_node_process.default.platform;
156
+ const cmd = platform === "win32" ? "tasklist" : platform === "darwin" ? "ps -ax | grep " + import_consts.PROCESS_TITLE_PREFIX : platform === "linux" ? "ps -A" : "";
157
+ if (cmd === "") {
158
+ resolve([]);
159
+ }
160
+ (0, import_node_child_process.exec)(cmd, function(err, stdout) {
161
+ if (err) {
162
+ reject(err);
163
+ }
164
+ const list = stdout.trim().split("\n");
165
+ const matches = list.filter((line) => {
166
+ if (platform == "darwin" || platform == "linux") {
167
+ return !line.match("grep");
168
+ }
169
+ return true;
170
+ });
171
+ if (matches.length === 0) {
172
+ resolve([]);
173
+ }
174
+ const pids = matches.map((line) => parseInt(line.split(" ")[0]));
175
+ if (id) {
176
+ resolve(pids.filter((pid) => pid === id));
177
+ } else {
178
+ resolve(pids);
179
+ }
180
+ });
181
+ });
182
+ };
183
+ const main = async () => {
184
+ const { command } = parseArgs(import_node_process.default.argv);
185
+ let jobsConfig;
186
+ try {
187
+ jobsConfig = await (0, import_loaders.loadJobsManager)();
188
+ } catch (e) {
189
+ import_node_console.default.error(e);
190
+ import_node_process.default.exit(1);
191
+ }
192
+ const workerConfig = jobsConfig.workers;
193
+ const numWorkers = buildNumWorkers(workerConfig);
194
+ const logger = jobsConfig.logger ?? import_consts.DEFAULT_LOGGER;
195
+ logger.warn(`Starting RedwoodJob Runner at ${(/* @__PURE__ */ new Date()).toISOString()}...`);
196
+ switch (command) {
197
+ case "start":
198
+ startWorkers({
199
+ numWorkers,
200
+ detach: true,
201
+ logger
202
+ });
203
+ return import_node_process.default.exit(0);
204
+ case "stop":
205
+ return await stopWorkers({
206
+ numWorkers,
207
+ signal: "SIGINT",
208
+ logger
209
+ });
210
+ case "restart":
211
+ await stopWorkers({ numWorkers, signal: "SIGINT", logger });
212
+ startWorkers({
213
+ numWorkers,
214
+ detach: true,
215
+ logger
216
+ });
217
+ return import_node_process.default.exit(0);
218
+ case "work":
219
+ return signalSetup({
220
+ workers: startWorkers({
221
+ numWorkers,
222
+ logger
223
+ }),
224
+ logger
225
+ });
226
+ case "workoff":
227
+ return signalSetup({
228
+ workers: startWorkers({
229
+ numWorkers,
230
+ workoff: true,
231
+ logger
232
+ }),
233
+ logger
234
+ });
235
+ case "clear":
236
+ return clearQueue({ logger });
237
+ }
238
+ };
239
+ if (import_node_process.default.env.NODE_ENV !== "test") {
240
+ main();
241
+ }
242
+ // Annotate the CommonJS export names for ESM import in node:
243
+ 0 && (module.exports = {
244
+ buildNumWorkers,
245
+ clearQueue,
246
+ startWorkers,
247
+ stopWorkers
248
+ });
@@ -0,0 +1,26 @@
1
+ export declare const DEFAULT_MAX_ATTEMPTS = 24;
2
+ /** 4 hours in seconds */
3
+ export declare const DEFAULT_MAX_RUNTIME = 14400;
4
+ /** 5 seconds */
5
+ export declare const DEFAULT_SLEEP_DELAY = 5;
6
+ export declare const DEFAULT_DELETE_SUCCESSFUL_JOBS = true;
7
+ export declare const DEFAULT_DELETE_FAILED_JOBS = false;
8
+ export declare const DEFAULT_LOGGER: Console;
9
+ export declare const DEFAULT_QUEUE = "default";
10
+ export declare const DEFAULT_WORK_QUEUE = "*";
11
+ export declare const DEFAULT_PRIORITY = 50;
12
+ export declare const DEFAULT_WAIT = 0;
13
+ export declare const DEFAULT_WAIT_UNTIL: null;
14
+ export declare const PROCESS_TITLE_PREFIX = "rw-jobs-worker";
15
+ export declare const DEFAULT_MODEL_NAME = "BackgroundJob";
16
+ /**
17
+ * The name of the exported variable from the jobs config file that contains
18
+ * the adapter
19
+ */
20
+ export declare const DEFAULT_ADAPTER_NAME = "adapter";
21
+ /**
22
+ * The name of the exported variable from the jobs config file that contains
23
+ * the logger
24
+ */
25
+ export declare const DEFAULT_LOGGER_NAME = "logger";
26
+ //# sourceMappingURL=consts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,oBAAoB,KAAK,CAAA;AACtC,yBAAyB;AACzB,eAAO,MAAM,mBAAmB,QAAS,CAAA;AACzC,gBAAgB;AAChB,eAAO,MAAM,mBAAmB,IAAI,CAAA;AAEpC,eAAO,MAAM,8BAA8B,OAAO,CAAA;AAClD,eAAO,MAAM,0BAA0B,QAAQ,CAAA;AAC/C,eAAO,MAAM,cAAc,SAAU,CAAA;AACrC,eAAO,MAAM,aAAa,YAAY,CAAA;AACtC,eAAO,MAAM,kBAAkB,MAAM,CAAA;AACrC,eAAO,MAAM,gBAAgB,KAAK,CAAA;AAClC,eAAO,MAAM,YAAY,IAAI,CAAA;AAC7B,eAAO,MAAM,kBAAkB,MAAO,CAAA;AACtC,eAAO,MAAM,oBAAoB,mBAAmB,CAAA;AACpD,eAAO,MAAM,kBAAkB,kBAAkB,CAAA;AAEjD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,YAAY,CAAA;AAC7C;;;GAGG;AACH,eAAO,MAAM,mBAAmB,WAAW,CAAA"}
package/dist/consts.js ADDED
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var consts_exports = {};
30
+ __export(consts_exports, {
31
+ DEFAULT_ADAPTER_NAME: () => DEFAULT_ADAPTER_NAME,
32
+ DEFAULT_DELETE_FAILED_JOBS: () => DEFAULT_DELETE_FAILED_JOBS,
33
+ DEFAULT_DELETE_SUCCESSFUL_JOBS: () => DEFAULT_DELETE_SUCCESSFUL_JOBS,
34
+ DEFAULT_LOGGER: () => DEFAULT_LOGGER,
35
+ DEFAULT_LOGGER_NAME: () => DEFAULT_LOGGER_NAME,
36
+ DEFAULT_MAX_ATTEMPTS: () => DEFAULT_MAX_ATTEMPTS,
37
+ DEFAULT_MAX_RUNTIME: () => DEFAULT_MAX_RUNTIME,
38
+ DEFAULT_MODEL_NAME: () => DEFAULT_MODEL_NAME,
39
+ DEFAULT_PRIORITY: () => DEFAULT_PRIORITY,
40
+ DEFAULT_QUEUE: () => DEFAULT_QUEUE,
41
+ DEFAULT_SLEEP_DELAY: () => DEFAULT_SLEEP_DELAY,
42
+ DEFAULT_WAIT: () => DEFAULT_WAIT,
43
+ DEFAULT_WAIT_UNTIL: () => DEFAULT_WAIT_UNTIL,
44
+ DEFAULT_WORK_QUEUE: () => DEFAULT_WORK_QUEUE,
45
+ PROCESS_TITLE_PREFIX: () => PROCESS_TITLE_PREFIX
46
+ });
47
+ module.exports = __toCommonJS(consts_exports);
48
+ var import_node_console = __toESM(require("node:console"));
49
+ const DEFAULT_MAX_ATTEMPTS = 24;
50
+ const DEFAULT_MAX_RUNTIME = 14400;
51
+ const DEFAULT_SLEEP_DELAY = 5;
52
+ const DEFAULT_DELETE_SUCCESSFUL_JOBS = true;
53
+ const DEFAULT_DELETE_FAILED_JOBS = false;
54
+ const DEFAULT_LOGGER = import_node_console.default;
55
+ const DEFAULT_QUEUE = "default";
56
+ const DEFAULT_WORK_QUEUE = "*";
57
+ const DEFAULT_PRIORITY = 50;
58
+ const DEFAULT_WAIT = 0;
59
+ const DEFAULT_WAIT_UNTIL = null;
60
+ const PROCESS_TITLE_PREFIX = "rw-jobs-worker";
61
+ const DEFAULT_MODEL_NAME = "BackgroundJob";
62
+ const DEFAULT_ADAPTER_NAME = "adapter";
63
+ const DEFAULT_LOGGER_NAME = "logger";
64
+ // Annotate the CommonJS export names for ESM import in node:
65
+ 0 && (module.exports = {
66
+ DEFAULT_ADAPTER_NAME,
67
+ DEFAULT_DELETE_FAILED_JOBS,
68
+ DEFAULT_DELETE_SUCCESSFUL_JOBS,
69
+ DEFAULT_LOGGER,
70
+ DEFAULT_LOGGER_NAME,
71
+ DEFAULT_MAX_ATTEMPTS,
72
+ DEFAULT_MAX_RUNTIME,
73
+ DEFAULT_MODEL_NAME,
74
+ DEFAULT_PRIORITY,
75
+ DEFAULT_QUEUE,
76
+ DEFAULT_SLEEP_DELAY,
77
+ DEFAULT_WAIT,
78
+ DEFAULT_WAIT_UNTIL,
79
+ DEFAULT_WORK_QUEUE,
80
+ PROCESS_TITLE_PREFIX
81
+ });
@@ -0,0 +1,29 @@
1
+ import type { BaseAdapter } from '../adapters/BaseAdapter/BaseAdapter.js';
2
+ import type { BaseJob, BasicLogger } from '../types.js';
3
+ export interface ExecutorOptions {
4
+ adapter: BaseAdapter;
5
+ job: BaseJob;
6
+ logger?: BasicLogger;
7
+ maxAttempts?: number;
8
+ deleteFailedJobs?: boolean;
9
+ deleteSuccessfulJobs?: boolean;
10
+ }
11
+ export declare const DEFAULTS: {
12
+ logger: Console;
13
+ maxAttempts: number;
14
+ deleteFailedJobs: boolean;
15
+ deleteSuccessfulJobs: boolean;
16
+ };
17
+ export declare class Executor {
18
+ options: Required<ExecutorOptions>;
19
+ adapter: ExecutorOptions['adapter'];
20
+ logger: NonNullable<ExecutorOptions['logger']>;
21
+ job: BaseJob;
22
+ maxAttempts: NonNullable<ExecutorOptions['maxAttempts']>;
23
+ deleteFailedJobs: NonNullable<ExecutorOptions['deleteFailedJobs']>;
24
+ deleteSuccessfulJobs: NonNullable<ExecutorOptions['deleteSuccessfulJobs']>;
25
+ constructor(options: ExecutorOptions);
26
+ get jobIdentifier(): string;
27
+ perform(): Promise<void>;
28
+ }
29
+ //# sourceMappingURL=Executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Executor.d.ts","sourceRoot":"","sources":["../../src/core/Executor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAA;AASzE,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEvD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,WAAW,CAAA;IACpB,GAAG,EAAE,OAAO,CAAA;IACZ,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B;AAED,eAAO,MAAM,QAAQ;;;;;CAKpB,CAAA;AAED,qBAAa,QAAQ;IACnB,OAAO,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAA;IAClC,OAAO,EAAE,eAAe,CAAC,SAAS,CAAC,CAAA;IACnC,MAAM,EAAE,WAAW,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC9C,GAAG,EAAE,OAAO,CAAA;IACZ,WAAW,EAAE,WAAW,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,CAAA;IACxD,gBAAgB,EAAE,WAAW,CAAC,eAAe,CAAC,kBAAkB,CAAC,CAAC,CAAA;IAClE,oBAAoB,EAAE,WAAW,CAAC,eAAe,CAAC,sBAAsB,CAAC,CAAC,CAAA;gBAE9D,OAAO,EAAE,eAAe;IAmBpC,IAAI,aAAa,WAEhB;IAEK,OAAO;CAkCd"}
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var Executor_exports = {};
20
+ __export(Executor_exports, {
21
+ DEFAULTS: () => DEFAULTS,
22
+ Executor: () => Executor
23
+ });
24
+ module.exports = __toCommonJS(Executor_exports);
25
+ var import_consts = require("../consts.js");
26
+ var import_errors = require("../errors.js");
27
+ var import_loaders = require("../loaders.js");
28
+ const DEFAULTS = {
29
+ logger: import_consts.DEFAULT_LOGGER,
30
+ maxAttempts: import_consts.DEFAULT_MAX_ATTEMPTS,
31
+ deleteFailedJobs: import_consts.DEFAULT_DELETE_FAILED_JOBS,
32
+ deleteSuccessfulJobs: import_consts.DEFAULT_DELETE_SUCCESSFUL_JOBS
33
+ };
34
+ class Executor {
35
+ options;
36
+ adapter;
37
+ logger;
38
+ job;
39
+ maxAttempts;
40
+ deleteFailedJobs;
41
+ deleteSuccessfulJobs;
42
+ constructor(options) {
43
+ this.options = { ...DEFAULTS, ...options };
44
+ if (!this.options.adapter) {
45
+ throw new import_errors.AdapterRequiredError();
46
+ }
47
+ if (!this.options.job) {
48
+ throw new import_errors.JobRequiredError();
49
+ }
50
+ this.adapter = this.options.adapter;
51
+ this.logger = this.options.logger;
52
+ this.job = this.options.job;
53
+ this.maxAttempts = this.options.maxAttempts;
54
+ this.deleteFailedJobs = this.options.deleteFailedJobs;
55
+ this.deleteSuccessfulJobs = this.options.deleteSuccessfulJobs;
56
+ }
57
+ get jobIdentifier() {
58
+ return `${this.job.id} (${this.job.path}:${this.job.name})`;
59
+ }
60
+ async perform() {
61
+ this.logger.info(`[RedwoodJob] Started job ${this.jobIdentifier}`);
62
+ try {
63
+ const job = await (0, import_loaders.loadJob)({ name: this.job.name, path: this.job.path });
64
+ await job.perform(...this.job.args);
65
+ await this.adapter.success({
66
+ job: this.job,
67
+ deleteJob: this.deleteSuccessfulJobs
68
+ });
69
+ } catch (error) {
70
+ this.logger.error(
71
+ `[RedwoodJob] Error in job ${this.jobIdentifier}: ${error.message}`
72
+ );
73
+ this.logger.error(error.stack);
74
+ await this.adapter.error({
75
+ job: this.job,
76
+ error
77
+ });
78
+ if (this.job.attempts >= this.maxAttempts) {
79
+ this.logger.warn(
80
+ this.job,
81
+ `[RedwoodJob] Failed job ${this.jobIdentifier}: reached max attempts (${this.maxAttempts})`
82
+ );
83
+ await this.adapter.failure({
84
+ job: this.job,
85
+ deleteJob: this.deleteFailedJobs
86
+ });
87
+ }
88
+ }
89
+ }
90
+ }
91
+ // Annotate the CommonJS export names for ESM import in node:
92
+ 0 && (module.exports = {
93
+ DEFAULTS,
94
+ Executor
95
+ });
@@ -0,0 +1,20 @@
1
+ import type { Adapters, BasicLogger, CreateSchedulerArgs, CreateSchedulerConfig, Job, JobDefinition, JobManagerConfig, QueueNames, WorkerConfig } from '../types.js';
2
+ import type { WorkerOptions } from './Worker.js';
3
+ import { Worker } from './Worker.js';
4
+ export interface CreateWorkerArgs {
5
+ index: number;
6
+ workoff: WorkerOptions['workoff'];
7
+ clear: WorkerOptions['clear'];
8
+ processName: string;
9
+ }
10
+ export declare class JobManager<TAdapters extends Adapters, TQueues extends QueueNames, TLogger extends BasicLogger> {
11
+ adapters: TAdapters;
12
+ queues: TQueues;
13
+ logger: TLogger;
14
+ workers: WorkerConfig<TAdapters, TQueues>[];
15
+ constructor(config: JobManagerConfig<TAdapters, TQueues extends string[] ? never : TQueues, TLogger>);
16
+ createScheduler(schedulerConfig: CreateSchedulerConfig<TAdapters>): <TJob extends Job<TQueues, any[]>>(job: TJob, ...argsAndOptions: CreateSchedulerArgs<TJob>) => Promise<boolean>;
17
+ createJob<TArgs extends unknown[]>(jobDefinition: JobDefinition<TQueues, TArgs>): Job<TQueues, TArgs>;
18
+ createWorker({ index, workoff, clear, processName }: CreateWorkerArgs): Worker;
19
+ }
20
+ //# sourceMappingURL=JobManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JobManager.d.ts","sourceRoot":"","sources":["../../src/core/JobManager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,QAAQ,EACR,WAAW,EACX,mBAAmB,EACnB,qBAAqB,EACrB,GAAG,EACH,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,YAAY,EACb,MAAM,aAAa,CAAA;AAGpB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,CAAA;IACjC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,CAAA;IAC7B,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,qBAAa,UAAU,CACrB,SAAS,SAAS,QAAQ,EAC1B,OAAO,SAAS,UAAU,EAC1B,OAAO,SAAS,WAAW;IAE3B,QAAQ,EAAE,SAAS,CAAA;IACnB,MAAM,EAAE,OAAO,CAAA;IACf,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,CAAA;gBAGzC,MAAM,EAAE,gBAAgB,CACtB,SAAS,EAGT,OAAO,SAAS,MAAM,EAAE,GAAG,KAAK,GAAG,OAAO,EAC1C,OAAO,CACR;IAQH,eAAe,CAAC,eAAe,EAAE,qBAAqB,CAAC,SAAS,CAAC,IAMvD,IAAI,SAAS,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OACjC,IAAI,qBACU,mBAAmB,CAAC,IAAI,CAAC;IAYhD,SAAS,CAAC,KAAK,SAAS,OAAO,EAAE,EAC/B,aAAa,EAAE,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,GAC3C,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC;IAOtB,YAAY,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,gBAAgB;CAqBtE"}
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var JobManager_exports = {};
20
+ __export(JobManager_exports, {
21
+ JobManager: () => JobManager
22
+ });
23
+ module.exports = __toCommonJS(JobManager_exports);
24
+ var import_errors = require("../errors.js");
25
+ var import_Scheduler = require("./Scheduler.js");
26
+ var import_Worker = require("./Worker.js");
27
+ class JobManager {
28
+ adapters;
29
+ queues;
30
+ logger;
31
+ workers;
32
+ constructor(config) {
33
+ this.adapters = config.adapters;
34
+ this.queues = config.queues;
35
+ this.logger = config.logger;
36
+ this.workers = config.workers;
37
+ }
38
+ createScheduler(schedulerConfig) {
39
+ const scheduler = new import_Scheduler.Scheduler({
40
+ adapter: this.adapters[schedulerConfig.adapter],
41
+ logger: this.logger
42
+ });
43
+ return (job, ...argsAndOptions) => {
44
+ const [possibleArgs, possibleOptions] = argsAndOptions;
45
+ const didPassArgs = Array.isArray(possibleArgs);
46
+ const args = didPassArgs ? possibleArgs : [];
47
+ const options = didPassArgs ? possibleOptions : possibleArgs;
48
+ return scheduler.schedule({ job, args, options });
49
+ };
50
+ }
51
+ createJob(jobDefinition) {
52
+ return jobDefinition;
53
+ }
54
+ createWorker({ index, workoff, clear, processName }) {
55
+ const config = this.workers[index];
56
+ const adapter = this.adapters[config.adapter];
57
+ if (!adapter) {
58
+ throw new import_errors.AdapterNotFoundError(config.adapter.toString());
59
+ }
60
+ return new import_Worker.Worker({
61
+ adapter: this.adapters[config.adapter],
62
+ logger: config.logger || this.logger,
63
+ maxAttempts: config.maxAttempts,
64
+ maxRuntime: config.maxRuntime,
65
+ sleepDelay: config.sleepDelay,
66
+ deleteFailedJobs: config.deleteFailedJobs,
67
+ deleteSuccessfulJobs: config.deleteSuccessfulJobs,
68
+ processName,
69
+ queues: [config.queue].flat(),
70
+ workoff,
71
+ clear
72
+ });
73
+ }
74
+ }
75
+ // Annotate the CommonJS export names for ESM import in node:
76
+ 0 && (module.exports = {
77
+ JobManager
78
+ });
@@ -0,0 +1,27 @@
1
+ import type { BaseAdapter, SchedulePayload } from '../adapters/BaseAdapter/BaseAdapter.js';
2
+ import type { BasicLogger, Job, QueueNames, ScheduleJobOptions } from '../types.js';
3
+ interface SchedulerConfig<TAdapter extends BaseAdapter> {
4
+ adapter: TAdapter;
5
+ logger?: BasicLogger;
6
+ }
7
+ export declare class Scheduler<TAdapter extends BaseAdapter> {
8
+ adapter: TAdapter;
9
+ logger: NonNullable<SchedulerConfig<TAdapter>['logger']>;
10
+ constructor({ adapter, logger }: SchedulerConfig<TAdapter>);
11
+ computeRunAt({ wait, waitUntil }: {
12
+ wait: number;
13
+ waitUntil: Date | null;
14
+ }): Date;
15
+ buildPayload<TJob extends Job<QueueNames, unknown[]>>({ job, args, options, }: {
16
+ job: TJob;
17
+ args: Parameters<TJob['perform']> | never[];
18
+ options?: ScheduleJobOptions;
19
+ }): SchedulePayload;
20
+ schedule<TJob extends Job<QueueNames, unknown[]>>({ job, args, options, }: {
21
+ job: TJob;
22
+ args: Parameters<TJob['perform']> | never[];
23
+ options?: ScheduleJobOptions;
24
+ }): Promise<boolean>;
25
+ }
26
+ export {};
27
+ //# sourceMappingURL=Scheduler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Scheduler.d.ts","sourceRoot":"","sources":["../../src/core/Scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,eAAe,EAChB,MAAM,wCAAwC,CAAA;AAY/C,OAAO,KAAK,EACV,WAAW,EACX,GAAG,EACH,UAAU,EACV,kBAAkB,EACnB,MAAM,aAAa,CAAA;AAEpB,UAAU,eAAe,CAAC,QAAQ,SAAS,WAAW;IACpD,OAAO,EAAE,QAAQ,CAAA;IACjB,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB;AAED,qBAAa,SAAS,CAAC,QAAQ,SAAS,WAAW;IACjD,OAAO,EAAE,QAAQ,CAAA;IACjB,MAAM,EAAE,WAAW,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAA;gBAE5C,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,eAAe,CAAC,QAAQ,CAAC;IAS1D,YAAY,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,IAAI,GAAG,IAAI,CAAA;KAAE;IAU1E,YAAY,CAAC,IAAI,SAAS,GAAG,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC,EAAE,EACpD,GAAG,EACH,IAAI,EACJ,OAAO,GACR,EAAE;QACD,GAAG,EAAE,IAAI,CAAA;QACT,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,KAAK,EAAE,CAAA;QAC3C,OAAO,CAAC,EAAE,kBAAkB,CAAA;KAC7B,GAAG,eAAe;IAoBb,QAAQ,CAAC,IAAI,SAAS,GAAG,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC,EAAE,EACtD,GAAG,EACH,IAAI,EACJ,OAAO,GACR,EAAE;QACD,GAAG,EAAE,IAAI,CAAA;QACT,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,KAAK,EAAE,CAAA;QAC3C,OAAO,CAAC,EAAE,kBAAkB,CAAA;KAC7B;CAmBF"}