velocious 1.0.176 → 1.0.178
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/README.md +89 -0
- package/build/src/background-jobs/client.d.ts +23 -0
- package/build/src/background-jobs/client.d.ts.map +1 -0
- package/build/src/background-jobs/client.js +58 -0
- package/build/src/background-jobs/job-record.d.ts +4 -0
- package/build/src/background-jobs/job-record.d.ts.map +1 -0
- package/build/src/background-jobs/job-record.js +11 -0
- package/build/src/background-jobs/job-registry.d.ts +23 -0
- package/build/src/background-jobs/job-registry.d.ts.map +1 -0
- package/build/src/background-jobs/job-registry.js +55 -0
- package/build/src/background-jobs/job-runner.d.ts +6 -0
- package/build/src/background-jobs/job-runner.d.ts.map +1 -0
- package/build/src/background-jobs/job-runner.js +44 -0
- package/build/src/background-jobs/job.d.ts +35 -0
- package/build/src/background-jobs/job.d.ts.map +1 -0
- package/build/src/background-jobs/job.js +61 -0
- package/build/src/background-jobs/json-socket.d.ts +27 -0
- package/build/src/background-jobs/json-socket.d.ts.map +1 -0
- package/build/src/background-jobs/json-socket.js +55 -0
- package/build/src/background-jobs/main.d.ts +62 -0
- package/build/src/background-jobs/main.d.ts.map +1 -0
- package/build/src/background-jobs/main.js +216 -0
- package/build/src/background-jobs/status-reporter.d.ts +54 -0
- package/build/src/background-jobs/status-reporter.d.ts.map +1 -0
- package/build/src/background-jobs/status-reporter.js +113 -0
- package/build/src/background-jobs/store.d.ts +237 -0
- package/build/src/background-jobs/store.d.ts.map +1 -0
- package/build/src/background-jobs/store.js +488 -0
- package/build/src/background-jobs/types.d.ts +17 -0
- package/build/src/background-jobs/types.d.ts.map +1 -0
- package/build/src/background-jobs/types.js +8 -0
- package/build/src/background-jobs/worker.d.ts +64 -0
- package/build/src/background-jobs/worker.d.ts.map +1 -0
- package/build/src/background-jobs/worker.js +155 -0
- package/build/src/cli/commands/background-jobs-main.d.ts +5 -0
- package/build/src/cli/commands/background-jobs-main.d.ts.map +1 -0
- package/build/src/cli/commands/background-jobs-main.js +19 -0
- package/build/src/cli/commands/background-jobs-runner.d.ts +5 -0
- package/build/src/cli/commands/background-jobs-runner.d.ts.map +1 -0
- package/build/src/cli/commands/background-jobs-runner.js +14 -0
- package/build/src/cli/commands/background-jobs-worker.d.ts +5 -0
- package/build/src/cli/commands/background-jobs-worker.d.ts.map +1 -0
- package/build/src/cli/commands/background-jobs-worker.js +19 -0
- package/build/src/configuration-types.d.ts +25 -0
- package/build/src/configuration-types.d.ts.map +1 -1
- package/build/src/configuration-types.js +8 -1
- package/build/src/configuration.d.ts +11 -1
- package/build/src/configuration.d.ts.map +1 -1
- package/build/src/configuration.js +26 -2
- package/build/src/database/drivers/mssql/sql/update.js +3 -3
- package/build/src/database/drivers/mysql/sql/update.js +3 -3
- package/build/src/database/drivers/pgsql/sql/update.js +3 -3
- package/build/src/database/drivers/sqlite/sql/update.js +3 -3
- package/build/src/database/query/update-base.d.ts +5 -0
- package/build/src/database/query/update-base.d.ts.map +1 -1
- package/build/src/database/query/update-base.js +10 -1
- package/build/src/database/query-parser/limit-parser.d.ts.map +1 -1
- package/build/src/database/query-parser/limit-parser.js +8 -7
- package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/generate/base-models.js +6 -4
- package/build/src/testing/base-expect.d.ts +13 -0
- package/build/src/testing/base-expect.d.ts.map +1 -0
- package/build/src/testing/base-expect.js +14 -0
- package/build/src/testing/expect-to-change.d.ts +27 -0
- package/build/src/testing/expect-to-change.d.ts.map +1 -0
- package/build/src/testing/expect-to-change.js +43 -0
- package/build/src/testing/expect-utils.d.ts +45 -0
- package/build/src/testing/expect-utils.d.ts.map +1 -0
- package/build/src/testing/expect-utils.js +190 -0
- package/build/src/testing/expect.d.ts +137 -0
- package/build/src/testing/expect.d.ts.map +1 -0
- package/build/src/testing/expect.js +619 -0
- package/build/src/testing/test.d.ts +4 -157
- package/build/src/testing/test.d.ts.map +1 -1
- package/build/src/testing/test.js +3 -678
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -720,6 +720,95 @@ Create the file `src/routes/testing/another-action.ejs` and so something like th
|
|
|
720
720
|
</p>
|
|
721
721
|
```
|
|
722
722
|
|
|
723
|
+
# Background jobs
|
|
724
|
+
|
|
725
|
+
Velocious includes a simple background jobs system inspired by Sidekiq.
|
|
726
|
+
|
|
727
|
+
## Setup
|
|
728
|
+
|
|
729
|
+
Create a jobs directory in your app:
|
|
730
|
+
|
|
731
|
+
```
|
|
732
|
+
src/jobs/
|
|
733
|
+
```
|
|
734
|
+
|
|
735
|
+
Start the background jobs main process (the queue router):
|
|
736
|
+
|
|
737
|
+
```bash
|
|
738
|
+
npx velocious background-jobs-main
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
Start one or more workers:
|
|
742
|
+
|
|
743
|
+
```bash
|
|
744
|
+
npx velocious background-jobs-worker
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
## Configuration
|
|
748
|
+
|
|
749
|
+
You can configure the main host/port in your configuration:
|
|
750
|
+
|
|
751
|
+
```js
|
|
752
|
+
export default new Configuration({
|
|
753
|
+
// ...
|
|
754
|
+
backgroundJobs: {
|
|
755
|
+
host: "127.0.0.1",
|
|
756
|
+
port: 7331,
|
|
757
|
+
databaseIdentifier: "default"
|
|
758
|
+
}
|
|
759
|
+
})
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
Or via env vars:
|
|
763
|
+
|
|
764
|
+
```
|
|
765
|
+
VELOCIOUS_BACKGROUND_JOBS_HOST=127.0.0.1
|
|
766
|
+
VELOCIOUS_BACKGROUND_JOBS_PORT=7331
|
|
767
|
+
VELOCIOUS_BACKGROUND_JOBS_DATABASE_IDENTIFIER=default
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
## Defining jobs
|
|
771
|
+
|
|
772
|
+
```js
|
|
773
|
+
import VelociousJob from "velocious/build/src/background-jobs/job.js"
|
|
774
|
+
|
|
775
|
+
export default class MyJob extends VelociousJob {
|
|
776
|
+
async perform(arg1, arg2) {
|
|
777
|
+
await doWork(arg1, arg2)
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
Queue a job:
|
|
783
|
+
|
|
784
|
+
```js
|
|
785
|
+
await MyJob.performLater("a", "b")
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
Jobs are forked by default (detached from the worker). To run inline:
|
|
789
|
+
|
|
790
|
+
```js
|
|
791
|
+
await MyJob.performLaterWithOptions({
|
|
792
|
+
args: ["a", "b"],
|
|
793
|
+
options: {forked: false}
|
|
794
|
+
})
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
## Persistence and retries
|
|
798
|
+
|
|
799
|
+
Jobs are persisted in the configured database (`backgroundJobs.databaseIdentifier`) in an internal `background_jobs` table. When a worker picks a job, the job is marked as handed off and the worker reports completion or failure back to the main process.
|
|
800
|
+
|
|
801
|
+
Failed jobs are re-queued with backoff and retried up to 10 times by default (10s, 1m, 10m, 1h, then +1h per retry). You can override the retry limit per job:
|
|
802
|
+
|
|
803
|
+
```js
|
|
804
|
+
await MyJob.performLaterWithOptions({
|
|
805
|
+
args: ["a", "b"],
|
|
806
|
+
options: {maxRetries: 3}
|
|
807
|
+
})
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
If a handed-off job does not report back within 2 hours, it is marked orphaned and re-queued if retries remain.
|
|
811
|
+
|
|
723
812
|
# Running a server
|
|
724
813
|
|
|
725
814
|
```bash
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export default class BackgroundJobsClient {
|
|
2
|
+
/**
|
|
3
|
+
* @param {object} [args] - Options.
|
|
4
|
+
* @param {import("../configuration.js").default} [args.configuration] - Configuration.
|
|
5
|
+
*/
|
|
6
|
+
constructor({ configuration }?: {
|
|
7
|
+
configuration?: import("../configuration.js").default;
|
|
8
|
+
});
|
|
9
|
+
configurationPromise: Promise<import("../configuration.js").default>;
|
|
10
|
+
/**
|
|
11
|
+
* @param {object} args - Options.
|
|
12
|
+
* @param {string} args.jobName - Job name.
|
|
13
|
+
* @param {any[]} args.args - Job args.
|
|
14
|
+
* @param {import("./types.js").BackgroundJobOptions} [args.options] - Job options.
|
|
15
|
+
* @returns {Promise<string>} - Job id.
|
|
16
|
+
*/
|
|
17
|
+
enqueue({ jobName, args, options }: {
|
|
18
|
+
jobName: string;
|
|
19
|
+
args: any[];
|
|
20
|
+
options?: import("./types.js").BackgroundJobOptions;
|
|
21
|
+
}): Promise<string>;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/background-jobs/client.js"],"names":[],"mappings":"AAMA;IACE;;;OAGG;IACH,gCAFG;QAAqD,aAAa,GAA1D,OAAO,qBAAqB,EAAE,OAAO;KAC/C,EAGA;IADC,qEAAoG;IAGtG;;;;;;OAMG;IACH,oCALG;QAAqB,OAAO,EAApB,MAAM;QACM,IAAI,EAAhB,GAAG,EAAE;QAC4C,OAAO,GAAxD,OAAO,YAAY,EAAE,oBAAoB;KACjD,GAAU,OAAO,CAAC,MAAM,CAAC,CA2C3B;CACF"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import net from "net";
|
|
3
|
+
import configurationResolver from "../configuration-resolver.js";
|
|
4
|
+
import JsonSocket from "./json-socket.js";
|
|
5
|
+
export default class BackgroundJobsClient {
|
|
6
|
+
/**
|
|
7
|
+
* @param {object} [args] - Options.
|
|
8
|
+
* @param {import("../configuration.js").default} [args.configuration] - Configuration.
|
|
9
|
+
*/
|
|
10
|
+
constructor({ configuration } = {}) {
|
|
11
|
+
this.configurationPromise = configuration ? Promise.resolve(configuration) : configurationResolver();
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* @param {object} args - Options.
|
|
15
|
+
* @param {string} args.jobName - Job name.
|
|
16
|
+
* @param {any[]} args.args - Job args.
|
|
17
|
+
* @param {import("./types.js").BackgroundJobOptions} [args.options] - Job options.
|
|
18
|
+
* @returns {Promise<string>} - Job id.
|
|
19
|
+
*/
|
|
20
|
+
async enqueue({ jobName, args, options }) {
|
|
21
|
+
const configuration = await this.configurationPromise;
|
|
22
|
+
const { host, port } = configuration.getBackgroundJobsConfig();
|
|
23
|
+
const socket = net.createConnection({ host, port });
|
|
24
|
+
const jsonSocket = new JsonSocket(socket);
|
|
25
|
+
return await new Promise((resolve, reject) => {
|
|
26
|
+
const cleanup = () => {
|
|
27
|
+
jsonSocket.removeAllListeners();
|
|
28
|
+
};
|
|
29
|
+
jsonSocket.on("error", (error) => {
|
|
30
|
+
cleanup();
|
|
31
|
+
reject(error);
|
|
32
|
+
});
|
|
33
|
+
jsonSocket.on("message", (message) => {
|
|
34
|
+
if (message?.type === "enqueued") {
|
|
35
|
+
cleanup();
|
|
36
|
+
jsonSocket.close();
|
|
37
|
+
resolve(message.jobId);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (message?.type === "enqueue-error") {
|
|
41
|
+
cleanup();
|
|
42
|
+
jsonSocket.close();
|
|
43
|
+
reject(new Error(message.error || "Failed to enqueue job"));
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
socket.on("connect", () => {
|
|
47
|
+
jsonSocket.send({ type: "hello", role: "client" });
|
|
48
|
+
jsonSocket.send({
|
|
49
|
+
type: "enqueue",
|
|
50
|
+
jobName,
|
|
51
|
+
args,
|
|
52
|
+
options
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2JhY2tncm91bmQtam9icy9jbGllbnQuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sR0FBRyxNQUFNLEtBQUssQ0FBQTtBQUNyQixPQUFPLHFCQUFxQixNQUFNLDhCQUE4QixDQUFBO0FBQ2hFLE9BQU8sVUFBVSxNQUFNLGtCQUFrQixDQUFBO0FBRXpDLE1BQU0sQ0FBQyxPQUFPLE9BQU8sb0JBQW9CO0lBQ3ZDOzs7T0FHRztJQUNILFlBQVksRUFBQyxhQUFhLEVBQUMsR0FBRyxFQUFFO1FBQzlCLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLHFCQUFxQixFQUFFLENBQUE7SUFDdEcsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBQztRQUNwQyxNQUFNLGFBQWEsR0FBRyxNQUFNLElBQUksQ0FBQyxvQkFBb0IsQ0FBQTtRQUNyRCxNQUFNLEVBQUMsSUFBSSxFQUFFLElBQUksRUFBQyxHQUFHLGFBQWEsQ0FBQyx1QkFBdUIsRUFBRSxDQUFBO1FBQzVELE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFDLElBQUksRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFBO1FBQ2pELE1BQU0sVUFBVSxHQUFHLElBQUksVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBRXpDLE9BQU8sTUFBTSxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtZQUMzQyxNQUFNLE9BQU8sR0FBRyxHQUFHLEVBQUU7Z0JBQ25CLFVBQVUsQ0FBQyxrQkFBa0IsRUFBRSxDQUFBO1lBQ2pDLENBQUMsQ0FBQTtZQUVELFVBQVUsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUU7Z0JBQy9CLE9BQU8sRUFBRSxDQUFBO2dCQUNULE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQTtZQUNmLENBQUMsQ0FBQyxDQUFBO1lBRUYsVUFBVSxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRTtnQkFDbkMsSUFBSSxPQUFPLEVBQUUsSUFBSSxLQUFLLFVBQVUsRUFBRSxDQUFDO29CQUNqQyxPQUFPLEVBQUUsQ0FBQTtvQkFDVCxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUE7b0JBQ2xCLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7b0JBQ3RCLE9BQU07Z0JBQ1IsQ0FBQztnQkFFRCxJQUFJLE9BQU8sRUFBRSxJQUFJLEtBQUssZUFBZSxFQUFFLENBQUM7b0JBQ3RDLE9BQU8sRUFBRSxDQUFBO29CQUNULFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtvQkFDbEIsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLElBQUksdUJBQXVCLENBQUMsQ0FBQyxDQUFBO2dCQUM3RCxDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUE7WUFFRixNQUFNLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUU7Z0JBQ3hCLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUMsQ0FBQyxDQUFBO2dCQUNoRCxVQUFVLENBQUMsSUFBSSxDQUFDO29CQUNkLElBQUksRUFBRSxTQUFTO29CQUNmLE9BQU87b0JBQ1AsSUFBSTtvQkFDSixPQUFPO2lCQUNSLENBQUMsQ0FBQTtZQUNKLENBQUMsQ0FBQyxDQUFBO1FBQ0osQ0FBQyxDQUFDLENBQUE7SUFDSixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IG5ldCBmcm9tIFwibmV0XCJcbmltcG9ydCBjb25maWd1cmF0aW9uUmVzb2x2ZXIgZnJvbSBcIi4uL2NvbmZpZ3VyYXRpb24tcmVzb2x2ZXIuanNcIlxuaW1wb3J0IEpzb25Tb2NrZXQgZnJvbSBcIi4vanNvbi1zb2NrZXQuanNcIlxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCYWNrZ3JvdW5kSm9ic0NsaWVudCB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gW2FyZ3NdIC0gT3B0aW9ucy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9IFthcmdzLmNvbmZpZ3VyYXRpb25dIC0gQ29uZmlndXJhdGlvbi5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHtjb25maWd1cmF0aW9ufSA9IHt9KSB7XG4gICAgdGhpcy5jb25maWd1cmF0aW9uUHJvbWlzZSA9IGNvbmZpZ3VyYXRpb24gPyBQcm9taXNlLnJlc29sdmUoY29uZmlndXJhdGlvbikgOiBjb25maWd1cmF0aW9uUmVzb2x2ZXIoKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3Muam9iTmFtZSAtIEpvYiBuYW1lLlxuICAgKiBAcGFyYW0ge2FueVtdfSBhcmdzLmFyZ3MgLSBKb2IgYXJncy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkJhY2tncm91bmRKb2JPcHRpb25zfSBbYXJncy5vcHRpb25zXSAtIEpvYiBvcHRpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmc+fSAtIEpvYiBpZC5cbiAgICovXG4gIGFzeW5jIGVucXVldWUoe2pvYk5hbWUsIGFyZ3MsIG9wdGlvbnN9KSB7XG4gICAgY29uc3QgY29uZmlndXJhdGlvbiA9IGF3YWl0IHRoaXMuY29uZmlndXJhdGlvblByb21pc2VcbiAgICBjb25zdCB7aG9zdCwgcG9ydH0gPSBjb25maWd1cmF0aW9uLmdldEJhY2tncm91bmRKb2JzQ29uZmlnKClcbiAgICBjb25zdCBzb2NrZXQgPSBuZXQuY3JlYXRlQ29ubmVjdGlvbih7aG9zdCwgcG9ydH0pXG4gICAgY29uc3QganNvblNvY2tldCA9IG5ldyBKc29uU29ja2V0KHNvY2tldClcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCBjbGVhbnVwID0gKCkgPT4ge1xuICAgICAgICBqc29uU29ja2V0LnJlbW92ZUFsbExpc3RlbmVycygpXG4gICAgICB9XG5cbiAgICAgIGpzb25Tb2NrZXQub24oXCJlcnJvclwiLCAoZXJyb3IpID0+IHtcbiAgICAgICAgY2xlYW51cCgpXG4gICAgICAgIHJlamVjdChlcnJvcilcbiAgICAgIH0pXG5cbiAgICAgIGpzb25Tb2NrZXQub24oXCJtZXNzYWdlXCIsIChtZXNzYWdlKSA9PiB7XG4gICAgICAgIGlmIChtZXNzYWdlPy50eXBlID09PSBcImVucXVldWVkXCIpIHtcbiAgICAgICAgICBjbGVhbnVwKClcbiAgICAgICAgICBqc29uU29ja2V0LmNsb3NlKClcbiAgICAgICAgICByZXNvbHZlKG1lc3NhZ2Uuam9iSWQpXG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBpZiAobWVzc2FnZT8udHlwZSA9PT0gXCJlbnF1ZXVlLWVycm9yXCIpIHtcbiAgICAgICAgICBjbGVhbnVwKClcbiAgICAgICAgICBqc29uU29ja2V0LmNsb3NlKClcbiAgICAgICAgICByZWplY3QobmV3IEVycm9yKG1lc3NhZ2UuZXJyb3IgfHwgXCJGYWlsZWQgdG8gZW5xdWV1ZSBqb2JcIikpXG4gICAgICAgIH1cbiAgICAgIH0pXG5cbiAgICAgIHNvY2tldC5vbihcImNvbm5lY3RcIiwgKCkgPT4ge1xuICAgICAgICBqc29uU29ja2V0LnNlbmQoe3R5cGU6IFwiaGVsbG9cIiwgcm9sZTogXCJjbGllbnRcIn0pXG4gICAgICAgIGpzb25Tb2NrZXQuc2VuZCh7XG4gICAgICAgICAgdHlwZTogXCJlbnF1ZXVlXCIsXG4gICAgICAgICAgam9iTmFtZSxcbiAgICAgICAgICBhcmdzLFxuICAgICAgICAgIG9wdGlvbnNcbiAgICAgICAgfSlcbiAgICAgIH0pXG4gICAgfSlcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-record.d.ts","sourceRoot":"","sources":["../../../src/background-jobs/job-record.js"],"names":[],"mappings":"AAIA;CAQC;2BAV0B,6BAA6B"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import DatabaseRecord from "../database/record/index.js";
|
|
3
|
+
export default class BackgroundJobRecord extends DatabaseRecord {
|
|
4
|
+
static tableName() {
|
|
5
|
+
return "background_jobs";
|
|
6
|
+
}
|
|
7
|
+
static primaryKey() {
|
|
8
|
+
return "id";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiam9iLXJlY29yZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9iYWNrZ3JvdW5kLWpvYnMvam9iLXJlY29yZC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxjQUFjLE1BQU0sNkJBQTZCLENBQUE7QUFFeEQsTUFBTSxDQUFDLE9BQU8sT0FBTyxtQkFBb0IsU0FBUSxjQUFjO0lBQzdELE1BQU0sQ0FBQyxTQUFTO1FBQ2QsT0FBTyxpQkFBaUIsQ0FBQTtJQUMxQixDQUFDO0lBRUQsTUFBTSxDQUFDLFVBQVU7UUFDZixPQUFPLElBQUksQ0FBQTtJQUNiLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgRGF0YWJhc2VSZWNvcmQgZnJvbSBcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJhY2tncm91bmRKb2JSZWNvcmQgZXh0ZW5kcyBEYXRhYmFzZVJlY29yZCB7XG4gIHN0YXRpYyB0YWJsZU5hbWUoKSB7XG4gICAgcmV0dXJuIFwiYmFja2dyb3VuZF9qb2JzXCJcbiAgfVxuXG4gIHN0YXRpYyBwcmltYXJ5S2V5KCkge1xuICAgIHJldHVybiBcImlkXCJcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export default class BackgroundJobRegistry {
|
|
2
|
+
/**
|
|
3
|
+
* @param {object} args - Options.
|
|
4
|
+
* @param {import("../configuration.js").default} args.configuration - Configuration.
|
|
5
|
+
*/
|
|
6
|
+
constructor({ configuration }: {
|
|
7
|
+
configuration: import("../configuration.js").default;
|
|
8
|
+
});
|
|
9
|
+
configuration: import("../configuration.js").default;
|
|
10
|
+
/** @type {Map<string, typeof VelociousJob>} */
|
|
11
|
+
jobsByName: Map<string, typeof VelociousJob>;
|
|
12
|
+
/**
|
|
13
|
+
* @returns {Promise<void>} - Resolves when complete.
|
|
14
|
+
*/
|
|
15
|
+
load(): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* @param {string} jobName - Job name.
|
|
18
|
+
* @returns {typeof VelociousJob} - Job class.
|
|
19
|
+
*/
|
|
20
|
+
getJobByName(jobName: string): typeof VelociousJob;
|
|
21
|
+
}
|
|
22
|
+
import VelociousJob from "./job.js";
|
|
23
|
+
//# sourceMappingURL=job-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-registry.d.ts","sourceRoot":"","sources":["../../../src/background-jobs/job-registry.js"],"names":[],"mappings":"AAMA;IACE;;;OAGG;IACH,+BAFG;QAAoD,aAAa,EAAzD,OAAO,qBAAqB,EAAE,OAAO;KAC/C,EAKA;IAHC,qDAAkC;IAClC,+CAA+C;IAC/C,YADW,GAAG,CAAC,MAAM,EAAE,OAAO,YAAY,CAAC,CAChB;IAG7B;;OAEG;IACH,QAFa,OAAO,CAAC,IAAI,CAAC,CA+BzB;IAED;;;OAGG;IACH,sBAHW,MAAM,GACJ,OAAO,YAAY,CAU/B;CACF;yBA5DwB,UAAU"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import fs from "fs/promises";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import VelociousJob from "./job.js";
|
|
5
|
+
export default class BackgroundJobRegistry {
|
|
6
|
+
/**
|
|
7
|
+
* @param {object} args - Options.
|
|
8
|
+
* @param {import("../configuration.js").default} args.configuration - Configuration.
|
|
9
|
+
*/
|
|
10
|
+
constructor({ configuration }) {
|
|
11
|
+
this.configuration = configuration;
|
|
12
|
+
/** @type {Map<string, typeof VelociousJob>} */
|
|
13
|
+
this.jobsByName = new Map();
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* @returns {Promise<void>} - Resolves when complete.
|
|
17
|
+
*/
|
|
18
|
+
async load() {
|
|
19
|
+
const directory = this.configuration.getDirectory();
|
|
20
|
+
const jobsDir = path.join(directory, "src", "jobs");
|
|
21
|
+
try {
|
|
22
|
+
await fs.access(jobsDir);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const jobFiles = fs.glob(`${jobsDir}/**/*.js`);
|
|
28
|
+
for await (const jobFile of jobFiles) {
|
|
29
|
+
const jobImport = await import(jobFile);
|
|
30
|
+
const JobClass = jobImport.default;
|
|
31
|
+
if (!JobClass)
|
|
32
|
+
throw new Error(`Job file must export a default class: ${jobFile}`);
|
|
33
|
+
if (!(JobClass.prototype instanceof VelociousJob)) {
|
|
34
|
+
throw new Error(`Job class must extend VelociousJob: ${jobFile}`);
|
|
35
|
+
}
|
|
36
|
+
const jobName = JobClass.jobName();
|
|
37
|
+
if (this.jobsByName.has(jobName)) {
|
|
38
|
+
throw new Error(`Duplicate job name "${jobName}" from ${jobFile}`);
|
|
39
|
+
}
|
|
40
|
+
this.jobsByName.set(jobName, JobClass);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* @param {string} jobName - Job name.
|
|
45
|
+
* @returns {typeof VelociousJob} - Job class.
|
|
46
|
+
*/
|
|
47
|
+
getJobByName(jobName) {
|
|
48
|
+
const jobClass = this.jobsByName.get(jobName);
|
|
49
|
+
if (!jobClass) {
|
|
50
|
+
throw new Error(`Unknown job "${jobName}". Check src/jobs`);
|
|
51
|
+
}
|
|
52
|
+
return jobClass;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiam9iLXJlZ2lzdHJ5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2JhY2tncm91bmQtam9icy9qb2ItcmVnaXN0cnkuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sRUFBRSxNQUFNLGFBQWEsQ0FBQTtBQUM1QixPQUFPLElBQUksTUFBTSxNQUFNLENBQUE7QUFDdkIsT0FBTyxZQUFZLE1BQU0sVUFBVSxDQUFBO0FBRW5DLE1BQU0sQ0FBQyxPQUFPLE9BQU8scUJBQXFCO0lBQ3hDOzs7T0FHRztJQUNILFlBQVksRUFBQyxhQUFhLEVBQUM7UUFDekIsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUE7UUFDbEMsK0NBQStDO1FBQy9DLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQTtJQUM3QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsSUFBSTtRQUNSLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxFQUFFLENBQUE7UUFDbkQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFBO1FBRW5ELElBQUksQ0FBQztZQUNILE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUMxQixDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsT0FBTTtRQUNSLENBQUM7UUFFRCxNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsT0FBTyxVQUFVLENBQUMsQ0FBQTtRQUU5QyxJQUFJLEtBQUssRUFBRSxNQUFNLE9BQU8sSUFBSSxRQUFRLEVBQUUsQ0FBQztZQUNyQyxNQUFNLFNBQVMsR0FBRyxNQUFNLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQTtZQUN2QyxNQUFNLFFBQVEsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFBO1lBRWxDLElBQUksQ0FBQyxRQUFRO2dCQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMseUNBQXlDLE9BQU8sRUFBRSxDQUFDLENBQUE7WUFDbEYsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLFNBQVMsWUFBWSxZQUFZLENBQUMsRUFBRSxDQUFDO2dCQUNsRCxNQUFNLElBQUksS0FBSyxDQUFDLHVDQUF1QyxPQUFPLEVBQUUsQ0FBQyxDQUFBO1lBQ25FLENBQUM7WUFFRCxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUE7WUFFbEMsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dCQUNqQyxNQUFNLElBQUksS0FBSyxDQUFDLHVCQUF1QixPQUFPLFVBQVUsT0FBTyxFQUFFLENBQUMsQ0FBQTtZQUNwRSxDQUFDO1lBRUQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFBO1FBQ3hDLENBQUM7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsWUFBWSxDQUFDLE9BQU87UUFDbEIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUE7UUFFN0MsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ2QsTUFBTSxJQUFJLEtBQUssQ0FBQyxnQkFBZ0IsT0FBTyxtQkFBbUIsQ0FBQyxDQUFBO1FBQzdELENBQUM7UUFFRCxPQUFPLFFBQVEsQ0FBQTtJQUNqQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IGZzIGZyb20gXCJmcy9wcm9taXNlc1wiXG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiXG5pbXBvcnQgVmVsb2Npb3VzSm9iIGZyb20gXCIuL2pvYi5qc1wiXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJhY2tncm91bmRKb2JSZWdpc3RyeSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0fSBhcmdzLmNvbmZpZ3VyYXRpb24gLSBDb25maWd1cmF0aW9uLlxuICAgKi9cbiAgY29uc3RydWN0b3Ioe2NvbmZpZ3VyYXRpb259KSB7XG4gICAgdGhpcy5jb25maWd1cmF0aW9uID0gY29uZmlndXJhdGlvblxuICAgIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgdHlwZW9mIFZlbG9jaW91c0pvYj59ICovXG4gICAgdGhpcy5qb2JzQnlOYW1lID0gbmV3IE1hcCgpXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGxvYWQoKSB7XG4gICAgY29uc3QgZGlyZWN0b3J5ID0gdGhpcy5jb25maWd1cmF0aW9uLmdldERpcmVjdG9yeSgpXG4gICAgY29uc3Qgam9ic0RpciA9IHBhdGguam9pbihkaXJlY3RvcnksIFwic3JjXCIsIFwiam9ic1wiKVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGZzLmFjY2Vzcyhqb2JzRGlyKVxuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3Qgam9iRmlsZXMgPSBmcy5nbG9iKGAke2pvYnNEaXJ9LyoqLyouanNgKVxuXG4gICAgZm9yIGF3YWl0IChjb25zdCBqb2JGaWxlIG9mIGpvYkZpbGVzKSB7XG4gICAgICBjb25zdCBqb2JJbXBvcnQgPSBhd2FpdCBpbXBvcnQoam9iRmlsZSlcbiAgICAgIGNvbnN0IEpvYkNsYXNzID0gam9iSW1wb3J0LmRlZmF1bHRcblxuICAgICAgaWYgKCFKb2JDbGFzcykgdGhyb3cgbmV3IEVycm9yKGBKb2IgZmlsZSBtdXN0IGV4cG9ydCBhIGRlZmF1bHQgY2xhc3M6ICR7am9iRmlsZX1gKVxuICAgICAgaWYgKCEoSm9iQ2xhc3MucHJvdG90eXBlIGluc3RhbmNlb2YgVmVsb2Npb3VzSm9iKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEpvYiBjbGFzcyBtdXN0IGV4dGVuZCBWZWxvY2lvdXNKb2I6ICR7am9iRmlsZX1gKVxuICAgICAgfVxuXG4gICAgICBjb25zdCBqb2JOYW1lID0gSm9iQ2xhc3Muam9iTmFtZSgpXG5cbiAgICAgIGlmICh0aGlzLmpvYnNCeU5hbWUuaGFzKGpvYk5hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRHVwbGljYXRlIGpvYiBuYW1lIFwiJHtqb2JOYW1lfVwiIGZyb20gJHtqb2JGaWxlfWApXG4gICAgICB9XG5cbiAgICAgIHRoaXMuam9ic0J5TmFtZS5zZXQoam9iTmFtZSwgSm9iQ2xhc3MpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBqb2JOYW1lIC0gSm9iIG5hbWUuXG4gICAqIEByZXR1cm5zIHt0eXBlb2YgVmVsb2Npb3VzSm9ifSAtIEpvYiBjbGFzcy5cbiAgICovXG4gIGdldEpvYkJ5TmFtZShqb2JOYW1lKSB7XG4gICAgY29uc3Qgam9iQ2xhc3MgPSB0aGlzLmpvYnNCeU5hbWUuZ2V0KGpvYk5hbWUpXG5cbiAgICBpZiAoIWpvYkNsYXNzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gam9iIFwiJHtqb2JOYW1lfVwiLiBDaGVjayBzcmMvam9ic2ApXG4gICAgfVxuXG4gICAgcmV0dXJuIGpvYkNsYXNzXG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-runner.d.ts","sourceRoot":"","sources":["../../../src/background-jobs/job-runner.js"],"names":[],"mappings":"AAMA;;;GAGG;AACH,+CAHW,MAAM,GACJ,OAAO,CAAC,IAAI,CAAC,CAuCzB"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import configurationResolver from "../configuration-resolver.js";
|
|
3
|
+
import BackgroundJobRegistry from "./job-registry.js";
|
|
4
|
+
import BackgroundJobsStatusReporter from "./status-reporter.js";
|
|
5
|
+
/**
|
|
6
|
+
* @param {object} payload - Payload.
|
|
7
|
+
* @returns {Promise<void>} - Resolves when complete.
|
|
8
|
+
*/
|
|
9
|
+
export default async function runJobPayload(payload) {
|
|
10
|
+
const configuration = await configurationResolver();
|
|
11
|
+
configuration.setCurrent();
|
|
12
|
+
await configuration.initialize({ type: "background-jobs-runner" });
|
|
13
|
+
const reporter = new BackgroundJobsStatusReporter({ configuration });
|
|
14
|
+
const registry = new BackgroundJobRegistry({ configuration });
|
|
15
|
+
await registry.load();
|
|
16
|
+
const JobClass = registry.getJobByName(payload.jobName);
|
|
17
|
+
const jobInstance = new JobClass();
|
|
18
|
+
try {
|
|
19
|
+
await jobInstance.perform.apply(jobInstance, payload.args || []);
|
|
20
|
+
if (payload.id) {
|
|
21
|
+
await reporter.reportWithRetry({
|
|
22
|
+
jobId: payload.id,
|
|
23
|
+
status: "completed",
|
|
24
|
+
workerId: payload.workerId,
|
|
25
|
+
handedOffAtMs: payload.handedOffAtMs,
|
|
26
|
+
maxDurationMs: 30000
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
if (payload.id) {
|
|
32
|
+
await reporter.reportWithRetry({
|
|
33
|
+
jobId: payload.id,
|
|
34
|
+
status: "failed",
|
|
35
|
+
error,
|
|
36
|
+
workerId: payload.workerId,
|
|
37
|
+
handedOffAtMs: payload.handedOffAtMs,
|
|
38
|
+
maxDurationMs: 30000
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiam9iLXJ1bm5lci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9iYWNrZ3JvdW5kLWpvYnMvam9iLXJ1bm5lci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxxQkFBcUIsTUFBTSw4QkFBOEIsQ0FBQTtBQUNoRSxPQUFPLHFCQUFxQixNQUFNLG1CQUFtQixDQUFBO0FBQ3JELE9BQU8sNEJBQTRCLE1BQU0sc0JBQXNCLENBQUE7QUFFL0Q7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLFVBQVUsYUFBYSxDQUFDLE9BQU87SUFDakQsTUFBTSxhQUFhLEdBQUcsTUFBTSxxQkFBcUIsRUFBRSxDQUFBO0lBQ25ELGFBQWEsQ0FBQyxVQUFVLEVBQUUsQ0FBQTtJQUMxQixNQUFNLGFBQWEsQ0FBQyxVQUFVLENBQUMsRUFBQyxJQUFJLEVBQUUsd0JBQXdCLEVBQUMsQ0FBQyxDQUFBO0lBQ2hFLE1BQU0sUUFBUSxHQUFHLElBQUksNEJBQTRCLENBQUMsRUFBQyxhQUFhLEVBQUMsQ0FBQyxDQUFBO0lBRWxFLE1BQU0sUUFBUSxHQUFHLElBQUkscUJBQXFCLENBQUMsRUFBQyxhQUFhLEVBQUMsQ0FBQyxDQUFBO0lBQzNELE1BQU0sUUFBUSxDQUFDLElBQUksRUFBRSxDQUFBO0lBQ3JCLE1BQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQ3ZELE1BQU0sV0FBVyxHQUFHLElBQUksUUFBUSxFQUFFLENBQUE7SUFFbEMsSUFBSSxDQUFDO1FBQ0gsTUFBTSxXQUFXLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsT0FBTyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQTtRQUVoRSxJQUFJLE9BQU8sQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNmLE1BQU0sUUFBUSxDQUFDLGVBQWUsQ0FBQztnQkFDN0IsS0FBSyxFQUFFLE9BQU8sQ0FBQyxFQUFFO2dCQUNqQixNQUFNLEVBQUUsV0FBVztnQkFDbkIsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRO2dCQUMxQixhQUFhLEVBQUUsT0FBTyxDQUFDLGFBQWE7Z0JBQ3BDLGFBQWEsRUFBRSxLQUFLO2FBQ3JCLENBQUMsQ0FBQTtRQUNKLENBQUM7SUFDSCxDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLElBQUksT0FBTyxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ2YsTUFBTSxRQUFRLENBQUMsZUFBZSxDQUFDO2dCQUM3QixLQUFLLEVBQUUsT0FBTyxDQUFDLEVBQUU7Z0JBQ2pCLE1BQU0sRUFBRSxRQUFRO2dCQUNoQixLQUFLO2dCQUNMLFFBQVEsRUFBRSxPQUFPLENBQUMsUUFBUTtnQkFDMUIsYUFBYSxFQUFFLE9BQU8sQ0FBQyxhQUFhO2dCQUNwQyxhQUFhLEVBQUUsS0FBSzthQUNyQixDQUFDLENBQUE7UUFDSixDQUFDO1FBRUQsTUFBTSxLQUFLLENBQUE7SUFDYixDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgY29uZmlndXJhdGlvblJlc29sdmVyIGZyb20gXCIuLi9jb25maWd1cmF0aW9uLXJlc29sdmVyLmpzXCJcbmltcG9ydCBCYWNrZ3JvdW5kSm9iUmVnaXN0cnkgZnJvbSBcIi4vam9iLXJlZ2lzdHJ5LmpzXCJcbmltcG9ydCBCYWNrZ3JvdW5kSm9ic1N0YXR1c1JlcG9ydGVyIGZyb20gXCIuL3N0YXR1cy1yZXBvcnRlci5qc1wiXG5cbi8qKlxuICogQHBhcmFtIHtvYmplY3R9IHBheWxvYWQgLSBQYXlsb2FkLlxuICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgYXN5bmMgZnVuY3Rpb24gcnVuSm9iUGF5bG9hZChwYXlsb2FkKSB7XG4gIGNvbnN0IGNvbmZpZ3VyYXRpb24gPSBhd2FpdCBjb25maWd1cmF0aW9uUmVzb2x2ZXIoKVxuICBjb25maWd1cmF0aW9uLnNldEN1cnJlbnQoKVxuICBhd2FpdCBjb25maWd1cmF0aW9uLmluaXRpYWxpemUoe3R5cGU6IFwiYmFja2dyb3VuZC1qb2JzLXJ1bm5lclwifSlcbiAgY29uc3QgcmVwb3J0ZXIgPSBuZXcgQmFja2dyb3VuZEpvYnNTdGF0dXNSZXBvcnRlcih7Y29uZmlndXJhdGlvbn0pXG5cbiAgY29uc3QgcmVnaXN0cnkgPSBuZXcgQmFja2dyb3VuZEpvYlJlZ2lzdHJ5KHtjb25maWd1cmF0aW9ufSlcbiAgYXdhaXQgcmVnaXN0cnkubG9hZCgpXG4gIGNvbnN0IEpvYkNsYXNzID0gcmVnaXN0cnkuZ2V0Sm9iQnlOYW1lKHBheWxvYWQuam9iTmFtZSlcbiAgY29uc3Qgam9iSW5zdGFuY2UgPSBuZXcgSm9iQ2xhc3MoKVxuXG4gIHRyeSB7XG4gICAgYXdhaXQgam9iSW5zdGFuY2UucGVyZm9ybS5hcHBseShqb2JJbnN0YW5jZSwgcGF5bG9hZC5hcmdzIHx8IFtdKVxuXG4gICAgaWYgKHBheWxvYWQuaWQpIHtcbiAgICAgIGF3YWl0IHJlcG9ydGVyLnJlcG9ydFdpdGhSZXRyeSh7XG4gICAgICAgIGpvYklkOiBwYXlsb2FkLmlkLFxuICAgICAgICBzdGF0dXM6IFwiY29tcGxldGVkXCIsXG4gICAgICAgIHdvcmtlcklkOiBwYXlsb2FkLndvcmtlcklkLFxuICAgICAgICBoYW5kZWRPZmZBdE1zOiBwYXlsb2FkLmhhbmRlZE9mZkF0TXMsXG4gICAgICAgIG1heER1cmF0aW9uTXM6IDMwMDAwXG4gICAgICB9KVxuICAgIH1cbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAocGF5bG9hZC5pZCkge1xuICAgICAgYXdhaXQgcmVwb3J0ZXIucmVwb3J0V2l0aFJldHJ5KHtcbiAgICAgICAgam9iSWQ6IHBheWxvYWQuaWQsXG4gICAgICAgIHN0YXR1czogXCJmYWlsZWRcIixcbiAgICAgICAgZXJyb3IsXG4gICAgICAgIHdvcmtlcklkOiBwYXlsb2FkLndvcmtlcklkLFxuICAgICAgICBoYW5kZWRPZmZBdE1zOiBwYXlsb2FkLmhhbmRlZE9mZkF0TXMsXG4gICAgICAgIG1heER1cmF0aW9uTXM6IDMwMDAwXG4gICAgICB9KVxuICAgIH1cblxuICAgIHRocm93IGVycm9yXG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export default class VelociousJob {
|
|
2
|
+
/**
|
|
3
|
+
* @returns {string} - Job name.
|
|
4
|
+
*/
|
|
5
|
+
static jobName(): string;
|
|
6
|
+
/**
|
|
7
|
+
* @param {...any} args - Job args.
|
|
8
|
+
* @returns {Promise<string>} - Job id.
|
|
9
|
+
*/
|
|
10
|
+
static performLater(...args: any[]): Promise<string>;
|
|
11
|
+
/**
|
|
12
|
+
* @param {object} args - Options.
|
|
13
|
+
* @param {any[]} args.args - Job args.
|
|
14
|
+
* @param {import("./types.js").BackgroundJobOptions} [args.options] - Job options.
|
|
15
|
+
* @returns {Promise<string>} - Job id.
|
|
16
|
+
*/
|
|
17
|
+
static performLaterWithOptions({ args, options }: {
|
|
18
|
+
args: any[];
|
|
19
|
+
options?: import("./types.js").BackgroundJobOptions;
|
|
20
|
+
}): Promise<string>;
|
|
21
|
+
/**
|
|
22
|
+
* @param {any[]} args - Job args.
|
|
23
|
+
* @returns {{jobArgs: any[], jobOptions: import("./types.js").BackgroundJobOptions}} - Split args and options.
|
|
24
|
+
*/
|
|
25
|
+
static _splitArgsAndOptions(args: any[]): {
|
|
26
|
+
jobArgs: any[];
|
|
27
|
+
jobOptions: import("./types.js").BackgroundJobOptions;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Override in subclasses.
|
|
31
|
+
* @returns {Promise<void>} - Resolves when complete.
|
|
32
|
+
*/
|
|
33
|
+
perform(): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=job.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job.d.ts","sourceRoot":"","sources":["../../../src/background-jobs/job.js"],"names":[],"mappings":"AAIA;IACE;;OAEG;IACH,kBAFa,MAAM,CAIlB;IAED;;;OAGG;IACH,6BAHc,GAAG,EAAA,GACJ,OAAO,CAAC,MAAM,CAAC,CAW3B;IAED;;;;;OAKG;IACH,kDAJG;QAAoB,IAAI,EAAhB,GAAG,EAAE;QAC4C,OAAO,GAAxD,OAAO,YAAY,EAAE,oBAAoB;KACjD,GAAU,OAAO,CAAC,MAAM,CAAC,CAU3B;IAED;;;OAGG;IACH,kCAHW,GAAG,EAAE,GACH;QAAC,OAAO,EAAE,GAAG,EAAE,CAAC;QAAC,UAAU,EAAE,OAAO,YAAY,EAAE,oBAAoB,CAAA;KAAC,CAgBnF;IAED;;;OAGG;IACH,WAFa,OAAO,CAAC,IAAI,CAAC,CAIzB;CACF"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import BackgroundJobsClient from "./client.js";
|
|
3
|
+
export default class VelociousJob {
|
|
4
|
+
/**
|
|
5
|
+
* @returns {string} - Job name.
|
|
6
|
+
*/
|
|
7
|
+
static jobName() {
|
|
8
|
+
return this.name;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* @param {...any} args - Job args.
|
|
12
|
+
* @returns {Promise<string>} - Job id.
|
|
13
|
+
*/
|
|
14
|
+
static async performLater(...args) {
|
|
15
|
+
const { jobArgs, jobOptions } = this._splitArgsAndOptions(args);
|
|
16
|
+
const client = new BackgroundJobsClient();
|
|
17
|
+
return await client.enqueue({
|
|
18
|
+
jobName: this.jobName(),
|
|
19
|
+
args: jobArgs,
|
|
20
|
+
options: jobOptions
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* @param {object} args - Options.
|
|
25
|
+
* @param {any[]} args.args - Job args.
|
|
26
|
+
* @param {import("./types.js").BackgroundJobOptions} [args.options] - Job options.
|
|
27
|
+
* @returns {Promise<string>} - Job id.
|
|
28
|
+
*/
|
|
29
|
+
static async performLaterWithOptions({ args, options }) {
|
|
30
|
+
const client = new BackgroundJobsClient();
|
|
31
|
+
return await client.enqueue({
|
|
32
|
+
jobName: this.jobName(),
|
|
33
|
+
args,
|
|
34
|
+
options
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* @param {any[]} args - Job args.
|
|
39
|
+
* @returns {{jobArgs: any[], jobOptions: import("./types.js").BackgroundJobOptions}} - Split args and options.
|
|
40
|
+
*/
|
|
41
|
+
static _splitArgsAndOptions(args) {
|
|
42
|
+
if (args.length === 0) {
|
|
43
|
+
return { jobArgs: [], jobOptions: {} };
|
|
44
|
+
}
|
|
45
|
+
const lastArg = args[args.length - 1];
|
|
46
|
+
const isOptionsArg = lastArg && typeof lastArg === "object" && !Array.isArray(lastArg) && "jobOptions" in lastArg;
|
|
47
|
+
if (isOptionsArg) {
|
|
48
|
+
const { jobOptions } = /** @type {{jobOptions: import("./types.js").BackgroundJobOptions}} */ (lastArg);
|
|
49
|
+
return { jobArgs: args.slice(0, -1), jobOptions: jobOptions || {} };
|
|
50
|
+
}
|
|
51
|
+
return { jobArgs: args, jobOptions: {} };
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Override in subclasses.
|
|
55
|
+
* @returns {Promise<void>} - Resolves when complete.
|
|
56
|
+
*/
|
|
57
|
+
async perform() {
|
|
58
|
+
throw new Error("perform not implemented");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiam9iLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2JhY2tncm91bmQtam9icy9qb2IuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sb0JBQW9CLE1BQU0sYUFBYSxDQUFBO0FBRTlDLE1BQU0sQ0FBQyxPQUFPLE9BQU8sWUFBWTtJQUMvQjs7T0FFRztJQUNILE1BQU0sQ0FBQyxPQUFPO1FBQ1osT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFBO0lBQ2xCLENBQUM7SUFFRDs7O09BR0c7SUFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxHQUFHLElBQUk7UUFDL0IsTUFBTSxFQUFDLE9BQU8sRUFBRSxVQUFVLEVBQUMsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDN0QsTUFBTSxNQUFNLEdBQUcsSUFBSSxvQkFBb0IsRUFBRSxDQUFBO1FBRXpDLE9BQU8sTUFBTSxNQUFNLENBQUMsT0FBTyxDQUFDO1lBQzFCLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ3ZCLElBQUksRUFBRSxPQUFPO1lBQ2IsT0FBTyxFQUFFLFVBQVU7U0FDcEIsQ0FBQyxDQUFBO0lBQ0osQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxFQUFDLElBQUksRUFBRSxPQUFPLEVBQUM7UUFDbEQsTUFBTSxNQUFNLEdBQUcsSUFBSSxvQkFBb0IsRUFBRSxDQUFBO1FBRXpDLE9BQU8sTUFBTSxNQUFNLENBQUMsT0FBTyxDQUFDO1lBQzFCLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ3ZCLElBQUk7WUFDSixPQUFPO1NBQ1IsQ0FBQyxDQUFBO0lBQ0osQ0FBQztJQUVEOzs7T0FHRztJQUNILE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJO1FBQzlCLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN0QixPQUFPLEVBQUMsT0FBTyxFQUFFLEVBQUUsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFDLENBQUE7UUFDdEMsQ0FBQztRQUVELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFBO1FBQ3JDLE1BQU0sWUFBWSxHQUFHLE9BQU8sSUFBSSxPQUFPLE9BQU8sS0FBSyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLFlBQVksSUFBSSxPQUFPLENBQUE7UUFFakgsSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUNqQixNQUFNLEVBQUMsVUFBVSxFQUFDLEdBQUcsc0VBQXNFLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQTtZQUNyRyxPQUFPLEVBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsVUFBVSxFQUFFLFVBQVUsSUFBSSxFQUFFLEVBQUMsQ0FBQTtRQUNuRSxDQUFDO1FBRUQsT0FBTyxFQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLEVBQUUsRUFBQyxDQUFBO0lBQ3hDLENBQUM7SUFFRDs7O09BR0c7SUFDSCxLQUFLLENBQUMsT0FBTztRQUNYLE1BQU0sSUFBSSxLQUFLLENBQUMseUJBQXlCLENBQUMsQ0FBQTtJQUM1QyxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IEJhY2tncm91bmRKb2JzQ2xpZW50IGZyb20gXCIuL2NsaWVudC5qc1wiXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFZlbG9jaW91c0pvYiB7XG4gIC8qKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIEpvYiBuYW1lLlxuICAgKi9cbiAgc3RhdGljIGpvYk5hbWUoKSB7XG4gICAgcmV0dXJuIHRoaXMubmFtZVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7Li4uYW55fSBhcmdzIC0gSm9iIGFyZ3MuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZz59IC0gSm9iIGlkLlxuICAgKi9cbiAgc3RhdGljIGFzeW5jIHBlcmZvcm1MYXRlciguLi5hcmdzKSB7XG4gICAgY29uc3Qge2pvYkFyZ3MsIGpvYk9wdGlvbnN9ID0gdGhpcy5fc3BsaXRBcmdzQW5kT3B0aW9ucyhhcmdzKVxuICAgIGNvbnN0IGNsaWVudCA9IG5ldyBCYWNrZ3JvdW5kSm9ic0NsaWVudCgpXG5cbiAgICByZXR1cm4gYXdhaXQgY2xpZW50LmVucXVldWUoe1xuICAgICAgam9iTmFtZTogdGhpcy5qb2JOYW1lKCksXG4gICAgICBhcmdzOiBqb2JBcmdzLFxuICAgICAgb3B0aW9uczogam9iT3B0aW9uc1xuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zLlxuICAgKiBAcGFyYW0ge2FueVtdfSBhcmdzLmFyZ3MgLSBKb2IgYXJncy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkJhY2tncm91bmRKb2JPcHRpb25zfSBbYXJncy5vcHRpb25zXSAtIEpvYiBvcHRpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmc+fSAtIEpvYiBpZC5cbiAgICovXG4gIHN0YXRpYyBhc3luYyBwZXJmb3JtTGF0ZXJXaXRoT3B0aW9ucyh7YXJncywgb3B0aW9uc30pIHtcbiAgICBjb25zdCBjbGllbnQgPSBuZXcgQmFja2dyb3VuZEpvYnNDbGllbnQoKVxuXG4gICAgcmV0dXJuIGF3YWl0IGNsaWVudC5lbnF1ZXVlKHtcbiAgICAgIGpvYk5hbWU6IHRoaXMuam9iTmFtZSgpLFxuICAgICAgYXJncyxcbiAgICAgIG9wdGlvbnNcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7YW55W119IGFyZ3MgLSBKb2IgYXJncy5cbiAgICogQHJldHVybnMge3tqb2JBcmdzOiBhbnlbXSwgam9iT3B0aW9uczogaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5CYWNrZ3JvdW5kSm9iT3B0aW9uc319IC0gU3BsaXQgYXJncyBhbmQgb3B0aW9ucy5cbiAgICovXG4gIHN0YXRpYyBfc3BsaXRBcmdzQW5kT3B0aW9ucyhhcmdzKSB7XG4gICAgaWYgKGFyZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4ge2pvYkFyZ3M6IFtdLCBqb2JPcHRpb25zOiB7fX1cbiAgICB9XG5cbiAgICBjb25zdCBsYXN0QXJnID0gYXJnc1thcmdzLmxlbmd0aCAtIDFdXG4gICAgY29uc3QgaXNPcHRpb25zQXJnID0gbGFzdEFyZyAmJiB0eXBlb2YgbGFzdEFyZyA9PT0gXCJvYmplY3RcIiAmJiAhQXJyYXkuaXNBcnJheShsYXN0QXJnKSAmJiBcImpvYk9wdGlvbnNcIiBpbiBsYXN0QXJnXG5cbiAgICBpZiAoaXNPcHRpb25zQXJnKSB7XG4gICAgICBjb25zdCB7am9iT3B0aW9uc30gPSAvKiogQHR5cGUge3tqb2JPcHRpb25zOiBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkJhY2tncm91bmRKb2JPcHRpb25zfX0gKi8gKGxhc3RBcmcpXG4gICAgICByZXR1cm4ge2pvYkFyZ3M6IGFyZ3Muc2xpY2UoMCwgLTEpLCBqb2JPcHRpb25zOiBqb2JPcHRpb25zIHx8IHt9fVxuICAgIH1cblxuICAgIHJldHVybiB7am9iQXJnczogYXJncywgam9iT3B0aW9uczoge319XG4gIH1cblxuICAvKipcbiAgICogT3ZlcnJpZGUgaW4gc3ViY2xhc3Nlcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHBlcmZvcm0oKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwicGVyZm9ybSBub3QgaW1wbGVtZW50ZWRcIilcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
declare const JsonSocket_base: typeof import("eventemitter3").EventEmitter;
|
|
2
|
+
export default class JsonSocket extends JsonSocket_base {
|
|
3
|
+
/**
|
|
4
|
+
* @param {import("net").Socket} socket - Socket instance.
|
|
5
|
+
*/
|
|
6
|
+
constructor(socket: import("net").Socket);
|
|
7
|
+
socket: import("net").Socket;
|
|
8
|
+
/** @type {string | undefined} */
|
|
9
|
+
workerId: string | undefined;
|
|
10
|
+
buffer: string;
|
|
11
|
+
/**
|
|
12
|
+
* @param {string} chunk - Data chunk.
|
|
13
|
+
* @returns {void}
|
|
14
|
+
*/
|
|
15
|
+
_onData(chunk: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* @param {unknown} message - Message to send.
|
|
18
|
+
* @returns {void}
|
|
19
|
+
*/
|
|
20
|
+
send(message: unknown): void;
|
|
21
|
+
/**
|
|
22
|
+
* @returns {void}
|
|
23
|
+
*/
|
|
24
|
+
close(): void;
|
|
25
|
+
}
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=json-socket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-socket.d.ts","sourceRoot":"","sources":["../../../src/background-jobs/json-socket.js"],"names":[],"mappings":";AAIA;IACE;;OAEG;IACH,oBAFW,OAAO,KAAK,EAAE,MAAM,EAY9B;IARC,6BAAoB;IACpB,iCAAiC;IACjC,UADW,MAAM,GAAG,SAAS,CACJ;IACzB,eAAgB;IAOlB;;;OAGG;IACH,eAHW,MAAM,GACJ,IAAI,CAqBhB;IAED;;;OAGG;IACH,cAHW,OAAO,GACL,IAAI,CAIhB;IAED;;OAEG;IACH,SAFa,IAAI,CAIhB;CACF"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import EventEmitter from "../utils/event-emitter.js";
|
|
3
|
+
export default class JsonSocket extends EventEmitter {
|
|
4
|
+
/**
|
|
5
|
+
* @param {import("net").Socket} socket - Socket instance.
|
|
6
|
+
*/
|
|
7
|
+
constructor(socket) {
|
|
8
|
+
super();
|
|
9
|
+
this.socket = socket;
|
|
10
|
+
/** @type {string | undefined} */
|
|
11
|
+
this.workerId = undefined;
|
|
12
|
+
this.buffer = "";
|
|
13
|
+
this.socket.setEncoding("utf8");
|
|
14
|
+
this.socket.on("data", (chunk) => this._onData(String(chunk)));
|
|
15
|
+
this.socket.on("close", () => this.emit("close"));
|
|
16
|
+
this.socket.on("error", (error) => this.emit("error", error));
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* @param {string} chunk - Data chunk.
|
|
20
|
+
* @returns {void}
|
|
21
|
+
*/
|
|
22
|
+
_onData(chunk) {
|
|
23
|
+
this.buffer += chunk;
|
|
24
|
+
while (true) {
|
|
25
|
+
const newlineIndex = this.buffer.indexOf("\n");
|
|
26
|
+
if (newlineIndex === -1)
|
|
27
|
+
break;
|
|
28
|
+
const line = this.buffer.slice(0, newlineIndex).trim();
|
|
29
|
+
this.buffer = this.buffer.slice(newlineIndex + 1);
|
|
30
|
+
if (!line)
|
|
31
|
+
continue;
|
|
32
|
+
try {
|
|
33
|
+
const message = JSON.parse(line);
|
|
34
|
+
this.emit("message", message);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
this.emit("error", error);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* @param {unknown} message - Message to send.
|
|
43
|
+
* @returns {void}
|
|
44
|
+
*/
|
|
45
|
+
send(message) {
|
|
46
|
+
this.socket.write(`${JSON.stringify(message)}\n`);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* @returns {void}
|
|
50
|
+
*/
|
|
51
|
+
close() {
|
|
52
|
+
this.socket.end();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbi1zb2NrZXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYmFja2dyb3VuZC1qb2JzL2pzb24tc29ja2V0LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLFlBQVksTUFBTSwyQkFBMkIsQ0FBQTtBQUVwRCxNQUFNLENBQUMsT0FBTyxPQUFPLFVBQVcsU0FBUSxZQUFZO0lBQ2xEOztPQUVHO0lBQ0gsWUFBWSxNQUFNO1FBQ2hCLEtBQUssRUFBRSxDQUFBO1FBQ1AsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUE7UUFDcEIsaUNBQWlDO1FBQ2pDLElBQUksQ0FBQyxRQUFRLEdBQUcsU0FBUyxDQUFBO1FBQ3pCLElBQUksQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFBO1FBQ2hCLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQy9CLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQzlELElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUE7UUFDakQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFBO0lBQy9ELENBQUM7SUFFRDs7O09BR0c7SUFDSCxPQUFPLENBQUMsS0FBSztRQUNYLElBQUksQ0FBQyxNQUFNLElBQUksS0FBSyxDQUFBO1FBRXBCLE9BQU8sSUFBSSxFQUFFLENBQUM7WUFDWixNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQTtZQUM5QyxJQUFJLFlBQVksS0FBSyxDQUFDLENBQUM7Z0JBQUUsTUFBSztZQUU5QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUE7WUFDdEQsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDLENBQUE7WUFFakQsSUFBSSxDQUFDLElBQUk7Z0JBQUUsU0FBUTtZQUVuQixJQUFJLENBQUM7Z0JBQ0gsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQTtnQkFDaEMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUE7WUFDL0IsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2YsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUE7WUFDM0IsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsSUFBSSxDQUFDLE9BQU87UUFDVixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQ25ELENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUs7UUFDSCxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFBO0lBQ25CLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgRXZlbnRFbWl0dGVyIGZyb20gXCIuLi91dGlscy9ldmVudC1lbWl0dGVyLmpzXCJcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSnNvblNvY2tldCBleHRlbmRzIEV2ZW50RW1pdHRlciB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIm5ldFwiKS5Tb2NrZXR9IHNvY2tldCAtIFNvY2tldCBpbnN0YW5jZS5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHNvY2tldCkge1xuICAgIHN1cGVyKClcbiAgICB0aGlzLnNvY2tldCA9IHNvY2tldFxuICAgIC8qKiBAdHlwZSB7c3RyaW5nIHwgdW5kZWZpbmVkfSAqL1xuICAgIHRoaXMud29ya2VySWQgPSB1bmRlZmluZWRcbiAgICB0aGlzLmJ1ZmZlciA9IFwiXCJcbiAgICB0aGlzLnNvY2tldC5zZXRFbmNvZGluZyhcInV0ZjhcIilcbiAgICB0aGlzLnNvY2tldC5vbihcImRhdGFcIiwgKGNodW5rKSA9PiB0aGlzLl9vbkRhdGEoU3RyaW5nKGNodW5rKSkpXG4gICAgdGhpcy5zb2NrZXQub24oXCJjbG9zZVwiLCAoKSA9PiB0aGlzLmVtaXQoXCJjbG9zZVwiKSlcbiAgICB0aGlzLnNvY2tldC5vbihcImVycm9yXCIsIChlcnJvcikgPT4gdGhpcy5lbWl0KFwiZXJyb3JcIiwgZXJyb3IpKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjaHVuayAtIERhdGEgY2h1bmsuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgX29uRGF0YShjaHVuaykge1xuICAgIHRoaXMuYnVmZmVyICs9IGNodW5rXG5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgY29uc3QgbmV3bGluZUluZGV4ID0gdGhpcy5idWZmZXIuaW5kZXhPZihcIlxcblwiKVxuICAgICAgaWYgKG5ld2xpbmVJbmRleCA9PT0gLTEpIGJyZWFrXG5cbiAgICAgIGNvbnN0IGxpbmUgPSB0aGlzLmJ1ZmZlci5zbGljZSgwLCBuZXdsaW5lSW5kZXgpLnRyaW0oKVxuICAgICAgdGhpcy5idWZmZXIgPSB0aGlzLmJ1ZmZlci5zbGljZShuZXdsaW5lSW5kZXggKyAxKVxuXG4gICAgICBpZiAoIWxpbmUpIGNvbnRpbnVlXG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBKU09OLnBhcnNlKGxpbmUpXG4gICAgICAgIHRoaXMuZW1pdChcIm1lc3NhZ2VcIiwgbWVzc2FnZSlcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHRoaXMuZW1pdChcImVycm9yXCIsIGVycm9yKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3Vua25vd259IG1lc3NhZ2UgLSBNZXNzYWdlIHRvIHNlbmQuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgc2VuZChtZXNzYWdlKSB7XG4gICAgdGhpcy5zb2NrZXQud3JpdGUoYCR7SlNPTi5zdHJpbmdpZnkobWVzc2FnZSl9XFxuYClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGNsb3NlKCkge1xuICAgIHRoaXMuc29ja2V0LmVuZCgpXG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export default class BackgroundJobsMain {
|
|
2
|
+
/**
|
|
3
|
+
* @param {object} args - Options.
|
|
4
|
+
* @param {import("../configuration.js").default} args.configuration - Configuration.
|
|
5
|
+
* @param {string} [args.host] - Hostname.
|
|
6
|
+
* @param {number} [args.port] - Port.
|
|
7
|
+
*/
|
|
8
|
+
constructor({ configuration, host, port }: {
|
|
9
|
+
configuration: import("../configuration.js").default;
|
|
10
|
+
host?: string;
|
|
11
|
+
port?: number;
|
|
12
|
+
});
|
|
13
|
+
configuration: import("../configuration.js").default;
|
|
14
|
+
host: string;
|
|
15
|
+
port: number;
|
|
16
|
+
store: BackgroundJobsStore;
|
|
17
|
+
logger: Logger;
|
|
18
|
+
/** @type {Set<JsonSocket>} */
|
|
19
|
+
workers: Set<JsonSocket>;
|
|
20
|
+
/** @type {Set<JsonSocket>} */
|
|
21
|
+
readyWorkers: Set<JsonSocket>;
|
|
22
|
+
_dispatching: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* @returns {Promise<void>} - Resolves when listening.
|
|
25
|
+
*/
|
|
26
|
+
start(): Promise<void>;
|
|
27
|
+
server: net.Server;
|
|
28
|
+
_dispatchTimer: NodeJS.Timeout;
|
|
29
|
+
_orphanTimer: NodeJS.Timeout;
|
|
30
|
+
/**
|
|
31
|
+
* @returns {Promise<void>} - Resolves when closed.
|
|
32
|
+
*/
|
|
33
|
+
stop(): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* @returns {number} - Bound port.
|
|
36
|
+
*/
|
|
37
|
+
getPort(): number;
|
|
38
|
+
/**
|
|
39
|
+
* @param {import("net").Socket} socket - Socket.
|
|
40
|
+
* @returns {void}
|
|
41
|
+
*/
|
|
42
|
+
_handleConnection(socket: import("net").Socket): void;
|
|
43
|
+
_handleEnqueue({ jsonSocket, message }: {
|
|
44
|
+
jsonSocket: any;
|
|
45
|
+
message: any;
|
|
46
|
+
}): Promise<void>;
|
|
47
|
+
_handleJobComplete({ jsonSocket, message }: {
|
|
48
|
+
jsonSocket: any;
|
|
49
|
+
message: any;
|
|
50
|
+
}): Promise<void>;
|
|
51
|
+
_handleJobFailed({ jsonSocket, message }: {
|
|
52
|
+
jsonSocket: any;
|
|
53
|
+
message: any;
|
|
54
|
+
}): Promise<void>;
|
|
55
|
+
_dispatch(): Promise<void>;
|
|
56
|
+
_sweepOrphans(): Promise<void>;
|
|
57
|
+
}
|
|
58
|
+
import BackgroundJobsStore from "./store.js";
|
|
59
|
+
import { Logger } from "../logger.js";
|
|
60
|
+
import JsonSocket from "./json-socket.js";
|
|
61
|
+
import net from "net";
|
|
62
|
+
//# sourceMappingURL=main.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/background-jobs/main.js"],"names":[],"mappings":"AAOA;IACE;;;;;OAKG;IACH,2CAJG;QAAoD,aAAa,EAAzD,OAAO,qBAAqB,EAAE,OAAO;QACvB,IAAI,GAAlB,MAAM;QACQ,IAAI,GAAlB,MAAM;KAChB,EAaA;IAXC,qDAAkC;IAElC,aAA+B;IAC/B,aAAyD;IACzD,2BAAoG;IACpG,eAA8B;IAC9B,8BAA8B;IAC9B,SADW,GAAG,CAAC,UAAU,CAAC,CACF;IACxB,8BAA8B;IAC9B,cADW,GAAG,CAAC,UAAU,CAAC,CACG;IAC7B,sBAAyB;IAG3B;;OAEG;IACH,SAFa,OAAO,CAAC,IAAI,CAAC,CAyBzB;IAnBC,mBAA0E;IAY1E,+BAEQ;IAER,6BAES;IAGX;;OAEG;IACH,QAFa,OAAO,CAAC,IAAI,CAAC,CAazB;IAED;;OAEG;IACH,WAFa,MAAM,CAIlB;IAED;;;OAGG;IACH,0BAHW,OAAO,KAAK,EAAE,MAAM,GAClB,IAAI,CAqDhB;IAED;;;sBAcC;IAED;;;sBAYC;IAED;;;sBAcC;IAED,2BAyCC;IAED,+BAUC;CACF;gCAxO+B,YAAY;uBACvB,cAAc;uBAFZ,kBAAkB;gBADzB,KAAK"}
|