nmtjs 0.16.0 → 0.17.0-beta.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.
- package/LICENSE.md +1 -1
- package/README.md +41 -1
- package/dist/index.d.ts +22 -121
- package/dist/index.js +24 -53
- package/dist/index.js.map +1 -1
- package/package.json +11 -63
- package/src/index.ts +71 -91
- package/bin/cli.js +0 -2
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +0 -137
- package/dist/cli.js.map +0 -1
- package/dist/codegen.d.ts +0 -5
- package/dist/codegen.js +0 -18
- package/dist/codegen.js.map +0 -1
- package/dist/config.d.ts +0 -47
- package/dist/config.js +0 -16
- package/dist/config.js.map +0 -1
- package/dist/entrypoints/cli.d.ts +0 -1
- package/dist/entrypoints/cli.js +0 -12
- package/dist/entrypoints/cli.js.map +0 -1
- package/dist/entrypoints/main.d.ts +0 -5
- package/dist/entrypoints/main.js +0 -248
- package/dist/entrypoints/main.js.map +0 -1
- package/dist/entrypoints/thread.d.ts +0 -16
- package/dist/entrypoints/thread.js +0 -182
- package/dist/entrypoints/thread.js.map +0 -1
- package/dist/entrypoints/worker.d.ts +0 -9
- package/dist/entrypoints/worker.js +0 -143
- package/dist/entrypoints/worker.js.map +0 -1
- package/dist/resolver.d.ts +0 -2
- package/dist/resolver.js +0 -7
- package/dist/resolver.js.map +0 -1
- package/dist/runtime/application/index.d.ts +0 -1
- package/dist/runtime/application/index.js +0 -2
- package/dist/runtime/application/index.js.map +0 -1
- package/dist/runtime/constants.d.ts +0 -8
- package/dist/runtime/constants.js +0 -5
- package/dist/runtime/constants.js.map +0 -1
- package/dist/runtime/enums.d.ts +0 -10
- package/dist/runtime/enums.js +0 -13
- package/dist/runtime/enums.js.map +0 -1
- package/dist/runtime/hooks.d.ts +0 -1
- package/dist/runtime/hooks.js +0 -2
- package/dist/runtime/hooks.js.map +0 -1
- package/dist/runtime/index.d.ts +0 -28
- package/dist/runtime/index.js +0 -29
- package/dist/runtime/index.js.map +0 -1
- package/dist/runtime/injectables.d.ts +0 -28
- package/dist/runtime/injectables.js +0 -24
- package/dist/runtime/injectables.js.map +0 -1
- package/dist/runtime/jobs/job.d.ts +0 -146
- package/dist/runtime/jobs/job.js +0 -89
- package/dist/runtime/jobs/job.js.map +0 -1
- package/dist/runtime/jobs/manager.d.ts +0 -131
- package/dist/runtime/jobs/manager.js +0 -309
- package/dist/runtime/jobs/manager.js.map +0 -1
- package/dist/runtime/jobs/router.d.ts +0 -296
- package/dist/runtime/jobs/router.js +0 -458
- package/dist/runtime/jobs/router.js.map +0 -1
- package/dist/runtime/jobs/runner.d.ts +0 -103
- package/dist/runtime/jobs/runner.js +0 -425
- package/dist/runtime/jobs/runner.js.map +0 -1
- package/dist/runtime/jobs/step.d.ts +0 -26
- package/dist/runtime/jobs/step.js +0 -18
- package/dist/runtime/jobs/step.js.map +0 -1
- package/dist/runtime/jobs/types.d.ts +0 -86
- package/dist/runtime/jobs/types.js +0 -5
- package/dist/runtime/jobs/types.js.map +0 -1
- package/dist/runtime/metrics/metric.d.ts +0 -8
- package/dist/runtime/metrics/metric.js +0 -11
- package/dist/runtime/metrics/metric.js.map +0 -1
- package/dist/runtime/metrics/registry.d.ts +0 -3
- package/dist/runtime/metrics/registry.js +0 -5
- package/dist/runtime/metrics/registry.js.map +0 -1
- package/dist/runtime/metrics/server.d.ts +0 -7
- package/dist/runtime/metrics/server.js +0 -53
- package/dist/runtime/metrics/server.js.map +0 -1
- package/dist/runtime/plugin.d.ts +0 -2
- package/dist/runtime/plugin.js +0 -2
- package/dist/runtime/plugin.js.map +0 -1
- package/dist/runtime/runtime.d.ts +0 -27
- package/dist/runtime/runtime.js +0 -77
- package/dist/runtime/runtime.js.map +0 -1
- package/dist/runtime/scheduler/index.d.ts +0 -22
- package/dist/runtime/scheduler/index.js +0 -20
- package/dist/runtime/scheduler/index.js.map +0 -1
- package/dist/runtime/server/applications.d.ts +0 -91
- package/dist/runtime/server/applications.js +0 -171
- package/dist/runtime/server/applications.js.map +0 -1
- package/dist/runtime/server/config.d.ts +0 -148
- package/dist/runtime/server/config.js +0 -33
- package/dist/runtime/server/config.js.map +0 -1
- package/dist/runtime/server/environment.d.ts +0 -43
- package/dist/runtime/server/environment.js +0 -33
- package/dist/runtime/server/environment.js.map +0 -1
- package/dist/runtime/server/error-policy.d.ts +0 -62
- package/dist/runtime/server/error-policy.js +0 -73
- package/dist/runtime/server/error-policy.js.map +0 -1
- package/dist/runtime/server/hmr-coordinator.d.ts +0 -37
- package/dist/runtime/server/hmr-coordinator.js +0 -94
- package/dist/runtime/server/hmr-coordinator.js.map +0 -1
- package/dist/runtime/server/jobs.d.ts +0 -54
- package/dist/runtime/server/jobs.js +0 -176
- package/dist/runtime/server/jobs.js.map +0 -1
- package/dist/runtime/server/lifecycle.d.ts +0 -85
- package/dist/runtime/server/lifecycle.js +0 -177
- package/dist/runtime/server/lifecycle.js.map +0 -1
- package/dist/runtime/server/managed-worker.d.ts +0 -158
- package/dist/runtime/server/managed-worker.js +0 -420
- package/dist/runtime/server/managed-worker.js.map +0 -1
- package/dist/runtime/server/pool-manager.d.ts +0 -85
- package/dist/runtime/server/pool-manager.js +0 -129
- package/dist/runtime/server/pool-manager.js.map +0 -1
- package/dist/runtime/server/proxy.d.ts +0 -21
- package/dist/runtime/server/proxy.js +0 -76
- package/dist/runtime/server/proxy.js.map +0 -1
- package/dist/runtime/server/server.d.ts +0 -60
- package/dist/runtime/server/server.js +0 -163
- package/dist/runtime/server/server.js.map +0 -1
- package/dist/runtime/server/types.d.ts +0 -31
- package/dist/runtime/server/types.js +0 -2
- package/dist/runtime/server/types.js.map +0 -1
- package/dist/runtime/server/worker-pool.d.ts +0 -121
- package/dist/runtime/server/worker-pool.js +0 -171
- package/dist/runtime/server/worker-pool.js.map +0 -1
- package/dist/runtime/store/index.d.ts +0 -3
- package/dist/runtime/store/index.js +0 -23
- package/dist/runtime/store/index.js.map +0 -1
- package/dist/runtime/subscription/manager.d.ts +0 -49
- package/dist/runtime/subscription/manager.js +0 -170
- package/dist/runtime/subscription/manager.js.map +0 -1
- package/dist/runtime/subscription/redis.d.ts +0 -18
- package/dist/runtime/subscription/redis.js +0 -120
- package/dist/runtime/subscription/redis.js.map +0 -1
- package/dist/runtime/types.d.ts +0 -95
- package/dist/runtime/types.js +0 -2
- package/dist/runtime/types.js.map +0 -1
- package/dist/runtime/workers/application.d.ts +0 -29
- package/dist/runtime/workers/application.js +0 -77
- package/dist/runtime/workers/application.js.map +0 -1
- package/dist/runtime/workers/base.d.ts +0 -16
- package/dist/runtime/workers/base.js +0 -46
- package/dist/runtime/workers/base.js.map +0 -1
- package/dist/runtime/workers/cli.d.ts +0 -1
- package/dist/runtime/workers/cli.js +0 -2
- package/dist/runtime/workers/cli.js.map +0 -1
- package/dist/runtime/workers/job.d.ts +0 -20
- package/dist/runtime/workers/job.js +0 -170
- package/dist/runtime/workers/job.js.map +0 -1
- package/dist/vite/builder.d.ts +0 -5
- package/dist/vite/builder.js +0 -79
- package/dist/vite/builder.js.map +0 -1
- package/dist/vite/config.d.ts +0 -28
- package/dist/vite/config.js +0 -22
- package/dist/vite/config.js.map +0 -1
- package/dist/vite/plugins.d.ts +0 -2
- package/dist/vite/plugins.js +0 -43
- package/dist/vite/plugins.js.map +0 -1
- package/dist/vite/runners/worker.d.ts +0 -3
- package/dist/vite/runners/worker.js +0 -34
- package/dist/vite/runners/worker.js.map +0 -1
- package/dist/vite/server.d.ts +0 -3
- package/dist/vite/server.js +0 -36
- package/dist/vite/server.js.map +0 -1
- package/dist/vite/servers/main.d.ts +0 -8
- package/dist/vite/servers/main.js +0 -24
- package/dist/vite/servers/main.js.map +0 -1
- package/dist/vite/servers/worker.d.ts +0 -13
- package/dist/vite/servers/worker.js +0 -124
- package/dist/vite/servers/worker.js.map +0 -1
- package/src/cli.ts +0 -162
- package/src/codegen.ts +0 -30
- package/src/config.ts +0 -69
- package/src/entrypoints/cli.ts +0 -13
- package/src/entrypoints/main.ts +0 -317
- package/src/entrypoints/thread.ts +0 -223
- package/src/entrypoints/worker.ts +0 -174
- package/src/resolver.ts +0 -7
- package/src/runtime/application/index.ts +0 -1
- package/src/runtime/constants.ts +0 -13
- package/src/runtime/enums.ts +0 -12
- package/src/runtime/hooks.ts +0 -1
- package/src/runtime/index.ts +0 -29
- package/src/runtime/injectables.ts +0 -72
- package/src/runtime/jobs/job.ts +0 -467
- package/src/runtime/jobs/manager.ts +0 -454
- package/src/runtime/jobs/router.ts +0 -967
- package/src/runtime/jobs/runner.ts +0 -583
- package/src/runtime/jobs/step.ts +0 -66
- package/src/runtime/jobs/types.ts +0 -116
- package/src/runtime/metrics/metric.ts +0 -18
- package/src/runtime/metrics/registry.ts +0 -11
- package/src/runtime/metrics/server.ts +0 -69
- package/src/runtime/plugin.ts +0 -2
- package/src/runtime/runtime.ts +0 -103
- package/src/runtime/scheduler/index.ts +0 -39
- package/src/runtime/server/applications.ts +0 -264
- package/src/runtime/server/config.ts +0 -199
- package/src/runtime/server/environment.ts +0 -71
- package/src/runtime/server/error-policy.ts +0 -132
- package/src/runtime/server/hmr-coordinator.ts +0 -116
- package/src/runtime/server/jobs.ts +0 -266
- package/src/runtime/server/lifecycle.ts +0 -234
- package/src/runtime/server/managed-worker.ts +0 -546
- package/src/runtime/server/pool-manager.ts +0 -187
- package/src/runtime/server/proxy.ts +0 -119
- package/src/runtime/server/server.ts +0 -218
- package/src/runtime/server/types.ts +0 -32
- package/src/runtime/server/worker-pool.ts +0 -275
- package/src/runtime/store/index.ts +0 -30
- package/src/runtime/subscription/manager.ts +0 -310
- package/src/runtime/subscription/redis.ts +0 -157
- package/src/runtime/types.ts +0 -84
- package/src/runtime/workers/application.ts +0 -133
- package/src/runtime/workers/base.ts +0 -71
- package/src/runtime/workers/cli.ts +0 -0
- package/src/runtime/workers/job.ts +0 -142
- package/src/vite/builder.ts +0 -94
- package/src/vite/config.ts +0 -45
- package/src/vite/plugins.ts +0 -53
- package/src/vite/runners/worker.ts +0 -55
- package/src/vite/server.ts +0 -55
- package/src/vite/servers/main.ts +0 -41
- package/src/vite/servers/worker.ts +0 -177
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import type { MaybePromise, TSError } from '@nmtjs/common';
|
|
2
|
-
import type { Dependencies, DependencyContext } from '@nmtjs/core';
|
|
3
|
-
import type { t } from '@nmtjs/type';
|
|
4
|
-
import type { AnyObjectLikeType, ObjectType } from '@nmtjs/type/object';
|
|
5
|
-
import type { AnyJobStep, JobStep } from './step.ts';
|
|
6
|
-
import { kJobKey } from '../constants.ts';
|
|
7
|
-
type DefaultObjectType = ObjectType<{}>;
|
|
8
|
-
type DefaultResultType = Record<string, any>;
|
|
9
|
-
type UnionToIntersection<T> = (T extends unknown ? (value: T) => void : never) extends (value: infer R) => void ? R : never;
|
|
10
|
-
type StepOutput<Step extends AnyJobStep> = Step extends JobStep<any, infer Output, any, any, any> ? t.infer.decode.output<Output extends undefined ? DefaultObjectType : Output> : {};
|
|
11
|
-
type GroupOutput<Steps extends readonly AnyJobStep[]> = UnionToIntersection<StepOutput<Steps[number]>>;
|
|
12
|
-
type EnsureStepInputSatisfied<CurrentResult, StepInput extends AnyObjectLikeType> = CurrentResult extends t.infer.decode.output<StepInput> ? unknown : TSError<'Accumulated job result does not satisfy current step input:', CurrentResult>;
|
|
13
|
-
type EnsureStepDataSatisfied<CurrentData, StepData> = CurrentData extends StepData ? unknown : TSError<'Job data does not satisfy step data type:', CurrentData>;
|
|
14
|
-
type ValidatedParallelStep<Step extends AnyJobStep, CurrentResult, CurrentData> = Step extends JobStep<infer StepInput, any, any, any, infer StepData> ? Step & EnsureStepInputSatisfied<CurrentResult, StepInput> & EnsureStepDataSatisfied<CurrentData, StepData> : never;
|
|
15
|
-
type ValidatedParallelSteps<Steps extends readonly AnyJobStep[], CurrentResult, CurrentData> = {
|
|
16
|
-
[K in keyof Steps]: ValidatedParallelStep<Steps[K], CurrentResult, CurrentData>;
|
|
17
|
-
};
|
|
18
|
-
export type AnyJobOptions = JobOptions<string, any, any, any, any, any>;
|
|
19
|
-
export interface AnyJob {
|
|
20
|
-
_: {
|
|
21
|
-
data: any;
|
|
22
|
-
result: any;
|
|
23
|
-
input: any;
|
|
24
|
-
output: any;
|
|
25
|
-
progress: any;
|
|
26
|
-
};
|
|
27
|
-
[kJobKey]: true;
|
|
28
|
-
options: AnyJobOptions;
|
|
29
|
-
jobSteps: readonly AnyJobStep[];
|
|
30
|
-
parallelGroups: Map<number, number>;
|
|
31
|
-
parallelGroupByStepIndex: Map<number, number>;
|
|
32
|
-
conditions: Map<number, JobCondition<any, any, any, any>>;
|
|
33
|
-
name: string;
|
|
34
|
-
dependencies: Dependencies;
|
|
35
|
-
input: AnyObjectLikeType;
|
|
36
|
-
output: AnyObjectLikeType;
|
|
37
|
-
progress: AnyObjectLikeType;
|
|
38
|
-
afterEachHandler?: JobAfterEachHandler<any, any, any, any, any>;
|
|
39
|
-
beforeEachHandler?: JobBeforeEachHandler<any, any, any, any, any>;
|
|
40
|
-
onErrorHandler?: JobOnErrorHandler<any, any, any, any, any>;
|
|
41
|
-
returnHandler?: JobReturnHandler<any, any, any, any, any, any>;
|
|
42
|
-
}
|
|
43
|
-
export type JobBackoffOptions = {
|
|
44
|
-
type: 'fixed' | 'exponential';
|
|
45
|
-
delay: number;
|
|
46
|
-
jitter?: number;
|
|
47
|
-
};
|
|
48
|
-
export type JobCondition<Deps extends Dependencies = {}, Result extends DefaultResultType = {}, Data = any, Input extends AnyObjectLikeType = AnyObjectLikeType, Progress extends AnyObjectLikeType = AnyObjectLikeType> = (params: {
|
|
49
|
-
context: DependencyContext<Deps>;
|
|
50
|
-
data: Data;
|
|
51
|
-
input: t.infer.decode.output<Input>;
|
|
52
|
-
result: Result;
|
|
53
|
-
progress: t.infer.decode.output<Progress>;
|
|
54
|
-
}) => MaybePromise<boolean>;
|
|
55
|
-
export type JobReturnHandler<Deps extends Dependencies, Result extends DefaultResultType, Input extends AnyObjectLikeType, Output extends AnyObjectLikeType, Data, Progress extends AnyObjectLikeType = AnyObjectLikeType> = (params: {
|
|
56
|
-
context: DependencyContext<Deps>;
|
|
57
|
-
data: Data;
|
|
58
|
-
input: t.infer.decode.output<Input>;
|
|
59
|
-
result: Result;
|
|
60
|
-
progress: t.infer.decode.output<Progress>;
|
|
61
|
-
}) => MaybePromise<t.infer.encode.input<Output>>;
|
|
62
|
-
export type JobDataHandler<Deps extends Dependencies, Input extends AnyObjectLikeType, Data, Progress extends AnyObjectLikeType = AnyObjectLikeType> = (ctx: DependencyContext<Deps>, input: t.infer.decode.output<Input>, progress: t.infer.decode.output<Progress>) => MaybePromise<Data>;
|
|
63
|
-
export type JobAfterEachHandler<Deps extends Dependencies, Result extends DefaultResultType, Input extends AnyObjectLikeType, Data, Progress extends AnyObjectLikeType = AnyObjectLikeType> = (params: {
|
|
64
|
-
context: DependencyContext<Deps>;
|
|
65
|
-
data: Data;
|
|
66
|
-
input: t.infer.decode.output<Input>;
|
|
67
|
-
result: Result;
|
|
68
|
-
progress: t.infer.decode.output<Progress>;
|
|
69
|
-
step: AnyJobStep;
|
|
70
|
-
stepIndex: number;
|
|
71
|
-
}) => MaybePromise<void>;
|
|
72
|
-
export type JobBeforeEachHandler<Deps extends Dependencies, Result extends DefaultResultType, Input extends AnyObjectLikeType, Data, Progress extends AnyObjectLikeType = AnyObjectLikeType> = (params: {
|
|
73
|
-
context: DependencyContext<Deps>;
|
|
74
|
-
data: Data;
|
|
75
|
-
input: t.infer.decode.output<Input>;
|
|
76
|
-
result: Result;
|
|
77
|
-
progress: t.infer.decode.output<Progress>;
|
|
78
|
-
step: AnyJobStep;
|
|
79
|
-
stepIndex: number;
|
|
80
|
-
}) => MaybePromise<void>;
|
|
81
|
-
export type JobOnErrorHandler<Deps extends Dependencies, Result extends DefaultResultType, Input extends AnyObjectLikeType, Data, Progress extends AnyObjectLikeType = AnyObjectLikeType> = (params: {
|
|
82
|
-
context: DependencyContext<Deps>;
|
|
83
|
-
data: Data;
|
|
84
|
-
input: t.infer.decode.output<Input>;
|
|
85
|
-
result: Result;
|
|
86
|
-
progress: t.infer.decode.output<Progress>;
|
|
87
|
-
step: AnyJobStep;
|
|
88
|
-
stepIndex: number;
|
|
89
|
-
error: unknown;
|
|
90
|
-
}) => MaybePromise<boolean | void>;
|
|
91
|
-
export interface JobOptions<Name extends string = string, Input extends AnyObjectLikeType = AnyObjectLikeType, Output extends AnyObjectLikeType = AnyObjectLikeType, Progress extends AnyObjectLikeType = DefaultObjectType, Deps extends Dependencies = {}, Data = any> {
|
|
92
|
-
name: Name;
|
|
93
|
-
pool: string;
|
|
94
|
-
input: Input;
|
|
95
|
-
output: Output;
|
|
96
|
-
progress?: Progress;
|
|
97
|
-
concurrency?: number;
|
|
98
|
-
timeout?: number;
|
|
99
|
-
dependencies?: Deps;
|
|
100
|
-
data?: JobDataHandler<Deps, Input, Data, Progress>;
|
|
101
|
-
attempts?: number;
|
|
102
|
-
backoff?: JobBackoffOptions;
|
|
103
|
-
oneoff?: boolean;
|
|
104
|
-
}
|
|
105
|
-
export declare class Job<in out Name extends string = string, in out Deps extends Dependencies = {}, in out Data = any, in out Input extends AnyObjectLikeType = DefaultObjectType, in out Output extends AnyObjectLikeType = DefaultObjectType, in out Progress extends AnyObjectLikeType = DefaultObjectType, out JobSteps extends [...AnyJobStep[]] = [], in out Result extends DefaultResultType = {}, out Return extends boolean = false> implements AnyJob {
|
|
106
|
-
options: JobOptions<Name, Input, Output, Progress, Deps, Data>;
|
|
107
|
-
stack?: string | undefined;
|
|
108
|
-
_: {
|
|
109
|
-
data: Data;
|
|
110
|
-
result: Result & t.infer.decode.output<Input>;
|
|
111
|
-
input: t.infer.decode.output<Input>;
|
|
112
|
-
output: t.infer.decode.output<Output>;
|
|
113
|
-
progress: t.infer.decode.output<Progress>;
|
|
114
|
-
};
|
|
115
|
-
[kJobKey]: true;
|
|
116
|
-
protected _jobSteps: JobSteps;
|
|
117
|
-
parallelGroups: Map<number, number>;
|
|
118
|
-
parallelGroupByStepIndex: Map<number, number>;
|
|
119
|
-
conditions: Map<number, JobCondition<any, any, any, any, any>>;
|
|
120
|
-
returnHandler?: JobReturnHandler<Deps, this['_']['result'], Input, Output, Data, Progress>;
|
|
121
|
-
afterEachHandler?: JobAfterEachHandler<Deps, this['_']['result'], Input, Data, Progress>;
|
|
122
|
-
beforeEachHandler?: JobBeforeEachHandler<Deps, this['_']['result'], Input, Data, Progress>;
|
|
123
|
-
onErrorHandler?: JobOnErrorHandler<Deps, this['_']['result'], Input, Data, Progress>;
|
|
124
|
-
constructor(options: JobOptions<Name, Input, Output, Progress, Deps, Data>, stack?: string | undefined);
|
|
125
|
-
get name(): Name;
|
|
126
|
-
get jobSteps(): JobSteps;
|
|
127
|
-
get dependencies(): Deps;
|
|
128
|
-
get input(): Input;
|
|
129
|
-
get output(): Output;
|
|
130
|
-
get progress(): Progress;
|
|
131
|
-
step<StepInput extends AnyObjectLikeType, StepOutput extends AnyObjectLikeType, StepDeps extends Dependencies, Condition extends JobCondition<Deps, Result, this['_']['data'], Input> | undefined>(...[step, condition]: Return extends false ? [
|
|
132
|
-
step: JobStep<StepInput, StepOutput, StepDeps, any, this['_']['data']> & EnsureStepInputSatisfied<this['_']['result'], StepInput>,
|
|
133
|
-
condition?: Condition
|
|
134
|
-
] : [TSError<'Job has already has return statement'>]): Job<Name, Deps, Data, Input, Output, Progress, [...JobSteps, JobStep<StepInput, StepOutput, StepDeps, any, any>], Result & (undefined extends Condition ? t.infer.decode.output<StepOutput extends undefined ? DefaultObjectType : StepOutput> : Partial<t.infer.decode.output<StepOutput extends undefined ? DefaultObjectType : StepOutput>>)>;
|
|
135
|
-
steps<const GroupSteps extends [AnyJobStep, AnyJobStep, ...AnyJobStep[]]>(...steps: Return extends false ? GroupSteps & ValidatedParallelSteps<GroupSteps, this['_']['result'], this['_']['data']> : [TSError<'Job has already has return statement'>]): Job<Name, Deps, Data, Input, Output, Progress, [...JobSteps, ...GroupSteps], Result & GroupOutput<GroupSteps>>;
|
|
136
|
-
return(...[handler]: Return extends false ? Result extends t.infer.encode.input<Output> ? [
|
|
137
|
-
JobReturnHandler<Deps, this['_']['result'], Input, Output, Data, Progress>?
|
|
138
|
-
] : [
|
|
139
|
-
JobReturnHandler<Deps, this['_']['result'], Input, Output, Data, Progress>
|
|
140
|
-
] : [TSError<'Job already has a return statement'>]): Job<Name, Deps, Data, Input, Output, Progress, JobSteps, Result, true>;
|
|
141
|
-
afterEach(handler: Return extends true ? JobAfterEachHandler<Deps, this['_']['result'], Input, Data, Progress> : TSError<'Job must have a return statement to use afterEach'>): this;
|
|
142
|
-
beforeEach(handler: Return extends true ? JobBeforeEachHandler<Deps, this['_']['result'], Input, Data, Progress> : TSError<'Job must have a return statement to use beforeEach'>): this;
|
|
143
|
-
onError(handler: Return extends true ? JobOnErrorHandler<Deps, this['_']['result'], Input, Data, Progress> : TSError<'Job must have a return statement to use onError'>): this;
|
|
144
|
-
}
|
|
145
|
-
export declare function createJob<Name extends string, Input extends AnyObjectLikeType, Output extends AnyObjectLikeType, Deps extends Dependencies = {}, Data = any, Progress extends AnyObjectLikeType = DefaultObjectType>(options: JobOptions<Name, Input, Output, Progress, Deps, Data>): Job<Name, Deps, Data, Input, Output, Progress, [], {}, false>;
|
|
146
|
-
export {};
|
package/dist/runtime/jobs/job.js
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { tryCaptureStackTrace } from '@nmtjs/common';
|
|
2
|
-
import { kJobKey } from '../constants.js';
|
|
3
|
-
import { isJobStep } from './step.js';
|
|
4
|
-
export class Job {
|
|
5
|
-
options;
|
|
6
|
-
stack;
|
|
7
|
-
_;
|
|
8
|
-
[kJobKey] = true;
|
|
9
|
-
_jobSteps = [];
|
|
10
|
-
parallelGroups = new Map();
|
|
11
|
-
parallelGroupByStepIndex = new Map();
|
|
12
|
-
conditions = new Map();
|
|
13
|
-
returnHandler;
|
|
14
|
-
afterEachHandler;
|
|
15
|
-
beforeEachHandler;
|
|
16
|
-
onErrorHandler;
|
|
17
|
-
constructor(options, stack) {
|
|
18
|
-
this.options = options;
|
|
19
|
-
this.stack = stack;
|
|
20
|
-
}
|
|
21
|
-
get name() {
|
|
22
|
-
return this.options.name;
|
|
23
|
-
}
|
|
24
|
-
get jobSteps() {
|
|
25
|
-
return this._jobSteps;
|
|
26
|
-
}
|
|
27
|
-
get dependencies() {
|
|
28
|
-
return this.options.dependencies ?? {};
|
|
29
|
-
}
|
|
30
|
-
get input() {
|
|
31
|
-
return this.options.input;
|
|
32
|
-
}
|
|
33
|
-
get output() {
|
|
34
|
-
return this.options.output;
|
|
35
|
-
}
|
|
36
|
-
get progress() {
|
|
37
|
-
return this.options.progress;
|
|
38
|
-
}
|
|
39
|
-
step(...[step, condition]) {
|
|
40
|
-
if (!isJobStep(step))
|
|
41
|
-
throw new Error('Invalid job step object');
|
|
42
|
-
const length = this._jobSteps.push(step);
|
|
43
|
-
if (condition)
|
|
44
|
-
this.conditions.set(length - 1, condition);
|
|
45
|
-
return this;
|
|
46
|
-
}
|
|
47
|
-
steps(...steps) {
|
|
48
|
-
const validated = [];
|
|
49
|
-
for (const step of steps) {
|
|
50
|
-
if (!isJobStep(step))
|
|
51
|
-
throw new Error('Invalid job step object');
|
|
52
|
-
validated.push(step);
|
|
53
|
-
}
|
|
54
|
-
const start = this._jobSteps.length;
|
|
55
|
-
this._jobSteps.push(...validated);
|
|
56
|
-
const end = this._jobSteps.length;
|
|
57
|
-
this.parallelGroups.set(start, end);
|
|
58
|
-
for (let index = start; index < end; index++) {
|
|
59
|
-
this.parallelGroupByStepIndex.set(index, start);
|
|
60
|
-
}
|
|
61
|
-
return this;
|
|
62
|
-
}
|
|
63
|
-
return(...[handler]) {
|
|
64
|
-
if (typeof handler === 'function') {
|
|
65
|
-
this.returnHandler = handler;
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
this.returnHandler = (result) => result;
|
|
69
|
-
}
|
|
70
|
-
return this;
|
|
71
|
-
}
|
|
72
|
-
afterEach(handler) {
|
|
73
|
-
this.afterEachHandler = handler;
|
|
74
|
-
return this;
|
|
75
|
-
}
|
|
76
|
-
beforeEach(handler) {
|
|
77
|
-
this.beforeEachHandler = handler;
|
|
78
|
-
return this;
|
|
79
|
-
}
|
|
80
|
-
onError(handler) {
|
|
81
|
-
this.onErrorHandler = handler;
|
|
82
|
-
return this;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
export function createJob(options) {
|
|
86
|
-
const stack = tryCaptureStackTrace();
|
|
87
|
-
return new Job({ dependencies: {}, ...options }, stack);
|
|
88
|
-
}
|
|
89
|
-
//# sourceMappingURL=job.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"job.js","sourceRoot":"","sources":["../../../src/runtime/jobs/job.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import type { Job, JobState, JobType, QueueEventsListener, RedisClient } from 'bullmq';
|
|
2
|
-
import { Queue, QueueEvents, QueueEventsProducer } from 'bullmq';
|
|
3
|
-
import type { ServerStoreConfig } from '../server/config.ts';
|
|
4
|
-
import type { AnyJob, JobBackoffOptions } from './job.ts';
|
|
5
|
-
import type { JobDefinitionInfo } from './types.ts';
|
|
6
|
-
/**
|
|
7
|
-
* Get the dedicated BullMQ queue name for a job
|
|
8
|
-
*/
|
|
9
|
-
export declare function getJobQueueName(job: AnyJob): string;
|
|
10
|
-
type QueueJobResultOptions<T extends AnyJob = AnyJob> = {
|
|
11
|
-
job: T;
|
|
12
|
-
bullJob: Job<T['_']['input'], T['_']['output'], T['options']['name']>;
|
|
13
|
-
events: QueueEvents;
|
|
14
|
-
};
|
|
15
|
-
type QueueJobAddOptions = {
|
|
16
|
-
jobId?: string;
|
|
17
|
-
priority?: number;
|
|
18
|
-
forceMissingWorkers?: boolean;
|
|
19
|
-
attempts?: number;
|
|
20
|
-
backoff?: JobBackoffOptions;
|
|
21
|
-
oneoff?: boolean;
|
|
22
|
-
delay?: number;
|
|
23
|
-
};
|
|
24
|
-
export declare class QueueJobResult<T extends AnyJob = AnyJob> {
|
|
25
|
-
#private;
|
|
26
|
-
constructor(options: QueueJobResultOptions<T>);
|
|
27
|
-
get id(): string;
|
|
28
|
-
get name(): string;
|
|
29
|
-
waitResult(): Promise<T["_"]["output"]>;
|
|
30
|
-
}
|
|
31
|
-
export type { JobDefinitionInfo, JobItem, JobStepInfo } from './types.ts';
|
|
32
|
-
import type { JobItem, JobStatus } from './types.ts';
|
|
33
|
-
/** Job item type with generic job typing for internal use */
|
|
34
|
-
export type JobItemOf<T extends AnyJob = AnyJob> = JobItem<T['_']['input'], T['_']['output']>;
|
|
35
|
-
export interface JobManagerInstance {
|
|
36
|
-
list<T extends AnyJob>(job: T, options?: {
|
|
37
|
-
page?: number;
|
|
38
|
-
limit?: number;
|
|
39
|
-
status?: JobStatus[];
|
|
40
|
-
}): Promise<{
|
|
41
|
-
items: JobItemOf<T>[];
|
|
42
|
-
page: number;
|
|
43
|
-
limit: number;
|
|
44
|
-
pages: number;
|
|
45
|
-
total: number;
|
|
46
|
-
}>;
|
|
47
|
-
get<T extends AnyJob>(job: T, id: string): Promise<JobItemOf<T> | null>;
|
|
48
|
-
getInfo(job: AnyJob): JobDefinitionInfo;
|
|
49
|
-
add<T extends AnyJob>(job: T, data: T['_']['input'], options?: QueueJobAddOptions): Promise<QueueJobResult<T>>;
|
|
50
|
-
retry(job: AnyJob, id: string, options?: {
|
|
51
|
-
clearState?: boolean;
|
|
52
|
-
}): Promise<void>;
|
|
53
|
-
remove(job: AnyJob, id: string): Promise<void>;
|
|
54
|
-
cancel(job: AnyJob, id: string): Promise<void>;
|
|
55
|
-
}
|
|
56
|
-
export type CustomJobsEvents = QueueEventsListener & {
|
|
57
|
-
[K in `cancel:${string}`]: (args: {}, id: string) => void;
|
|
58
|
-
};
|
|
59
|
-
type JobQueueEntry = {
|
|
60
|
-
queue: Queue;
|
|
61
|
-
events: QueueEvents;
|
|
62
|
-
custom: QueueEventsProducer;
|
|
63
|
-
};
|
|
64
|
-
/**
|
|
65
|
-
* TODO: Consider implementing an abstract SQL storage layer for job queries.
|
|
66
|
-
*
|
|
67
|
-
* Current limitations with BullMQ direct queries:
|
|
68
|
-
* - Pagination is per-type, requires complex offset calculations
|
|
69
|
-
* - Limited filtering/sorting capabilities
|
|
70
|
-
* - No full-text search on job data
|
|
71
|
-
*
|
|
72
|
-
* Proposed architecture:
|
|
73
|
-
* 1. Shared SQLite file (WAL mode) across all workers on the same machine
|
|
74
|
-
* 2. Each worker subscribes to BullMQ events and syncs to SQLite
|
|
75
|
-
* 3. List/filter/sort queries run against SQLite with proper SQL semantics
|
|
76
|
-
* 4. Mutations (add, retry, cancel, remove) still go through BullMQ directly
|
|
77
|
-
*
|
|
78
|
-
* Benefits:
|
|
79
|
-
* - Proper SQL pagination, filtering, sorting
|
|
80
|
-
* - Abstract storage layer could support different queue backends (not just BullMQ)
|
|
81
|
-
* - No per-process memory duplication (shared file)
|
|
82
|
-
* - Complex queries: date ranges, priority ranges, full-text search
|
|
83
|
-
*
|
|
84
|
-
* Implementation notes:
|
|
85
|
-
* - Use better-sqlite3 (sync, fast for in-memory/WAL)
|
|
86
|
-
* - Subscribe to QueueEvents BEFORE initial sync to buffer events
|
|
87
|
-
* - Handle race conditions: initial load + event replay
|
|
88
|
-
* - Consider leader election for sync to reduce write contention
|
|
89
|
-
*/
|
|
90
|
-
export declare class JobManager {
|
|
91
|
-
protected storeConfig: ServerStoreConfig;
|
|
92
|
-
protected jobs: AnyJob[];
|
|
93
|
-
protected store: RedisClient;
|
|
94
|
-
/**
|
|
95
|
-
* Per-job dedicated queues. Each job has its own queue for granular control.
|
|
96
|
-
*/
|
|
97
|
-
protected jobQueues: Map<string, JobQueueEntry>;
|
|
98
|
-
constructor(storeConfig: ServerStoreConfig, jobs: AnyJob[]);
|
|
99
|
-
get publicInstance(): JobManagerInstance;
|
|
100
|
-
initialize(): Promise<void>;
|
|
101
|
-
terminate(): Promise<void>;
|
|
102
|
-
protected getJobQueue(job: AnyJob): JobQueueEntry;
|
|
103
|
-
getInfo(job: AnyJob): JobDefinitionInfo;
|
|
104
|
-
list<T extends AnyJob>(job: T, { limit, page, status }?: {
|
|
105
|
-
page?: number;
|
|
106
|
-
limit?: number;
|
|
107
|
-
status?: JobStatus[];
|
|
108
|
-
}): Promise<{
|
|
109
|
-
items: JobItemOf<AnyJob>[];
|
|
110
|
-
page: number;
|
|
111
|
-
limit: number;
|
|
112
|
-
pages: number;
|
|
113
|
-
total: number;
|
|
114
|
-
}>;
|
|
115
|
-
get<T extends AnyJob>(job: T, id: string): Promise<JobItemOf<AnyJob> | null>;
|
|
116
|
-
add<T extends AnyJob>(job: T, data: T['_']['input'], { forceMissingWorkers, jobId, priority, attempts, backoff, oneoff, delay }?: QueueJobAddOptions): Promise<QueueJobResult<T>>;
|
|
117
|
-
retry(job: AnyJob, id: string, options?: {
|
|
118
|
-
clearState?: boolean;
|
|
119
|
-
}): Promise<void>;
|
|
120
|
-
remove(job: AnyJob, id: string): Promise<void>;
|
|
121
|
-
cancel(job: AnyJob, id: string): Promise<void>;
|
|
122
|
-
cancellationSignal(job: AnyJob, id: string): AbortSignal & {
|
|
123
|
-
[Symbol.dispose]: () => void;
|
|
124
|
-
};
|
|
125
|
-
getQueue(job: AnyJob): JobQueueEntry;
|
|
126
|
-
protected _mapJob(bullJob: Job): Promise<JobItemOf>;
|
|
127
|
-
/** Map BullMQ JobState to vendor-agnostic JobStatus */
|
|
128
|
-
protected _mapStatus(state: JobState | 'unknown'): JobStatus;
|
|
129
|
-
/** Map vendor-agnostic JobStatus to BullMQ JobType for queries */
|
|
130
|
-
protected _mapStatusToJobType(status: JobStatus): JobType[];
|
|
131
|
-
}
|
|
@@ -1,309 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert';
|
|
2
|
-
import { randomUUID } from 'node:crypto';
|
|
3
|
-
import { Queue, QueueEvents, QueueEventsProducer, UnrecoverableError, } from 'bullmq';
|
|
4
|
-
import { createStoreClient } from '../store/index.js';
|
|
5
|
-
/**
|
|
6
|
-
* Get the dedicated BullMQ queue name for a job
|
|
7
|
-
*/
|
|
8
|
-
export function getJobQueueName(job) {
|
|
9
|
-
return `job.${job.options.name}`;
|
|
10
|
-
}
|
|
11
|
-
export class QueueJobResult {
|
|
12
|
-
#options;
|
|
13
|
-
constructor(options) {
|
|
14
|
-
this.#options = options;
|
|
15
|
-
}
|
|
16
|
-
get id() {
|
|
17
|
-
return this.#options.bullJob.id;
|
|
18
|
-
}
|
|
19
|
-
get name() {
|
|
20
|
-
return this.#options.job.options.name;
|
|
21
|
-
}
|
|
22
|
-
async waitResult() {
|
|
23
|
-
return await this.#options.bullJob.waitUntilFinished(this.#options.events);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* TODO: Consider implementing an abstract SQL storage layer for job queries.
|
|
28
|
-
*
|
|
29
|
-
* Current limitations with BullMQ direct queries:
|
|
30
|
-
* - Pagination is per-type, requires complex offset calculations
|
|
31
|
-
* - Limited filtering/sorting capabilities
|
|
32
|
-
* - No full-text search on job data
|
|
33
|
-
*
|
|
34
|
-
* Proposed architecture:
|
|
35
|
-
* 1. Shared SQLite file (WAL mode) across all workers on the same machine
|
|
36
|
-
* 2. Each worker subscribes to BullMQ events and syncs to SQLite
|
|
37
|
-
* 3. List/filter/sort queries run against SQLite with proper SQL semantics
|
|
38
|
-
* 4. Mutations (add, retry, cancel, remove) still go through BullMQ directly
|
|
39
|
-
*
|
|
40
|
-
* Benefits:
|
|
41
|
-
* - Proper SQL pagination, filtering, sorting
|
|
42
|
-
* - Abstract storage layer could support different queue backends (not just BullMQ)
|
|
43
|
-
* - No per-process memory duplication (shared file)
|
|
44
|
-
* - Complex queries: date ranges, priority ranges, full-text search
|
|
45
|
-
*
|
|
46
|
-
* Implementation notes:
|
|
47
|
-
* - Use better-sqlite3 (sync, fast for in-memory/WAL)
|
|
48
|
-
* - Subscribe to QueueEvents BEFORE initial sync to buffer events
|
|
49
|
-
* - Handle race conditions: initial load + event replay
|
|
50
|
-
* - Consider leader election for sync to reduce write contention
|
|
51
|
-
*/
|
|
52
|
-
export class JobManager {
|
|
53
|
-
storeConfig;
|
|
54
|
-
jobs;
|
|
55
|
-
store;
|
|
56
|
-
/**
|
|
57
|
-
* Per-job dedicated queues. Each job has its own queue for granular control.
|
|
58
|
-
*/
|
|
59
|
-
jobQueues = new Map();
|
|
60
|
-
constructor(storeConfig, jobs) {
|
|
61
|
-
this.storeConfig = storeConfig;
|
|
62
|
-
this.jobs = jobs;
|
|
63
|
-
}
|
|
64
|
-
get publicInstance() {
|
|
65
|
-
return {
|
|
66
|
-
list: this.list.bind(this),
|
|
67
|
-
add: this.add.bind(this),
|
|
68
|
-
get: this.get.bind(this),
|
|
69
|
-
getInfo: this.getInfo.bind(this),
|
|
70
|
-
retry: this.retry.bind(this),
|
|
71
|
-
remove: this.remove.bind(this),
|
|
72
|
-
cancel: this.cancel.bind(this),
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
async initialize() {
|
|
76
|
-
this.store = (await createStoreClient(this.storeConfig));
|
|
77
|
-
await this.store.connect();
|
|
78
|
-
// Create a dedicated queue for each job
|
|
79
|
-
for (const job of this.jobs) {
|
|
80
|
-
const queueName = getJobQueueName(job);
|
|
81
|
-
const entry = {
|
|
82
|
-
queue: new Queue(queueName, { connection: this.store }),
|
|
83
|
-
events: new QueueEvents(queueName, {
|
|
84
|
-
connection: this.store,
|
|
85
|
-
autorun: true,
|
|
86
|
-
}),
|
|
87
|
-
custom: new QueueEventsProducer(queueName, { connection: this.store }),
|
|
88
|
-
};
|
|
89
|
-
this.jobQueues.set(job.options.name, entry);
|
|
90
|
-
}
|
|
91
|
-
// Wait for all queues to be ready
|
|
92
|
-
await Promise.all(Array.from(this.jobQueues.values()).flatMap((entry) => [
|
|
93
|
-
entry.queue.waitUntilReady(),
|
|
94
|
-
entry.events.waitUntilReady(),
|
|
95
|
-
entry.custom.waitUntilReady(),
|
|
96
|
-
]));
|
|
97
|
-
}
|
|
98
|
-
async terminate() {
|
|
99
|
-
await Promise.allSettled(Array.from(this.jobQueues.values()).flatMap((entry) => [
|
|
100
|
-
entry.queue.close(),
|
|
101
|
-
entry.events.close(),
|
|
102
|
-
entry.custom.close(),
|
|
103
|
-
]));
|
|
104
|
-
this.store.disconnect(false);
|
|
105
|
-
}
|
|
106
|
-
getJobQueue(job) {
|
|
107
|
-
const entry = this.jobQueues.get(job.options.name);
|
|
108
|
-
if (!entry) {
|
|
109
|
-
throw new Error(`Job queue for [${job.options.name}] not found`);
|
|
110
|
-
}
|
|
111
|
-
return entry;
|
|
112
|
-
}
|
|
113
|
-
getInfo(job) {
|
|
114
|
-
return {
|
|
115
|
-
name: job.options.name,
|
|
116
|
-
steps: job.jobSteps.map((step, index) => ({
|
|
117
|
-
label: step.label,
|
|
118
|
-
conditional: job.conditions.has(index),
|
|
119
|
-
parallel: job.parallelGroupByStepIndex.has(index),
|
|
120
|
-
})),
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
async list(job, { limit = 20, page = 1, status = [], } = {}) {
|
|
124
|
-
const { queue } = this.getJobQueue(job);
|
|
125
|
-
// Convert vendor-agnostic status to BullMQ JobType for querying
|
|
126
|
-
const bullJobTypes = status.length
|
|
127
|
-
? status.flatMap((s) => this._mapStatusToJobType(s))
|
|
128
|
-
: [];
|
|
129
|
-
// Get counts per type to calculate proper offsets
|
|
130
|
-
const typeCounts = await queue.getJobCounts(...bullJobTypes);
|
|
131
|
-
const jobsCount = Object.values(typeCounts).reduce((a, b) => a + b, 0);
|
|
132
|
-
const totalPages = Math.ceil(jobsCount / limit);
|
|
133
|
-
if (page > totalPages)
|
|
134
|
-
return { items: [], page, limit, pages: totalPages, total: jobsCount };
|
|
135
|
-
// Calculate which types we need to fetch from and with what offsets
|
|
136
|
-
const globalStart = (page - 1) * limit;
|
|
137
|
-
const globalEnd = globalStart + limit;
|
|
138
|
-
// Determine the ordered types (use bullJobTypes if specified, otherwise use typeCounts keys)
|
|
139
|
-
const orderedTypes = bullJobTypes.length > 0
|
|
140
|
-
? bullJobTypes
|
|
141
|
-
: Object.keys(typeCounts);
|
|
142
|
-
// Calculate cumulative offsets and fetch jobs from each type as needed
|
|
143
|
-
let cumulative = 0;
|
|
144
|
-
const jobPromises = [];
|
|
145
|
-
for (const type of orderedTypes) {
|
|
146
|
-
const typeCount = typeCounts[type] ?? 0;
|
|
147
|
-
const typeStart = cumulative;
|
|
148
|
-
const typeEnd = cumulative + typeCount;
|
|
149
|
-
// Check if this type overlaps with our desired range
|
|
150
|
-
if (typeEnd > globalStart && typeStart < globalEnd) {
|
|
151
|
-
// Calculate local start/end within this type
|
|
152
|
-
const localStart = Math.max(0, globalStart - typeStart);
|
|
153
|
-
const localEnd = Math.min(typeCount, globalEnd - typeStart) - 1;
|
|
154
|
-
if (localEnd >= localStart) {
|
|
155
|
-
jobPromises.push(queue.getJobs([type], localStart, localEnd));
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
cumulative += typeCount;
|
|
159
|
-
}
|
|
160
|
-
const jobArrays = await Promise.all(jobPromises);
|
|
161
|
-
const jobs = jobArrays.flat().slice(0, limit);
|
|
162
|
-
const items = await Promise.all(jobs.map((job) => this._mapJob(job)));
|
|
163
|
-
return { items, page, limit, pages: totalPages, total: jobsCount };
|
|
164
|
-
}
|
|
165
|
-
async get(job, id) {
|
|
166
|
-
const { queue } = this.getJobQueue(job);
|
|
167
|
-
const bullJob = await queue.getJob(id);
|
|
168
|
-
if (!bullJob)
|
|
169
|
-
return null;
|
|
170
|
-
return await this._mapJob(bullJob);
|
|
171
|
-
}
|
|
172
|
-
async add(job, data, { forceMissingWorkers = false, jobId = randomUUID(), priority, attempts = job.options.attempts, backoff = job.options.backoff, oneoff = job.options.oneoff ?? true, delay, } = {}) {
|
|
173
|
-
const { queue, events } = this.getJobQueue(job);
|
|
174
|
-
if (!forceMissingWorkers) {
|
|
175
|
-
if ((await queue.getWorkersCount()) === 0) {
|
|
176
|
-
throw new Error(`No workers available for [${getJobQueueName(job)}] queue`);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
const bullJob = await queue.add(job.options.name, data, {
|
|
180
|
-
attempts,
|
|
181
|
-
backoff,
|
|
182
|
-
jobId,
|
|
183
|
-
priority,
|
|
184
|
-
delay,
|
|
185
|
-
removeOnComplete: oneoff,
|
|
186
|
-
removeOnFail: oneoff,
|
|
187
|
-
});
|
|
188
|
-
return new QueueJobResult({ job, bullJob, events });
|
|
189
|
-
}
|
|
190
|
-
async retry(job, id, options) {
|
|
191
|
-
const { queue } = this.getJobQueue(job);
|
|
192
|
-
const bullJob = await queue.getJob(id);
|
|
193
|
-
if (!bullJob)
|
|
194
|
-
throw new Error(`Job with id [${id}] not found`);
|
|
195
|
-
const state = await bullJob.getState();
|
|
196
|
-
// For completed jobs, clear state by default so it reruns from scratch
|
|
197
|
-
// For failed jobs, keep state by default so it resumes from checkpoint
|
|
198
|
-
const shouldClearState = options?.clearState ?? state === 'completed';
|
|
199
|
-
if (shouldClearState) {
|
|
200
|
-
await bullJob.updateProgress({});
|
|
201
|
-
}
|
|
202
|
-
await bullJob.retry();
|
|
203
|
-
}
|
|
204
|
-
async remove(job, id) {
|
|
205
|
-
const { queue } = this.getJobQueue(job);
|
|
206
|
-
const bullJob = await queue.getJob(id);
|
|
207
|
-
if (!bullJob)
|
|
208
|
-
throw new Error(`Job with id [${id}] not found`);
|
|
209
|
-
await bullJob.remove();
|
|
210
|
-
}
|
|
211
|
-
async cancel(job, id) {
|
|
212
|
-
const { custom, queue } = this.getJobQueue(job);
|
|
213
|
-
const bullJob = await queue.getJob(id);
|
|
214
|
-
if (!bullJob)
|
|
215
|
-
throw new Error(`Job with id [${id}] not found`);
|
|
216
|
-
if (bullJob.finishedOn)
|
|
217
|
-
return;
|
|
218
|
-
if ((await bullJob.getState()) === 'waiting') {
|
|
219
|
-
return await bullJob.remove();
|
|
220
|
-
}
|
|
221
|
-
if ((await bullJob.getState()) === 'active') {
|
|
222
|
-
await custom.publishEvent({ eventName: `cancel:${id}` });
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
cancellationSignal(job, id) {
|
|
226
|
-
const { events } = this.getJobQueue(job);
|
|
227
|
-
const controller = new AbortController();
|
|
228
|
-
const handler = () => {
|
|
229
|
-
controller.abort(new UnrecoverableError('Job cancelled'));
|
|
230
|
-
};
|
|
231
|
-
events.on(`cancel:${id}`, handler);
|
|
232
|
-
const signal = controller.signal;
|
|
233
|
-
return Object.assign(signal, {
|
|
234
|
-
[Symbol.dispose]: () => {
|
|
235
|
-
events.off(`cancel:${id}`, handler);
|
|
236
|
-
},
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
getQueue(job) {
|
|
240
|
-
return this.getJobQueue(job);
|
|
241
|
-
}
|
|
242
|
-
async _mapJob(bullJob) {
|
|
243
|
-
const bullState = await bullJob.getState();
|
|
244
|
-
const id = bullJob.id;
|
|
245
|
-
assert(typeof id === 'string', 'Expected job id to be a string');
|
|
246
|
-
// Map BullMQ state to vendor-agnostic status
|
|
247
|
-
const status = this._mapStatus(bullState);
|
|
248
|
-
// Extract progress only if it's a valid checkpoint object
|
|
249
|
-
const progress = typeof bullJob.progress === 'object' &&
|
|
250
|
-
bullJob.progress !== null &&
|
|
251
|
-
'stepIndex' in bullJob.progress
|
|
252
|
-
? bullJob.progress
|
|
253
|
-
: undefined;
|
|
254
|
-
return {
|
|
255
|
-
id,
|
|
256
|
-
name: bullJob.name,
|
|
257
|
-
queue: bullJob.queueName,
|
|
258
|
-
data: bullJob.data,
|
|
259
|
-
output: bullJob.returnvalue,
|
|
260
|
-
status,
|
|
261
|
-
priority: bullJob.priority,
|
|
262
|
-
progress,
|
|
263
|
-
attempts: bullJob.attemptsMade,
|
|
264
|
-
startedAt: bullJob.processedOn,
|
|
265
|
-
completedAt: bullJob.finishedOn,
|
|
266
|
-
error: bullJob.failedReason,
|
|
267
|
-
stacktrace: bullJob.stacktrace,
|
|
268
|
-
};
|
|
269
|
-
}
|
|
270
|
-
/** Map BullMQ JobState to vendor-agnostic JobStatus */
|
|
271
|
-
_mapStatus(state) {
|
|
272
|
-
switch (state) {
|
|
273
|
-
case 'waiting':
|
|
274
|
-
case 'prioritized':
|
|
275
|
-
case 'waiting-children':
|
|
276
|
-
return 'pending';
|
|
277
|
-
case 'active':
|
|
278
|
-
return 'active';
|
|
279
|
-
case 'completed':
|
|
280
|
-
return 'completed';
|
|
281
|
-
case 'failed':
|
|
282
|
-
return 'failed';
|
|
283
|
-
case 'delayed':
|
|
284
|
-
return 'delayed';
|
|
285
|
-
default:
|
|
286
|
-
return 'unknown';
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
/** Map vendor-agnostic JobStatus to BullMQ JobType for queries */
|
|
290
|
-
_mapStatusToJobType(status) {
|
|
291
|
-
switch (status) {
|
|
292
|
-
case 'pending':
|
|
293
|
-
return ['waiting', 'prioritized', 'waiting-children'];
|
|
294
|
-
case 'active':
|
|
295
|
-
return ['active'];
|
|
296
|
-
case 'completed':
|
|
297
|
-
return ['completed'];
|
|
298
|
-
case 'failed':
|
|
299
|
-
return ['failed'];
|
|
300
|
-
case 'delayed':
|
|
301
|
-
return ['delayed'];
|
|
302
|
-
case 'cancelled':
|
|
303
|
-
return []; // BullMQ doesn't have a cancelled state
|
|
304
|
-
default:
|
|
305
|
-
return [];
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
//# sourceMappingURL=manager.js.map
|