@nest-boot/schedule 7.0.2 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.spec.d.ts +0 -0
- package/dist/index.spec.js +45 -0
- package/dist/index.spec.js.map +1 -0
- package/dist/schedule-module-options.interface.d.ts +12 -0
- package/dist/schedule-options.interface.d.ts +4 -0
- package/dist/schedule.decorator.d.ts +17 -0
- package/dist/schedule.decorator.js +17 -0
- package/dist/schedule.decorator.js.map +1 -1
- package/dist/schedule.decorator.spec.d.ts +1 -0
- package/dist/schedule.decorator.spec.js +108 -0
- package/dist/schedule.decorator.spec.js.map +1 -0
- package/dist/schedule.module-definition.d.ts +1 -1
- package/dist/schedule.module-definition.js +2 -2
- package/dist/schedule.module-definition.js.map +1 -1
- package/dist/schedule.module.d.ts +21 -1
- package/dist/schedule.module.js +23 -0
- package/dist/schedule.module.js.map +1 -1
- package/dist/schedule.module.spec.d.ts +1 -1
- package/dist/schedule.module.spec.js +84 -32
- package/dist/schedule.module.spec.js.map +1 -1
- package/dist/schedule.processor.spec.d.ts +1 -0
- package/dist/schedule.processor.spec.js +180 -0
- package/dist/schedule.processor.spec.js.map +1 -0
- package/dist/schedule.registry.d.ts +29 -0
- package/dist/schedule.registry.js +27 -0
- package/dist/schedule.registry.js.map +1 -1
- package/dist/schedule.registry.spec.d.ts +1 -0
- package/dist/schedule.registry.spec.js +233 -0
- package/dist/schedule.registry.spec.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +24 -14
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const mockProcessorDecorator = jest.fn();
|
|
37
|
+
const mockProcessor = jest.fn(() => mockProcessorDecorator);
|
|
38
|
+
jest.mock("@nest-boot/bullmq", () => ({
|
|
39
|
+
InjectQueue: jest.fn(() => jest.fn()),
|
|
40
|
+
Processor: mockProcessor,
|
|
41
|
+
WorkerHost: class WorkerHost {
|
|
42
|
+
constructor() {
|
|
43
|
+
this.worker = {
|
|
44
|
+
concurrency: 1,
|
|
45
|
+
run: jest.fn().mockResolvedValue(undefined),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
}));
|
|
50
|
+
const testing_1 = require("@nestjs/testing");
|
|
51
|
+
const schedule_module_definition_1 = require("./schedule.module-definition");
|
|
52
|
+
const schedule_processor_1 = require("./schedule.processor");
|
|
53
|
+
const schedule_registry_1 = require("./schedule.registry");
|
|
54
|
+
describe("ScheduleProcessor", () => {
|
|
55
|
+
const createRegistry = (entry) => {
|
|
56
|
+
const get = jest.fn(() => entry);
|
|
57
|
+
return {
|
|
58
|
+
get,
|
|
59
|
+
registry: {
|
|
60
|
+
get,
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
it("should apply the schedule processor decorator", () => {
|
|
65
|
+
expect(mockProcessor).toHaveBeenCalledWith("schedule", {
|
|
66
|
+
autorun: false,
|
|
67
|
+
});
|
|
68
|
+
expect(mockProcessorDecorator).toHaveBeenCalledWith(schedule_processor_1.ScheduleProcessor);
|
|
69
|
+
});
|
|
70
|
+
it("should invoke the registered schedule handler for the job name", async () => {
|
|
71
|
+
const handler = jest.fn().mockResolvedValue(undefined);
|
|
72
|
+
const { get, registry } = createRegistry({
|
|
73
|
+
handler,
|
|
74
|
+
options: {
|
|
75
|
+
type: "cron",
|
|
76
|
+
value: "* * * * *",
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
const processor = await createProcessor(registry);
|
|
80
|
+
await processor.process({
|
|
81
|
+
name: "Tasks.run",
|
|
82
|
+
});
|
|
83
|
+
expect(get).toHaveBeenCalledWith("Tasks.run");
|
|
84
|
+
expect(handler).toHaveBeenCalledTimes(1);
|
|
85
|
+
});
|
|
86
|
+
it("should ignore jobs with no registered handler", async () => {
|
|
87
|
+
const { get, registry } = createRegistry();
|
|
88
|
+
const processor = await createProcessor(registry);
|
|
89
|
+
await expect(processor.process({
|
|
90
|
+
name: "Missing.run",
|
|
91
|
+
})).resolves.toBeUndefined();
|
|
92
|
+
expect(get).toHaveBeenCalledWith("Missing.run");
|
|
93
|
+
});
|
|
94
|
+
it("should configure concurrency and start the worker by default", async () => {
|
|
95
|
+
const processor = await createProcessor(createRegistry().registry, {
|
|
96
|
+
concurrency: 4,
|
|
97
|
+
});
|
|
98
|
+
processor.onApplicationBootstrap();
|
|
99
|
+
expect(processor.worker.concurrency).toBe(4);
|
|
100
|
+
expect(processor.worker.run).toHaveBeenCalledTimes(1);
|
|
101
|
+
});
|
|
102
|
+
it("should skip autorun when disabled", async () => {
|
|
103
|
+
const processor = await createProcessor(createRegistry().registry, {
|
|
104
|
+
autorun: false,
|
|
105
|
+
});
|
|
106
|
+
processor.onApplicationBootstrap();
|
|
107
|
+
expect(processor.worker.concurrency).toBe(1);
|
|
108
|
+
expect(processor.worker.run).not.toHaveBeenCalled();
|
|
109
|
+
});
|
|
110
|
+
it("should swallow worker run errors", async () => {
|
|
111
|
+
const processor = await createProcessor(createRegistry().registry);
|
|
112
|
+
processor.worker.run.mockRejectedValueOnce(new Error("boom"));
|
|
113
|
+
expect(() => {
|
|
114
|
+
processor.onApplicationBootstrap();
|
|
115
|
+
}).not.toThrow();
|
|
116
|
+
await Promise.resolve();
|
|
117
|
+
expect(processor.worker.run).toHaveBeenCalledTimes(1);
|
|
118
|
+
});
|
|
119
|
+
it("should load decorator metadata fallback branches", async () => {
|
|
120
|
+
await jest.isolateModulesAsync(async () => {
|
|
121
|
+
jest.doMock("@nest-boot/bullmq", () => ({
|
|
122
|
+
InjectQueue: jest.fn(() => jest.fn()),
|
|
123
|
+
Processor: jest.fn(() => jest.fn()),
|
|
124
|
+
WorkerHost: class WorkerHost {
|
|
125
|
+
constructor() {
|
|
126
|
+
this.worker = {
|
|
127
|
+
concurrency: 1,
|
|
128
|
+
run: jest.fn().mockResolvedValue(undefined),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
}));
|
|
133
|
+
jest.doMock("./schedule.registry", () => ({
|
|
134
|
+
ScheduleRegistry: undefined,
|
|
135
|
+
}));
|
|
136
|
+
const module = await Promise.resolve().then(() => __importStar(require("./schedule.processor")));
|
|
137
|
+
expect(module.ScheduleProcessor).toBeDefined();
|
|
138
|
+
});
|
|
139
|
+
await jest.isolateModulesAsync(async () => {
|
|
140
|
+
jest.doMock("@nest-boot/bullmq", () => ({
|
|
141
|
+
InjectQueue: jest.fn(() => jest.fn()),
|
|
142
|
+
Processor: jest.fn(() => jest.fn()),
|
|
143
|
+
WorkerHost: class WorkerHost {
|
|
144
|
+
constructor() {
|
|
145
|
+
this.worker = {
|
|
146
|
+
concurrency: 1,
|
|
147
|
+
run: jest.fn().mockResolvedValue(undefined),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
}));
|
|
152
|
+
jest.doMock("./schedule-module-options.interface", () => ({
|
|
153
|
+
ScheduleModuleOptions: class ScheduleModuleOptions {
|
|
154
|
+
},
|
|
155
|
+
}));
|
|
156
|
+
const module = await Promise.resolve().then(() => __importStar(require("./schedule.processor")));
|
|
157
|
+
expect(module.ScheduleProcessor).toBeDefined();
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
async function createProcessor(registry, options) {
|
|
162
|
+
const providers = [
|
|
163
|
+
schedule_processor_1.ScheduleProcessor,
|
|
164
|
+
{
|
|
165
|
+
provide: schedule_registry_1.ScheduleRegistry,
|
|
166
|
+
useValue: registry,
|
|
167
|
+
},
|
|
168
|
+
];
|
|
169
|
+
if (typeof options !== "undefined") {
|
|
170
|
+
providers.push({
|
|
171
|
+
provide: schedule_module_definition_1.MODULE_OPTIONS_TOKEN,
|
|
172
|
+
useValue: options,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
const moduleRef = await testing_1.Test.createTestingModule({
|
|
176
|
+
providers,
|
|
177
|
+
}).compile();
|
|
178
|
+
return moduleRef.get(schedule_processor_1.ScheduleProcessor);
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=schedule.processor.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.processor.spec.js","sourceRoot":"","sources":["../src/schedule.processor.spec.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,MAAM,sBAAsB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;AACzC,MAAM,aAAa,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,sBAAsB,CAAC,CAAC;AAE5D,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,GAAG,EAAE,CAAC,CAAC;IACpC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;IACrC,SAAS,EAAE,aAAa;IACxB,UAAU,EAAE,MAAM,UAAU;QAAhB;YACV,WAAM,GAAG;gBACP,WAAW,EAAE,CAAC;gBACd,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;aAC5C,CAAC;QACJ,CAAC;KAAA;CACF,CAAC,CAAC,CAAC;AAGJ,6CAAuC;AAEvC,6EAAoE;AACpE,6DAAyD;AACzD,2DAAuD;AAGvD,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,MAAM,cAAc,GAAG,CAAC,KAA2C,EAAE,EAAE;QACrE,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;QAEjC,OAAO;YACL,GAAG;YACH,QAAQ,EAAE;gBACR,GAAG;aAC2B;SACjC,CAAC;IACJ,CAAC,CAAC;IAEF,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,CAAC,aAAa,CAAC,CAAC,oBAAoB,CAAC,UAAU,EAAE;YACrD,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;QACH,MAAM,CAAC,sBAAsB,CAAC,CAAC,oBAAoB,CAAC,sCAAiB,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;QAC9E,MAAM,OAAO,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QACvD,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,cAAc,CAAC;YACvC,OAAO;YACP,OAAO,EAAE;gBACP,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE,WAAW;aACnB;SACF,CAAC,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC,CAAC;QAElD,MAAM,SAAS,CAAC,OAAO,CAAC;YACtB,IAAI,EAAE,WAAW;SACT,CAAC,CAAC;QAEZ,MAAM,CAAC,GAAG,CAAC,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC;QAC9C,MAAM,CAAC,OAAO,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,cAAc,EAAE,CAAC;QAC3C,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC,CAAC;QAElD,MAAM,MAAM,CACV,SAAS,CAAC,OAAO,CAAC;YAChB,IAAI,EAAE,aAAa;SACX,CAAC,CACZ,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;QAE3B,MAAM,CAAC,GAAG,CAAC,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,cAAc,EAAE,CAAC,QAAQ,EAAE;YACjE,WAAW,EAAE,CAAC;SACf,CAAC,CAAC;QAEH,SAAS,CAAC,sBAAsB,EAAE,CAAC;QAEnC,MAAM,CAAE,SAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtD,MAAM,CAAE,SAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,cAAc,EAAE,CAAC,QAAQ,EAAE;YACjE,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;QAEH,SAAS,CAAC,sBAAsB,EAAE,CAAC;QAEnC,MAAM,CAAE,SAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtD,MAAM,CAAE,SAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,cAAc,EAAE,CAAC,QAAQ,CAAC,CAAC;QAClE,SAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,qBAAqB,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAEvE,MAAM,CAAC,GAAG,EAAE;YACV,SAAS,CAAC,sBAAsB,EAAE,CAAC;QACrC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QAExB,MAAM,CAAE,SAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,IAAI,CAAC,mBAAmB,CAAC,KAAK,IAAI,EAAE;YACxC,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,GAAG,EAAE,CAAC,CAAC;gBACtC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;gBACrC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;gBACnC,UAAU,EAAE,MAAM,UAAU;oBAAhB;wBACV,WAAM,GAAG;4BACP,WAAW,EAAE,CAAC;4BACd,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;yBAC5C,CAAC;oBACJ,CAAC;iBAAA;aACF,CAAC,CAAC,CAAC;YACJ,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,GAAG,EAAE,CAAC,CAAC;gBACxC,gBAAgB,EAAE,SAAS;aAC5B,CAAC,CAAC,CAAC;YAEJ,MAAM,MAAM,GAAG,wDAAa,sBAAsB,GAAC,CAAC;YAEpD,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,WAAW,EAAE,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,MAAM,IAAI,CAAC,mBAAmB,CAAC,KAAK,IAAI,EAAE;YACxC,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,GAAG,EAAE,CAAC,CAAC;gBACtC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;gBACrC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;gBACnC,UAAU,EAAE,MAAM,UAAU;oBAAhB;wBACV,WAAM,GAAG;4BACP,WAAW,EAAE,CAAC;4BACd,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;yBAC5C,CAAC;oBACJ,CAAC;iBAAA;aACF,CAAC,CAAC,CAAC;YACJ,IAAI,CAAC,MAAM,CAAC,qCAAqC,EAAE,GAAG,EAAE,CAAC,CAAC;gBACxD,qBAAqB,EAAE,MAAM,qBAAqB;iBAAG;aACtD,CAAC,CAAC,CAAC;YAEJ,MAAM,MAAM,GAAG,wDAAa,sBAAsB,GAAC,CAAC;YAEpD,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,WAAW,EAAE,CAAC;QACjD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,KAAK,UAAU,eAAe,CAC5B,QAA0B,EAC1B,OAA+B;IAE/B,MAAM,SAAS,GAAe;QAC5B,sCAAiB;QACjB;YACE,OAAO,EAAE,oCAAgB;YACzB,QAAQ,EAAE,QAAQ;SACnB;KACF,CAAC;IAEF,IAAI,OAAO,OAAO,KAAK,WAAW,EAAE,CAAC;QACnC,SAAS,CAAC,IAAI,CAAC;YACb,OAAO,EAAE,iDAAoB;YAC7B,QAAQ,EAAE,OAAO;SAClB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,cAAI,CAAC,mBAAmB,CAAC;QAC/C,SAAS;KACV,CAAC,CAAC,OAAO,EAAE,CAAC;IAEb,OAAO,SAAS,CAAC,GAAG,CAAC,sCAAiB,CAAC,CAAC;AAC1C,CAAC"}
|
|
@@ -2,20 +2,49 @@ import { OnApplicationBootstrap } from "@nestjs/common";
|
|
|
2
2
|
import { DiscoveryService, MetadataScanner, Reflector } from "@nestjs/core";
|
|
3
3
|
import { Queue } from "bullmq";
|
|
4
4
|
import { type ScheduleOptions } from "./schedule-options.interface";
|
|
5
|
+
/**
|
|
6
|
+
* Registry that discovers and manages scheduled jobs at application startup.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* Scans all controllers and providers for methods decorated with
|
|
10
|
+
* {@link Schedule}, {@link Cron}, or {@link Interval}, then registers
|
|
11
|
+
* them as BullMQ job schedulers. Removes stale schedulers that are no
|
|
12
|
+
* longer defined in the codebase.
|
|
13
|
+
*/
|
|
5
14
|
export declare class ScheduleRegistry implements OnApplicationBootstrap {
|
|
6
15
|
private readonly queue;
|
|
7
16
|
private readonly reflector;
|
|
8
17
|
private readonly discoveryService;
|
|
9
18
|
private readonly metadataScanner;
|
|
19
|
+
/** Logger instance for the schedule registry. @internal */
|
|
10
20
|
private readonly logger;
|
|
21
|
+
/** Map of schedule names to their handlers and options. @internal */
|
|
11
22
|
private readonly schedules;
|
|
23
|
+
/**
|
|
24
|
+
* Creates a new ScheduleRegistry instance.
|
|
25
|
+
* @param queue - BullMQ queue for managing scheduled jobs
|
|
26
|
+
* @param reflector - NestJS reflector for reading decorator metadata
|
|
27
|
+
* @param discoveryService - NestJS discovery service for scanning providers
|
|
28
|
+
* @param metadataScanner - Scanner for extracting method metadata
|
|
29
|
+
*/
|
|
12
30
|
constructor(queue: Queue, reflector: Reflector, discoveryService: DiscoveryService, metadataScanner: MetadataScanner);
|
|
31
|
+
/**
|
|
32
|
+
* Retrieves a registered schedule entry by name.
|
|
33
|
+
* @param name - The schedule identifier (className.methodName)
|
|
34
|
+
* @returns The schedule handler and options, or undefined
|
|
35
|
+
*/
|
|
13
36
|
get(name: string): {
|
|
37
|
+
/** Handler function bound to the original instance. */
|
|
14
38
|
handler: () => Promise<void>;
|
|
39
|
+
/** Schedule options from the decorator. */
|
|
15
40
|
options: ScheduleOptions;
|
|
16
41
|
} | undefined;
|
|
42
|
+
/** Scans controllers and providers for schedule-decorated methods. @internal */
|
|
17
43
|
private discoverySchedules;
|
|
44
|
+
/** Removes job schedulers that are no longer defined. @internal */
|
|
18
45
|
private cleanUnregisteredSchedules;
|
|
46
|
+
/** Registers all discovered schedules as BullMQ job schedulers. @internal */
|
|
19
47
|
private registerSchedules;
|
|
48
|
+
/** Discovers all scheduled methods and registers them as BullMQ job schedulers. */
|
|
20
49
|
onApplicationBootstrap(): Promise<void>;
|
|
21
50
|
}
|
|
@@ -19,18 +19,42 @@ const common_1 = require("@nestjs/common");
|
|
|
19
19
|
const core_1 = require("@nestjs/core");
|
|
20
20
|
const bullmq_2 = require("bullmq");
|
|
21
21
|
const schedule_module_definition_1 = require("./schedule.module-definition");
|
|
22
|
+
/**
|
|
23
|
+
* Registry that discovers and manages scheduled jobs at application startup.
|
|
24
|
+
*
|
|
25
|
+
* @remarks
|
|
26
|
+
* Scans all controllers and providers for methods decorated with
|
|
27
|
+
* {@link Schedule}, {@link Cron}, or {@link Interval}, then registers
|
|
28
|
+
* them as BullMQ job schedulers. Removes stale schedulers that are no
|
|
29
|
+
* longer defined in the codebase.
|
|
30
|
+
*/
|
|
22
31
|
let ScheduleRegistry = ScheduleRegistry_1 = class ScheduleRegistry {
|
|
32
|
+
/**
|
|
33
|
+
* Creates a new ScheduleRegistry instance.
|
|
34
|
+
* @param queue - BullMQ queue for managing scheduled jobs
|
|
35
|
+
* @param reflector - NestJS reflector for reading decorator metadata
|
|
36
|
+
* @param discoveryService - NestJS discovery service for scanning providers
|
|
37
|
+
* @param metadataScanner - Scanner for extracting method metadata
|
|
38
|
+
*/
|
|
23
39
|
constructor(queue, reflector, discoveryService, metadataScanner) {
|
|
24
40
|
this.queue = queue;
|
|
25
41
|
this.reflector = reflector;
|
|
26
42
|
this.discoveryService = discoveryService;
|
|
27
43
|
this.metadataScanner = metadataScanner;
|
|
44
|
+
/** Logger instance for the schedule registry. @internal */
|
|
28
45
|
this.logger = new common_1.Logger(ScheduleRegistry_1.name);
|
|
46
|
+
/** Map of schedule names to their handlers and options. @internal */
|
|
29
47
|
this.schedules = new Map();
|
|
30
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Retrieves a registered schedule entry by name.
|
|
51
|
+
* @param name - The schedule identifier (className.methodName)
|
|
52
|
+
* @returns The schedule handler and options, or undefined
|
|
53
|
+
*/
|
|
31
54
|
get(name) {
|
|
32
55
|
return this.schedules.get(name);
|
|
33
56
|
}
|
|
57
|
+
/** Scans controllers and providers for schedule-decorated methods. @internal */
|
|
34
58
|
discoverySchedules() {
|
|
35
59
|
[
|
|
36
60
|
...this.discoveryService.getControllers(),
|
|
@@ -55,6 +79,7 @@ let ScheduleRegistry = ScheduleRegistry_1 = class ScheduleRegistry {
|
|
|
55
79
|
}
|
|
56
80
|
});
|
|
57
81
|
}
|
|
82
|
+
/** Removes job schedulers that are no longer defined. @internal */
|
|
58
83
|
async cleanUnregisteredSchedules() {
|
|
59
84
|
const jobSchedulers = await this.queue.getJobSchedulers();
|
|
60
85
|
for (const jobScheduler of jobSchedulers) {
|
|
@@ -64,6 +89,7 @@ let ScheduleRegistry = ScheduleRegistry_1 = class ScheduleRegistry {
|
|
|
64
89
|
}
|
|
65
90
|
}
|
|
66
91
|
}
|
|
92
|
+
/** Registers all discovered schedules as BullMQ job schedulers. @internal */
|
|
67
93
|
async registerSchedules() {
|
|
68
94
|
for (const [name, { options: { type, value, timezone, ...jobOptions }, },] of this.schedules.entries()) {
|
|
69
95
|
await this.queue.upsertJobScheduler(name, {
|
|
@@ -82,6 +108,7 @@ let ScheduleRegistry = ScheduleRegistry_1 = class ScheduleRegistry {
|
|
|
82
108
|
this.logger.log(`Registered {${name}, ${type}, ${String(value)}}`);
|
|
83
109
|
}
|
|
84
110
|
}
|
|
111
|
+
/** Discovers all scheduled methods and registers them as BullMQ job schedulers. */
|
|
85
112
|
async onApplicationBootstrap() {
|
|
86
113
|
this.discoverySchedules();
|
|
87
114
|
await this.cleanUnregisteredSchedules();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schedule.registry.js","sourceRoot":"","sources":["../src/schedule.registry.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAAgD;AAChD,2CAAgE;AAChE,uCAA4E;AAC5E,mCAA+B;AAE/B,6EAGsC;AAGtC,IAAa,gBAAgB,wBAA7B,MAAa,gBAAgB;
|
|
1
|
+
{"version":3,"file":"schedule.registry.js","sourceRoot":"","sources":["../src/schedule.registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
19
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
20
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
21
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
22
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
|
+
};
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
42
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
require("reflect-metadata");
|
|
46
|
+
jest.mock("@nest-boot/bullmq", () => ({
|
|
47
|
+
InjectQueue: jest.fn(() => jest.fn()),
|
|
48
|
+
}));
|
|
49
|
+
const common_1 = require("@nestjs/common");
|
|
50
|
+
const core_1 = require("@nestjs/core");
|
|
51
|
+
const testing_1 = require("@nestjs/testing");
|
|
52
|
+
const bullmq_1 = require("bullmq");
|
|
53
|
+
const schedule_decorator_1 = require("./schedule.decorator");
|
|
54
|
+
const schedule_module_definition_1 = require("./schedule.module-definition");
|
|
55
|
+
const schedule_registry_1 = require("./schedule.registry");
|
|
56
|
+
describe("ScheduleRegistry", () => {
|
|
57
|
+
class ControllerSchedules {
|
|
58
|
+
constructor() {
|
|
59
|
+
this.calls = [];
|
|
60
|
+
}
|
|
61
|
+
async syncUsers() {
|
|
62
|
+
await Promise.resolve();
|
|
63
|
+
this.calls.push("syncUsers");
|
|
64
|
+
}
|
|
65
|
+
undecorated() {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
__decorate([
|
|
70
|
+
(0, schedule_decorator_1.Cron)("*/5 * * * *", {
|
|
71
|
+
attempts: 2,
|
|
72
|
+
timezone: "Asia/Shanghai",
|
|
73
|
+
}),
|
|
74
|
+
__metadata("design:type", Function),
|
|
75
|
+
__metadata("design:paramtypes", []),
|
|
76
|
+
__metadata("design:returntype", Promise)
|
|
77
|
+
], ControllerSchedules.prototype, "syncUsers", null);
|
|
78
|
+
class ProviderSchedules {
|
|
79
|
+
constructor() {
|
|
80
|
+
this.calls = [];
|
|
81
|
+
}
|
|
82
|
+
async refreshCache() {
|
|
83
|
+
await Promise.resolve();
|
|
84
|
+
this.calls.push("refreshCache");
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
__decorate([
|
|
88
|
+
(0, schedule_decorator_1.Interval)("1000", {
|
|
89
|
+
removeOnComplete: true,
|
|
90
|
+
}),
|
|
91
|
+
__metadata("design:type", Function),
|
|
92
|
+
__metadata("design:paramtypes", []),
|
|
93
|
+
__metadata("design:returntype", Promise)
|
|
94
|
+
], ProviderSchedules.prototype, "refreshCache", null);
|
|
95
|
+
const createRegistry = async (controller = new ControllerSchedules(), provider = new ProviderSchedules(), schedulers = []) => {
|
|
96
|
+
const queue = {
|
|
97
|
+
getJobSchedulers: jest.fn().mockResolvedValue(schedulers),
|
|
98
|
+
removeJobScheduler: jest.fn().mockResolvedValue(undefined),
|
|
99
|
+
upsertJobScheduler: jest.fn().mockResolvedValue(undefined),
|
|
100
|
+
};
|
|
101
|
+
const reflector = {
|
|
102
|
+
get: jest.fn((key, handler) => Reflect.getMetadata(key, handler)),
|
|
103
|
+
};
|
|
104
|
+
const discoveryService = {
|
|
105
|
+
getControllers: jest.fn(() => [
|
|
106
|
+
{
|
|
107
|
+
instance: controller,
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
instance: null,
|
|
111
|
+
},
|
|
112
|
+
]),
|
|
113
|
+
getProviders: jest.fn(() => [
|
|
114
|
+
{
|
|
115
|
+
instance: provider,
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
instance: undefined,
|
|
119
|
+
},
|
|
120
|
+
]),
|
|
121
|
+
};
|
|
122
|
+
const metadataScanner = {
|
|
123
|
+
getAllMethodNames: jest.fn((prototype) => Object.getOwnPropertyNames(prototype).filter((key) => key !== "constructor")),
|
|
124
|
+
};
|
|
125
|
+
const moduleRef = await testing_1.Test.createTestingModule({
|
|
126
|
+
providers: [
|
|
127
|
+
schedule_registry_1.ScheduleRegistry,
|
|
128
|
+
{
|
|
129
|
+
provide: bullmq_1.Queue,
|
|
130
|
+
useValue: queue,
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
provide: core_1.Reflector,
|
|
134
|
+
useValue: reflector,
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
provide: core_1.DiscoveryService,
|
|
138
|
+
useValue: discoveryService,
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
provide: core_1.MetadataScanner,
|
|
142
|
+
useValue: metadataScanner,
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
}).compile();
|
|
146
|
+
const registry = moduleRef.get(schedule_registry_1.ScheduleRegistry);
|
|
147
|
+
jest.spyOn(registry.logger, "log").mockImplementation(jest.fn());
|
|
148
|
+
return {
|
|
149
|
+
controller,
|
|
150
|
+
discoveryService,
|
|
151
|
+
metadataScanner,
|
|
152
|
+
provider,
|
|
153
|
+
queue,
|
|
154
|
+
reflector,
|
|
155
|
+
registry,
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
beforeEach(() => {
|
|
159
|
+
jest.spyOn(common_1.Logger.prototype, "log").mockImplementation(jest.fn());
|
|
160
|
+
});
|
|
161
|
+
afterEach(() => {
|
|
162
|
+
jest.restoreAllMocks();
|
|
163
|
+
});
|
|
164
|
+
it("should discover decorated methods, clean stale schedulers, and register schedules", async () => {
|
|
165
|
+
const { controller, queue, registry } = await createRegistry(undefined, undefined, [
|
|
166
|
+
{
|
|
167
|
+
name: "Old.cron",
|
|
168
|
+
pattern: "0 0 * * *",
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
name: "Old.interval",
|
|
172
|
+
every: 5000,
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
name: "ControllerSchedules.syncUsers",
|
|
176
|
+
pattern: "*/5 * * * *",
|
|
177
|
+
},
|
|
178
|
+
]);
|
|
179
|
+
await registry.onApplicationBootstrap();
|
|
180
|
+
await registry.get("ControllerSchedules.syncUsers")?.handler();
|
|
181
|
+
expect(controller.calls).toEqual(["syncUsers"]);
|
|
182
|
+
expect(queue.removeJobScheduler).toHaveBeenCalledTimes(2);
|
|
183
|
+
expect(queue.removeJobScheduler).toHaveBeenCalledWith("Old.cron");
|
|
184
|
+
expect(queue.removeJobScheduler).toHaveBeenCalledWith("Old.interval");
|
|
185
|
+
expect(queue.upsertJobScheduler).toHaveBeenCalledWith("ControllerSchedules.syncUsers", {
|
|
186
|
+
pattern: "*/5 * * * *",
|
|
187
|
+
tz: "Asia/Shanghai",
|
|
188
|
+
}, {
|
|
189
|
+
name: "ControllerSchedules.syncUsers",
|
|
190
|
+
opts: {
|
|
191
|
+
attempts: 2,
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
expect(queue.upsertJobScheduler).toHaveBeenCalledWith("ProviderSchedules.refreshCache", {
|
|
195
|
+
every: 1000,
|
|
196
|
+
tz: "UTC",
|
|
197
|
+
}, {
|
|
198
|
+
name: "ProviderSchedules.refreshCache",
|
|
199
|
+
opts: {
|
|
200
|
+
removeOnComplete: true,
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
it("should ignore non-object wrappers and methods without schedule metadata", async () => {
|
|
205
|
+
const { discoveryService, metadataScanner, queue, reflector, registry } = await createRegistry();
|
|
206
|
+
await registry.onApplicationBootstrap();
|
|
207
|
+
expect(discoveryService.getControllers).toHaveBeenCalledTimes(1);
|
|
208
|
+
expect(discoveryService.getProviders).toHaveBeenCalledTimes(1);
|
|
209
|
+
expect(metadataScanner.getAllMethodNames).toHaveBeenCalledTimes(2);
|
|
210
|
+
expect(reflector.get).toHaveBeenCalledWith(schedule_module_definition_1.SCHEDULE_METADATA_KEY, Object.getOwnPropertyDescriptor(ControllerSchedules.prototype, "undecorated")?.value);
|
|
211
|
+
expect(queue.removeJobScheduler).not.toHaveBeenCalled();
|
|
212
|
+
expect(queue.upsertJobScheduler).toHaveBeenCalledTimes(2);
|
|
213
|
+
expect(registry.get("ControllerSchedules.undecorated")).toBeUndefined();
|
|
214
|
+
});
|
|
215
|
+
it("should load decorator metadata fallback branches", async () => {
|
|
216
|
+
await jest.isolateModulesAsync(async () => {
|
|
217
|
+
jest.doMock("@nest-boot/bullmq", () => ({
|
|
218
|
+
InjectQueue: jest.fn(() => jest.fn()),
|
|
219
|
+
}));
|
|
220
|
+
jest.doMock("bullmq", () => ({
|
|
221
|
+
Queue: undefined,
|
|
222
|
+
}));
|
|
223
|
+
jest.doMock("@nestjs/core", () => ({
|
|
224
|
+
DiscoveryService: undefined,
|
|
225
|
+
MetadataScanner: undefined,
|
|
226
|
+
Reflector: undefined,
|
|
227
|
+
}));
|
|
228
|
+
const module = await Promise.resolve().then(() => __importStar(require("./schedule.registry")));
|
|
229
|
+
expect(module.ScheduleRegistry).toBeDefined();
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
//# sourceMappingURL=schedule.registry.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.registry.spec.js","sourceRoot":"","sources":["../src/schedule.registry.spec.ts"],"names":[],"mappings":"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"}
|