@archlast/server 0.1.8 → 0.1.9
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 +104 -100
- package/dist/admin/auth.d.ts +24 -5
- package/dist/admin/auth.js +49 -25
- package/dist/admin/schema.d.ts +122 -32
- package/dist/admin/schema.js +131 -95
- package/dist/admin/seed.d.ts +1 -1
- package/dist/admin/seed.js +79 -47
- package/dist/auth/api-key-resolver.d.ts +1 -1
- package/dist/auth/api-key-resolver.js +7 -3
- package/dist/auth/archlast-auth-adapter.d.ts +2 -5
- package/dist/auth/archlast-auth-adapter.js +1 -1
- package/dist/auth/better-auth-adapter.d.ts.map +1 -1
- package/dist/auth/better-auth-adapter.js +41 -26
- package/dist/auth/better-auth-adapter.js.map +1 -1
- package/dist/auth/better-auth-admin.d.ts.map +1 -1
- package/dist/auth/better-auth-admin.js +1 -1
- package/dist/auth/better-auth-admin.js.map +1 -1
- package/dist/auth/better-auth-api-key-resolver.js +1 -1
- package/dist/auth/better-auth-api-key-resolver.js.map +1 -1
- package/dist/auth/better-auth-instance.d.ts +249 -301
- package/dist/auth/better-auth-instance.d.ts.map +1 -1
- package/dist/auth/better-auth-instance.js +11 -0
- package/dist/auth/better-auth-instance.js.map +1 -1
- package/dist/auth/better-auth-seed.d.ts +5 -2
- package/dist/auth/better-auth-seed.js +31 -22
- package/dist/auth/better-auth-session-adapter.d.ts.map +1 -1
- package/dist/auth/better-auth-session-adapter.js +14 -10
- package/dist/auth/better-auth-session-adapter.js.map +1 -1
- package/dist/auth/errors.d.ts.map +1 -1
- package/dist/auth/errors.js +11 -11
- package/dist/auth/errors.js.map +1 -1
- package/dist/auth/oauth-proxy.d.ts +5 -2
- package/dist/auth/oauth-proxy.js +23 -27
- package/dist/auth/resolver.d.ts.map +1 -1
- package/dist/auth/resolver.js.map +1 -1
- package/dist/auth/role-helpers.d.ts +1 -1
- package/dist/auth/role-helpers.d.ts.map +1 -1
- package/dist/auth/role-helpers.js.map +1 -1
- package/dist/auth/session-manager.d.ts +2 -5
- package/dist/auth/session-manager.js +16 -6
- package/dist/auth/system/better-auth-schema.d.ts.map +1 -1
- package/dist/auth/system/better-auth-schema.js +6 -23
- package/dist/auth/system/better-auth-schema.js.map +1 -1
- package/dist/cache/circuit-breaker.d.ts +81 -0
- package/dist/cache/circuit-breaker.d.ts.map +1 -0
- package/dist/cache/circuit-breaker.js +170 -0
- package/dist/cache/circuit-breaker.js.map +1 -0
- package/dist/cache/client.d.ts +6 -3
- package/dist/cache/client.d.ts.map +1 -1
- package/dist/cache/client.js +12 -53
- package/dist/cache/client.js.map +1 -1
- package/dist/cache/index.d.ts +2 -0
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +5 -1
- package/dist/cache/index.js.map +1 -1
- package/dist/cache/invalidation-queue.d.ts +63 -0
- package/dist/cache/invalidation-queue.d.ts.map +1 -0
- package/dist/cache/invalidation-queue.js +196 -0
- package/dist/cache/invalidation-queue.js.map +1 -0
- package/dist/cache/layers.d.ts +14 -4
- package/dist/cache/layers.d.ts.map +1 -1
- package/dist/cache/layers.js +66 -72
- package/dist/cache/layers.js.map +1 -1
- package/dist/cache/manager.d.ts.map +1 -1
- package/dist/cache/manager.js +6 -41
- package/dist/cache/manager.js.map +1 -1
- package/dist/cache/protocol.d.ts +4 -39
- package/dist/cache/protocol.d.ts.map +1 -1
- package/dist/cache/protocol.js.map +1 -1
- package/dist/cache/redis-adapter.d.ts +103 -0
- package/dist/cache/redis-adapter.d.ts.map +1 -0
- package/dist/cache/redis-adapter.js +424 -0
- package/dist/cache/redis-adapter.js.map +1 -0
- package/dist/cache/run-sidecar.js +10 -1
- package/dist/cache/run-sidecar.js.map +1 -1
- package/dist/cache/sidecar-server.d.ts +51 -1
- package/dist/cache/sidecar-server.d.ts.map +1 -1
- package/dist/cache/sidecar-server.js +368 -22
- package/dist/cache/sidecar-server.js.map +1 -1
- package/dist/cache/store.d.ts +43 -0
- package/dist/cache/store.d.ts.map +1 -1
- package/dist/cache/store.js +69 -76
- package/dist/cache/store.js.map +1 -1
- package/dist/cache/strategies.d.ts +2 -9
- package/dist/cache/strategies.d.ts.map +1 -1
- package/dist/cache/types.d.ts +130 -0
- package/dist/cache/types.d.ts.map +1 -0
- package/dist/cache/types.js +60 -0
- package/dist/cache/types.js.map +1 -0
- package/dist/config/bullmq.d.ts +16 -0
- package/dist/config/bullmq.d.ts.map +1 -0
- package/dist/config/bullmq.js +103 -0
- package/dist/config/bullmq.js.map +1 -0
- package/dist/config/index.d.ts +1 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +1 -0
- package/dist/config/index.js.map +1 -1
- package/dist/config/schema.d.ts +80 -6
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +71 -6
- package/dist/config/schema.js.map +1 -1
- package/dist/config/service.d.ts +54 -4
- package/dist/config/service.d.ts.map +1 -1
- package/dist/config/service.js +56 -2
- package/dist/config/service.js.map +1 -1
- package/dist/controllers/admin/admin-tokens.controller.d.ts +131 -115
- package/dist/controllers/admin/admin-tokens.controller.js +117 -98
- package/dist/controllers/admin/api-keys.controller.d.ts +1 -1
- package/dist/controllers/admin/api-keys.controller.d.ts.map +1 -1
- package/dist/controllers/admin/api-keys.controller.js.map +1 -1
- package/dist/controllers/admin/app-users.controller.d.ts +274 -243
- package/dist/controllers/admin/app-users.controller.js +301 -257
- package/dist/controllers/admin/auth.controller.d.ts +260 -236
- package/dist/controllers/admin/auth.controller.js +197 -174
- package/dist/controllers/admin/backup.controller.d.ts.map +1 -1
- package/dist/controllers/admin/backup.controller.js.map +1 -1
- package/dist/controllers/admin/settings.controller.d.ts +1 -1
- package/dist/controllers/admin/storage-stats.controller.d.ts +63 -0
- package/dist/controllers/admin/storage-stats.controller.d.ts.map +1 -0
- package/dist/controllers/admin/storage-stats.controller.js +33 -0
- package/dist/controllers/admin/storage-stats.controller.js.map +1 -0
- package/dist/controllers/admin/tenants.controller.d.ts.map +1 -1
- package/dist/controllers/admin/tenants.controller.js.map +1 -1
- package/dist/controllers/admin/users.controller.d.ts +1 -1
- package/dist/controllers/admin/users.controller.d.ts.map +1 -1
- package/dist/controllers/admin/users.controller.js.map +1 -1
- package/dist/controllers/auth.controller.d.ts +289 -271
- package/dist/controllers/auth.controller.js +275 -226
- package/dist/controllers/crud-generator.controller.d.ts.map +1 -1
- package/dist/controllers/crud-generator.controller.js +127 -125
- package/dist/controllers/crud-generator.controller.js.map +1 -1
- package/dist/controllers/index.d.ts +1 -1
- package/dist/controllers/index.d.ts.map +1 -1
- package/dist/controllers/index.js.map +1 -1
- package/dist/controllers/introspection.controller.d.ts +642 -0
- package/dist/controllers/introspection.controller.d.ts.map +1 -1
- package/dist/controllers/introspection.controller.js +611 -0
- package/dist/controllers/introspection.controller.js.map +1 -1
- package/dist/controllers/invite.controller.d.ts +190 -170
- package/dist/controllers/invite.controller.js +183 -164
- package/dist/controllers/mfa.controller.d.ts +205 -183
- package/dist/controllers/mfa.controller.js +131 -111
- package/dist/controllers/otp.controller.d.ts +194 -171
- package/dist/controllers/otp.controller.js +192 -175
- package/dist/controllers/storage.controller.d.ts.map +1 -1
- package/dist/controllers/storage.controller.js.map +1 -1
- package/dist/controllers/system.controller.d.ts +5 -3
- package/dist/controllers/system.controller.d.ts.map +1 -1
- package/dist/controllers/system.controller.js +4 -2
- package/dist/controllers/system.controller.js.map +1 -1
- package/dist/controllers/tenant.controller.d.ts +258 -227
- package/dist/controllers/tenant.controller.js +224 -200
- package/dist/db/cachedclient.d.ts +6 -11
- package/dist/db/cachedclient.d.ts.map +1 -1
- package/dist/db/cachedclient.js +79 -43
- package/dist/db/cachedclient.js.map +1 -1
- package/dist/db/distributed-client.d.ts +79 -24
- package/dist/db/distributed-client.js +23 -24
- package/dist/db/factory.d.ts +3 -8
- package/dist/db/factory.d.ts.map +1 -1
- package/dist/db/factory.js +3 -22
- package/dist/db/factory.js.map +1 -1
- package/dist/db/socket-client.d.ts +7 -0
- package/dist/db/socket-client.d.ts.map +1 -1
- package/dist/db/socket-client.js +140 -11
- package/dist/db/socket-client.js.map +1 -1
- package/dist/deployment/handler.d.ts +10 -2
- package/dist/deployment/handler.d.ts.map +1 -1
- package/dist/deployment/handler.js +70 -15
- package/dist/deployment/handler.js.map +1 -1
- package/dist/deployment/persistence.d.ts.map +1 -1
- package/dist/deployment/persistence.js +6 -1
- package/dist/deployment/persistence.js.map +1 -1
- package/dist/docker/compose.d.ts.map +1 -1
- package/dist/docker/compose.js +76 -0
- package/dist/docker/compose.js.map +1 -1
- package/dist/engine/runner.d.ts.map +1 -1
- package/dist/engine/runner.js +0 -43
- package/dist/engine/runner.js.map +1 -1
- package/dist/functions/built-in/auth-apikey.d.ts.map +1 -1
- package/dist/functions/built-in/auth-apikey.js.map +1 -1
- package/dist/functions/built-in/system-cache.d.ts.map +1 -1
- package/dist/functions/built-in/system-cache.js +6 -31
- package/dist/functions/built-in/system-cache.js.map +1 -1
- package/dist/functions/built-in/system-data.d.ts.map +1 -1
- package/dist/functions/built-in/system-data.js +4 -2
- package/dist/functions/built-in/system-data.js.map +1 -1
- package/dist/functions/definition.d.ts.map +1 -1
- package/dist/functions/definition.js +6 -2
- package/dist/functions/definition.js.map +1 -1
- package/dist/http/routes/metrics.d.ts +42 -0
- package/dist/http/routes/metrics.d.ts.map +1 -0
- package/dist/http/routes/metrics.js +29 -0
- package/dist/http/routes/metrics.js.map +1 -0
- package/dist/http/server.d.ts +1 -0
- package/dist/http/server.d.ts.map +1 -1
- package/dist/http/server.js +41 -3
- package/dist/http/server.js.map +1 -1
- package/dist/ipc/socket-bridge.d.ts +1 -0
- package/dist/ipc/socket-bridge.d.ts.map +1 -1
- package/dist/ipc/socket-bridge.js +5 -1
- package/dist/ipc/socket-bridge.js.map +1 -1
- package/dist/jobs/bullmq-adapter.d.ts +154 -0
- package/dist/jobs/bullmq-adapter.d.ts.map +1 -0
- package/dist/jobs/bullmq-adapter.js +688 -0
- package/dist/jobs/bullmq-adapter.js.map +1 -0
- package/dist/jobs/bullmq-circuit-breaker.d.ts +133 -0
- package/dist/jobs/bullmq-circuit-breaker.d.ts.map +1 -0
- package/dist/jobs/bullmq-circuit-breaker.js +323 -0
- package/dist/jobs/bullmq-circuit-breaker.js.map +1 -0
- package/dist/jobs/bullmq-dlq-manager.d.ts +155 -0
- package/dist/jobs/bullmq-dlq-manager.d.ts.map +1 -0
- package/dist/jobs/bullmq-dlq-manager.js +325 -0
- package/dist/jobs/bullmq-dlq-manager.js.map +1 -0
- package/dist/jobs/bullmq-metrics.d.ts +104 -0
- package/dist/jobs/bullmq-metrics.d.ts.map +1 -0
- package/dist/jobs/bullmq-metrics.js +323 -0
- package/dist/jobs/bullmq-metrics.js.map +1 -0
- package/dist/jobs/bullmq-priority-service.d.ts +173 -0
- package/dist/jobs/bullmq-priority-service.d.ts.map +1 -0
- package/dist/jobs/bullmq-priority-service.js +390 -0
- package/dist/jobs/bullmq-priority-service.js.map +1 -0
- package/dist/jobs/bullmq-scheduler.d.ts +111 -0
- package/dist/jobs/bullmq-scheduler.d.ts.map +1 -0
- package/dist/jobs/bullmq-scheduler.js +300 -0
- package/dist/jobs/bullmq-scheduler.js.map +1 -0
- package/dist/jobs/bullmq-worker.d.ts +155 -0
- package/dist/jobs/bullmq-worker.d.ts.map +1 -0
- package/dist/jobs/bullmq-worker.js +651 -0
- package/dist/jobs/bullmq-worker.js.map +1 -0
- package/dist/jobs/circuit-breaker.d.ts +120 -0
- package/dist/jobs/circuit-breaker.d.ts.map +1 -0
- package/dist/jobs/circuit-breaker.js +262 -0
- package/dist/jobs/circuit-breaker.js.map +1 -0
- package/dist/jobs/index.d.ts +1 -1
- package/dist/jobs/index.d.ts.map +1 -1
- package/dist/jobs/index.js.map +1 -1
- package/dist/jobs/queue.d.ts +120 -1
- package/dist/jobs/queue.d.ts.map +1 -1
- package/dist/jobs/queue.js +487 -9
- package/dist/jobs/queue.js.map +1 -1
- package/dist/jobs/redis-connection.d.ts +50 -0
- package/dist/jobs/redis-connection.d.ts.map +1 -0
- package/dist/jobs/redis-connection.js +123 -0
- package/dist/jobs/redis-connection.js.map +1 -0
- package/dist/jobs/run-scheduler.js +163 -10
- package/dist/jobs/run-scheduler.js.map +1 -1
- package/dist/jobs/run-worker.js +101 -9
- package/dist/jobs/run-worker.js.map +1 -1
- package/dist/jobs/worker-thread.d.ts +6 -0
- package/dist/jobs/worker-thread.d.ts.map +1 -1
- package/dist/jobs/worker-thread.js +37 -8
- package/dist/jobs/worker-thread.js.map +1 -1
- package/dist/jobs/worker.d.ts +33 -0
- package/dist/jobs/worker.d.ts.map +1 -1
- package/dist/jobs/worker.js +358 -115
- package/dist/jobs/worker.js.map +1 -1
- package/dist/linq/async-enumerable.d.ts.map +1 -1
- package/dist/linq/async-enumerable.js.map +1 -1
- package/dist/linq/enumerable.d.ts.map +1 -1
- package/dist/linq/enumerable.js +10 -10
- package/dist/linq/enumerable.js.map +1 -1
- package/dist/metrics/collector.d.ts +26 -0
- package/dist/metrics/collector.d.ts.map +1 -0
- package/dist/metrics/collector.js +103 -0
- package/dist/metrics/collector.js.map +1 -0
- package/dist/polling/updates.controller.d.ts +57 -0
- package/dist/polling/updates.controller.d.ts.map +1 -0
- package/dist/polling/updates.controller.js +70 -0
- package/dist/polling/updates.controller.js.map +1 -0
- package/dist/repository/db-set.d.ts.map +1 -1
- package/dist/repository/db-set.js +12 -8
- package/dist/repository/db-set.js.map +1 -1
- package/dist/repository/ef-core.d.ts.map +1 -1
- package/dist/repository/ef-core.js +6 -6
- package/dist/repository/ef-core.js.map +1 -1
- package/dist/repository/factory.d.ts +1 -1
- package/dist/repository/factory.d.ts.map +1 -1
- package/dist/repository/factory.js.map +1 -1
- package/dist/repository/interfaces.d.ts.map +1 -1
- package/dist/repository/interfaces.js.map +1 -1
- package/dist/repository/queryable.d.ts.map +1 -1
- package/dist/repository/queryable.js.map +1 -1
- package/dist/rpc/adapter.d.ts.map +1 -1
- package/dist/rpc/adapter.js.map +1 -1
- package/dist/rpc/router.d.ts +2 -2
- package/dist/rpc/router.d.ts.map +1 -1
- package/dist/rpc/router.js +1 -1
- package/dist/rpc/router.js.map +1 -1
- package/dist/schema/relationship-types.d.ts +7 -2
- package/dist/schema/relationship-types.js +1 -1
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/services/admin/app-users.service.d.ts +1 -1
- package/dist/services/admin/app-users.service.js +31 -38
- package/dist/services/admin/auth.service.d.ts +1 -1
- package/dist/services/admin/auth.service.js +11 -5
- package/dist/services/admin/backup/BackupOrchestrator.d.ts.map +1 -1
- package/dist/services/admin/backup/BackupOrchestrator.js +4 -7
- package/dist/services/admin/backup/BackupOrchestrator.js.map +1 -1
- package/dist/services/admin/backup/SqliteGenerator.js +8 -8
- package/dist/services/admin/backup/StorageStreamer.d.ts +3 -3
- package/dist/services/admin/backup/StorageStreamer.d.ts.map +1 -1
- package/dist/services/admin/backup/StorageStreamer.js +16 -55
- package/dist/services/admin/backup/StorageStreamer.js.map +1 -1
- package/dist/services/admin/backup/ZipComposer.d.ts +2 -0
- package/dist/services/admin/backup/ZipComposer.d.ts.map +1 -1
- package/dist/services/admin/backup/ZipComposer.js +23 -0
- package/dist/services/admin/backup/ZipComposer.js.map +1 -1
- package/dist/services/admin/backup.service.d.ts.map +1 -1
- package/dist/services/admin/backup.service.js.map +1 -1
- package/dist/services/admin/data.service.d.ts.map +1 -1
- package/dist/services/admin/data.service.js +287 -286
- package/dist/services/admin/data.service.js.map +1 -1
- package/dist/services/admin/tenants.service.d.ts.map +1 -1
- package/dist/services/admin/tenants.service.js.map +1 -1
- package/dist/services/auth.service.d.ts +2 -3
- package/dist/services/auth.service.js +16 -16
- package/dist/services/invite.service.d.ts +1 -1
- package/dist/services/invite.service.js +17 -15
- package/dist/services/storage.service.d.ts.map +1 -1
- package/dist/services/storage.service.js +35 -4
- package/dist/services/storage.service.js.map +1 -1
- package/dist/services/system.service.d.ts.map +1 -1
- package/dist/services/system.service.js +1 -1
- package/dist/services/system.service.js.map +1 -1
- package/dist/services/tenant.service.d.ts +1 -1
- package/dist/services/tenant.service.js +43 -31
- package/dist/sse/subscriptions.controller.d.ts +57 -0
- package/dist/sse/subscriptions.controller.d.ts.map +1 -0
- package/dist/sse/subscriptions.controller.js +127 -0
- package/dist/sse/subscriptions.controller.js.map +1 -0
- package/dist/startup/bootstrap.d.ts +13 -2
- package/dist/startup/bootstrap.d.ts.map +1 -1
- package/dist/startup/bootstrap.js +85 -13
- package/dist/startup/bootstrap.js.map +1 -1
- package/dist/storage/s3-backend.d.ts.map +1 -1
- package/dist/storage/s3-backend.js +3 -3
- package/dist/storage/s3-backend.js.map +1 -1
- package/dist/websocket/server.d.ts.map +1 -1
- package/dist/websocket/server.js +14 -3
- package/dist/websocket/server.js.map +1 -1
- package/docker/README.md +309 -11
- package/package.json +214 -210
- package/templates/.env.example +115 -55
- package/templates/archlast.config.js +51 -37
- package/templates/docker-compose.prod.yml +32 -15
- package/templates/docker-compose.yml +117 -33
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.BullMQPriorityAgingService = void 0;
|
|
7
|
+
const bullmq_1 = require("bullmq");
|
|
8
|
+
const ioredis_1 = __importDefault(require("ioredis"));
|
|
9
|
+
const logger_js_1 = require("../logging/logger.js");
|
|
10
|
+
/**
|
|
11
|
+
* Service that implements priority aging for BullMQ jobs.
|
|
12
|
+
*
|
|
13
|
+
* Priority aging prevents job starvation by boosting the priority of jobs
|
|
14
|
+
* that have been waiting in the queue for an extended period. Every 15 minutes,
|
|
15
|
+
* a job's priority is increased by 1 level (up to a maximum bonus of 5).
|
|
16
|
+
*
|
|
17
|
+
* This service runs a background worker that periodically scans waiting jobs
|
|
18
|
+
* and updates their priorities based on their wait time.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* const agingService = new BullMQPriorityAgingService(
|
|
23
|
+
* "my-queue",
|
|
24
|
+
* redisConnection,
|
|
25
|
+
* { checkIntervalMs: 60000 }
|
|
26
|
+
* );
|
|
27
|
+
*
|
|
28
|
+
* await agingService.start();
|
|
29
|
+
*
|
|
30
|
+
* // When enqueueing jobs, prepare data with aging metadata:
|
|
31
|
+
* const jobData = BullMQPriorityAgingService.prepareJobData(payload, priority);
|
|
32
|
+
* await queue.add("job-name", jobData, { priority: toBullMQPriority(priority) });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
class BullMQPriorityAgingService {
|
|
36
|
+
AGING_INTERVAL_MS = 15 * 60 * 1000; // 15 minutes
|
|
37
|
+
MAX_AGING_BONUS = 5;
|
|
38
|
+
DEFAULT_CHECK_INTERVAL_MS = 60000; // 1 minute
|
|
39
|
+
DEFAULT_MAX_JOBS_PER_CHECK = 100;
|
|
40
|
+
queue;
|
|
41
|
+
agingWorker = null;
|
|
42
|
+
workerConnection = null;
|
|
43
|
+
checkIntervalMs;
|
|
44
|
+
maxJobsPerCheck;
|
|
45
|
+
queueName;
|
|
46
|
+
connection;
|
|
47
|
+
_isRunning = false;
|
|
48
|
+
agingInterval = null;
|
|
49
|
+
/**
|
|
50
|
+
* Creates a new BullMQPriorityAgingService instance.
|
|
51
|
+
*
|
|
52
|
+
* @param queueName - The name of the BullMQ queue to monitor
|
|
53
|
+
* @param connection - Redis connection for BullMQ
|
|
54
|
+
* @param options - Optional configuration for the aging service
|
|
55
|
+
*/
|
|
56
|
+
constructor(queueName, connection, options) {
|
|
57
|
+
this.queueName = queueName;
|
|
58
|
+
this.connection = connection;
|
|
59
|
+
this.checkIntervalMs = options?.checkIntervalMs ?? this.DEFAULT_CHECK_INTERVAL_MS;
|
|
60
|
+
this.maxJobsPerCheck = options?.maxJobsPerCheck ?? this.DEFAULT_MAX_JOBS_PER_CHECK;
|
|
61
|
+
// Create the main queue instance (for accessing waiting jobs)
|
|
62
|
+
this.queue = new bullmq_1.Queue(queueName, {
|
|
63
|
+
connection,
|
|
64
|
+
defaultJobOptions: {
|
|
65
|
+
removeOnComplete: false,
|
|
66
|
+
removeOnFail: false,
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Start the priority aging service.
|
|
72
|
+
*
|
|
73
|
+
* This creates a background worker that periodically checks waiting jobs
|
|
74
|
+
* and applies priority boosts to jobs that have been waiting too long.
|
|
75
|
+
*
|
|
76
|
+
* @returns Promise that resolves when the service is started
|
|
77
|
+
*/
|
|
78
|
+
async start() {
|
|
79
|
+
if (this._isRunning) {
|
|
80
|
+
logger_js_1.logger.log({
|
|
81
|
+
timestamp: Date.now(),
|
|
82
|
+
level: "warn",
|
|
83
|
+
kind: "system",
|
|
84
|
+
message: `[BullMQPriorityAgingService] Service already running for queue: ${this.queueName}`,
|
|
85
|
+
});
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
logger_js_1.logger.log({
|
|
89
|
+
timestamp: Date.now(),
|
|
90
|
+
level: "info",
|
|
91
|
+
kind: "system",
|
|
92
|
+
message: `[BullMQPriorityAgingService] Starting aging service for queue: ${this.queueName}`,
|
|
93
|
+
});
|
|
94
|
+
// Create the aging worker on a separate queue for processing
|
|
95
|
+
// Note: Workers require a separate connection with maxRetriesPerRequest: null
|
|
96
|
+
const agingQueueName = `${this.queueName}-aging`;
|
|
97
|
+
this.workerConnection = new ioredis_1.default({
|
|
98
|
+
host: this.connection.options.host,
|
|
99
|
+
port: this.connection.options.port,
|
|
100
|
+
password: this.connection.options.password,
|
|
101
|
+
db: this.connection.options.db,
|
|
102
|
+
maxRetriesPerRequest: null,
|
|
103
|
+
enableReadyCheck: true,
|
|
104
|
+
enableOfflineQueue: false,
|
|
105
|
+
});
|
|
106
|
+
this.agingWorker = new bullmq_1.Worker(agingQueueName, async () => {
|
|
107
|
+
// This worker processes aging tasks
|
|
108
|
+
await this.performAgingCheck();
|
|
109
|
+
}, {
|
|
110
|
+
connection: this.workerConnection,
|
|
111
|
+
concurrency: 1,
|
|
112
|
+
});
|
|
113
|
+
// Set up interval to periodically trigger aging checks
|
|
114
|
+
this.agingInterval = setInterval(async () => {
|
|
115
|
+
try {
|
|
116
|
+
await this.performAgingCheck();
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
logger_js_1.logger.log({
|
|
120
|
+
timestamp: Date.now(),
|
|
121
|
+
level: "error",
|
|
122
|
+
kind: "system",
|
|
123
|
+
message: `[BullMQPriorityAgingService] Error during aging check: ${error}`,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}, this.checkIntervalMs);
|
|
127
|
+
this._isRunning = true;
|
|
128
|
+
logger_js_1.logger.log({
|
|
129
|
+
timestamp: Date.now(),
|
|
130
|
+
level: "info",
|
|
131
|
+
kind: "system",
|
|
132
|
+
message: `[BullMQPriorityAgingService] Aging service started for queue: ${this.queueName}`,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Stop the priority aging service.
|
|
137
|
+
*
|
|
138
|
+
* Closes the aging worker and clears the check interval.
|
|
139
|
+
*
|
|
140
|
+
* @returns Promise that resolves when the service is stopped
|
|
141
|
+
*/
|
|
142
|
+
async stop() {
|
|
143
|
+
if (!this._isRunning) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
logger_js_1.logger.log({
|
|
147
|
+
timestamp: Date.now(),
|
|
148
|
+
level: "info",
|
|
149
|
+
kind: "system",
|
|
150
|
+
message: `[BullMQPriorityAgingService] Stopping aging service for queue: ${this.queueName}`,
|
|
151
|
+
});
|
|
152
|
+
// Clear the interval
|
|
153
|
+
if (this.agingInterval) {
|
|
154
|
+
clearInterval(this.agingInterval);
|
|
155
|
+
this.agingInterval = null;
|
|
156
|
+
}
|
|
157
|
+
// Close the aging worker
|
|
158
|
+
if (this.agingWorker) {
|
|
159
|
+
await this.agingWorker.close();
|
|
160
|
+
this.agingWorker = null;
|
|
161
|
+
}
|
|
162
|
+
// Close the worker connection
|
|
163
|
+
if (this.workerConnection) {
|
|
164
|
+
await this.workerConnection.quit();
|
|
165
|
+
this.workerConnection = null;
|
|
166
|
+
}
|
|
167
|
+
// Close the queue connection
|
|
168
|
+
await this.queue.close();
|
|
169
|
+
this._isRunning = false;
|
|
170
|
+
logger_js_1.logger.log({
|
|
171
|
+
timestamp: Date.now(),
|
|
172
|
+
level: "info",
|
|
173
|
+
kind: "system",
|
|
174
|
+
message: `[BullMQPriorityAgingService] Aging service stopped for queue: ${this.queueName}`,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Check if the aging service is currently running.
|
|
179
|
+
*
|
|
180
|
+
* @returns true if the service is running, false otherwise
|
|
181
|
+
*/
|
|
182
|
+
isRunning() {
|
|
183
|
+
return this._isRunning;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Manually trigger an aging check.
|
|
187
|
+
*
|
|
188
|
+
* This method scans waiting jobs, calculates their effective priority based on
|
|
189
|
+
* wait time, and updates job priorities if the aging bonus has increased.
|
|
190
|
+
*
|
|
191
|
+
* @returns Statistics about the aging check
|
|
192
|
+
*/
|
|
193
|
+
async applyAging() {
|
|
194
|
+
if (!this._isRunning) {
|
|
195
|
+
throw new Error("Aging service is not running. Call start() first.");
|
|
196
|
+
}
|
|
197
|
+
return this.performAgingCheck();
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Calculate the effective priority for a job based on its base priority and creation time.
|
|
201
|
+
*
|
|
202
|
+
* The aging algorithm adds 1 priority level for every 15 minutes of wait time,
|
|
203
|
+
* up to a maximum bonus of 5 levels.
|
|
204
|
+
*
|
|
205
|
+
* @param basePriority - The original priority (1-20, where 1 is highest)
|
|
206
|
+
* @param createdAt - Timestamp when the job was created
|
|
207
|
+
* @param now - Optional current timestamp (defaults to Date.now())
|
|
208
|
+
* @returns Object containing the effective priority and the calculated aging bonus
|
|
209
|
+
*/
|
|
210
|
+
static calculateEffectivePriority(basePriority, createdAt, now) {
|
|
211
|
+
const currentTime = now ?? Date.now();
|
|
212
|
+
const waitTimeMs = currentTime - createdAt;
|
|
213
|
+
// Calculate aging periods (15-minute intervals)
|
|
214
|
+
const agingPeriods = Math.floor(waitTimeMs / (15 * 60 * 1000));
|
|
215
|
+
const agingBonus = Math.min(5, agingPeriods);
|
|
216
|
+
// Effective priority: boost priority by reducing the number (1 = highest)
|
|
217
|
+
const effectivePriority = Math.max(1, basePriority - agingBonus);
|
|
218
|
+
return { effectivePriority, agingBonus };
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Convert system priority (1-20) to BullMQ priority (1-2097152).
|
|
222
|
+
*
|
|
223
|
+
* BullMQ uses lower numbers for higher priority. The mapping:
|
|
224
|
+
* - System 1 (highest) → BullMQ 1
|
|
225
|
+
* - System 10 → BullMQ ~1104750
|
|
226
|
+
* - System 20 (lowest) → BullMQ 2097152
|
|
227
|
+
*
|
|
228
|
+
* @param systemPriority - Priority in system format (1-20)
|
|
229
|
+
* @returns Priority in BullMQ format (1-2097152)
|
|
230
|
+
*/
|
|
231
|
+
static toBullMQPriority(systemPriority) {
|
|
232
|
+
const normalizedPriority = Math.max(1, Math.min(20, systemPriority));
|
|
233
|
+
// Map 1-20 to 2097152-1 (inverted: lower number = higher priority in BullMQ)
|
|
234
|
+
return Math.floor((21 - normalizedPriority) * 104857.6);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Convert BullMQ priority (1-2097152) back to system priority (1-20).
|
|
238
|
+
*
|
|
239
|
+
* @param bullmqPriority - Priority in BullMQ format
|
|
240
|
+
* @returns Priority in system format (1-20)
|
|
241
|
+
*/
|
|
242
|
+
static fromBullMQPriority(bullmqPriority) {
|
|
243
|
+
const systemPriority = 21 - Math.ceil(bullmqPriority / 104857.6);
|
|
244
|
+
return Math.max(1, Math.min(20, systemPriority));
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Prepare job data with aging tracking metadata.
|
|
248
|
+
*
|
|
249
|
+
* This should be called when creating a new job to ensure aging metadata
|
|
250
|
+
* is properly attached to the job data.
|
|
251
|
+
*
|
|
252
|
+
* @param payload - The job payload/data
|
|
253
|
+
* @param priority - The original priority (1-20)
|
|
254
|
+
* @returns Object containing the payload and aging metadata
|
|
255
|
+
*/
|
|
256
|
+
static prepareJobData(payload, priority) {
|
|
257
|
+
const now = Date.now();
|
|
258
|
+
const normalizedPriority = Math.max(1, Math.min(20, priority));
|
|
259
|
+
return {
|
|
260
|
+
payload,
|
|
261
|
+
__aging__: {
|
|
262
|
+
originalPriority: normalizedPriority,
|
|
263
|
+
agingBonus: 0,
|
|
264
|
+
createdAt: now,
|
|
265
|
+
lastAgingCheck: now,
|
|
266
|
+
},
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Extract aging metadata from BullMQ job data.
|
|
271
|
+
*
|
|
272
|
+
* @param jobData - The job data from BullMQ
|
|
273
|
+
* @returns The aging data if present, null otherwise
|
|
274
|
+
*/
|
|
275
|
+
static extractAgingData(jobData) {
|
|
276
|
+
if (typeof jobData === "object" && jobData !== null && "__aging__" in jobData) {
|
|
277
|
+
const aging = jobData.__aging__;
|
|
278
|
+
if (typeof aging === "object" &&
|
|
279
|
+
aging !== null &&
|
|
280
|
+
"originalPriority" in aging &&
|
|
281
|
+
"agingBonus" in aging &&
|
|
282
|
+
"createdAt" in aging &&
|
|
283
|
+
"lastAgingCheck" in aging) {
|
|
284
|
+
return aging;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Perform the actual aging check on waiting jobs.
|
|
291
|
+
*
|
|
292
|
+
* This is the internal implementation that scans waiting jobs and applies
|
|
293
|
+
* priority updates based on their wait time.
|
|
294
|
+
*/
|
|
295
|
+
async performAgingCheck() {
|
|
296
|
+
const now = Date.now();
|
|
297
|
+
let jobsChecked = 0;
|
|
298
|
+
let jobsBoosted = 0;
|
|
299
|
+
let totalWaitTimeMs = 0;
|
|
300
|
+
try {
|
|
301
|
+
// Get waiting jobs from the queue
|
|
302
|
+
const waitingJobs = await this.queue.getWaiting(0, this.maxJobsPerCheck);
|
|
303
|
+
logger_js_1.logger.log({
|
|
304
|
+
timestamp: now,
|
|
305
|
+
level: "debug",
|
|
306
|
+
kind: "system",
|
|
307
|
+
message: `[BullMQPriorityAgingService] Checking ${waitingJobs.length} waiting jobs for aging`,
|
|
308
|
+
});
|
|
309
|
+
for (const job of waitingJobs) {
|
|
310
|
+
jobsChecked++;
|
|
311
|
+
const agingData = BullMQPriorityAgingService.extractAgingData(job.data);
|
|
312
|
+
if (!agingData) {
|
|
313
|
+
// Job doesn't have aging metadata, skip
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
const waitTimeMs = now - agingData.createdAt;
|
|
317
|
+
totalWaitTimeMs += waitTimeMs;
|
|
318
|
+
// Calculate new effective priority
|
|
319
|
+
const { effectivePriority, agingBonus } = BullMQPriorityAgingService.calculateEffectivePriority(agingData.originalPriority, agingData.createdAt, now);
|
|
320
|
+
// Check if aging bonus has increased
|
|
321
|
+
if (agingBonus > agingData.agingBonus) {
|
|
322
|
+
try {
|
|
323
|
+
// Convert effective priority to BullMQ format
|
|
324
|
+
const newBullMQPriority = BullMQPriorityAgingService.toBullMQPriority(effectivePriority);
|
|
325
|
+
// Update job priority using changePriority
|
|
326
|
+
await job.changePriority({ priority: newBullMQPriority });
|
|
327
|
+
// Update job data with new aging info
|
|
328
|
+
const updatedData = {
|
|
329
|
+
...job.data,
|
|
330
|
+
__aging__: {
|
|
331
|
+
...agingData,
|
|
332
|
+
agingBonus,
|
|
333
|
+
lastAgingCheck: now,
|
|
334
|
+
},
|
|
335
|
+
};
|
|
336
|
+
// Note: BullMQ doesn't have a direct method to update job data
|
|
337
|
+
// The priority has been updated, and we track aging state separately
|
|
338
|
+
// In a real implementation, you might store this in Redis or accept
|
|
339
|
+
// that job.data.__aging__ won't be persisted after priority change
|
|
340
|
+
jobsBoosted++;
|
|
341
|
+
logger_js_1.logger.log({
|
|
342
|
+
timestamp: now,
|
|
343
|
+
level: "debug",
|
|
344
|
+
kind: "system",
|
|
345
|
+
message: `[BullMQPriorityAgingService] Boosted job ${job.id} priority: ${agingData.originalPriority} → ${effectivePriority} (bonus: ${agingBonus})`,
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
catch (error) {
|
|
349
|
+
logger_js_1.logger.log({
|
|
350
|
+
timestamp: now,
|
|
351
|
+
level: "error",
|
|
352
|
+
kind: "system",
|
|
353
|
+
message: `[BullMQPriorityAgingService] Failed to update priority for job ${job.id}: ${error}`,
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
const averageWaitTimeMs = jobsChecked > 0 ? totalWaitTimeMs / jobsChecked : 0;
|
|
359
|
+
if (jobsBoosted > 0 || jobsChecked > 0) {
|
|
360
|
+
logger_js_1.logger.log({
|
|
361
|
+
timestamp: now,
|
|
362
|
+
level: "info",
|
|
363
|
+
kind: "system",
|
|
364
|
+
message: `[BullMQPriorityAgingService] Aging check complete: ${jobsChecked} checked, ${jobsBoosted} boosted, avg wait: ${Math.round(averageWaitTimeMs / 1000)}s`,
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
return {
|
|
368
|
+
jobsChecked,
|
|
369
|
+
jobsBoosted,
|
|
370
|
+
averageWaitTimeMs,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
catch (error) {
|
|
374
|
+
logger_js_1.logger.log({
|
|
375
|
+
timestamp: now,
|
|
376
|
+
level: "error",
|
|
377
|
+
kind: "system",
|
|
378
|
+
message: `[BullMQPriorityAgingService] Error during aging check: ${error}`,
|
|
379
|
+
});
|
|
380
|
+
return {
|
|
381
|
+
jobsChecked,
|
|
382
|
+
jobsBoosted,
|
|
383
|
+
averageWaitTimeMs: jobsChecked > 0 ? totalWaitTimeMs / jobsChecked : 0,
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
exports.BullMQPriorityAgingService = BullMQPriorityAgingService;
|
|
389
|
+
exports.default = BullMQPriorityAgingService;
|
|
390
|
+
//# sourceMappingURL=bullmq-priority-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bullmq-priority-service.js","sourceRoot":"","sources":["../../src/jobs/bullmq-priority-service.ts"],"names":[],"mappings":";;;;;;AAAA,mCAA4C;AAC5C,sDAA4B;AAC5B,oDAA8C;AAoC9C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAa,0BAA0B;IAClB,iBAAiB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;IACjD,eAAe,GAAG,CAAC,CAAC;IACpB,yBAAyB,GAAG,KAAK,CAAC,CAAC,WAAW;IAC9C,0BAA0B,GAAG,GAAG,CAAC;IAE1C,KAAK,CAAQ;IACb,WAAW,GAAkB,IAAI,CAAC;IAClC,gBAAgB,GAAiB,IAAI,CAAC;IACtC,eAAe,CAAS;IACxB,eAAe,CAAS;IACxB,SAAS,CAAS;IAClB,UAAU,CAAQ;IAClB,UAAU,GAAG,KAAK,CAAC;IACnB,aAAa,GAA0B,IAAI,CAAC;IAEpD;;;;;;OAMG;IACH,YAAY,SAAiB,EAAE,UAAiB,EAAE,OAAqC;QACnF,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,eAAe,GAAG,OAAO,EAAE,eAAe,IAAI,IAAI,CAAC,yBAAyB,CAAC;QAClF,IAAI,CAAC,eAAe,GAAG,OAAO,EAAE,eAAe,IAAI,IAAI,CAAC,0BAA0B,CAAC;QAEnF,8DAA8D;QAC9D,IAAI,CAAC,KAAK,GAAG,IAAI,cAAK,CAAC,SAAS,EAAE;YAC9B,UAAU;YACV,iBAAiB,EAAE;gBACf,gBAAgB,EAAE,KAAK;gBACvB,YAAY,EAAE,KAAK;aACtB;SACJ,CAAC,CAAC;IACP,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,KAAK;QACP,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAClB,kBAAM,CAAC,GAAG,CAAC;gBACP,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;gBACrB,KAAK,EAAE,MAAM;gBACb,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,mEAAmE,IAAI,CAAC,SAAS,EAAE;aAC/F,CAAC,CAAC;YACH,OAAO;QACX,CAAC;QAED,kBAAM,CAAC,GAAG,CAAC;YACP,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,KAAK,EAAE,MAAM;YACb,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,kEAAkE,IAAI,CAAC,SAAS,EAAE;SAC9F,CAAC,CAAC;QAEH,6DAA6D;QAC7D,8EAA8E;QAC9E,MAAM,cAAc,GAAG,GAAG,IAAI,CAAC,SAAS,QAAQ,CAAC;QACjD,IAAI,CAAC,gBAAgB,GAAG,IAAI,iBAAK,CAAC;YAC9B,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI;YAClC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI;YAClC,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ;YAC1C,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE;YAC9B,oBAAoB,EAAE,IAAI;YAC1B,gBAAgB,EAAE,IAAI;YACtB,kBAAkB,EAAE,KAAK;SAC5B,CAAC,CAAC;QAEH,IAAI,CAAC,WAAW,GAAG,IAAI,eAAM,CACzB,cAAc,EACd,KAAK,IAAI,EAAE;YACP,oCAAoC;YACpC,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACnC,CAAC,EACD;YACI,UAAU,EAAE,IAAI,CAAC,gBAAgB;YACjC,WAAW,EAAE,CAAC;SACjB,CACJ,CAAC;QAEF,uDAAuD;QACvD,IAAI,CAAC,aAAa,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;YACxC,IAAI,CAAC;gBACD,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACnC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,kBAAM,CAAC,GAAG,CAAC;oBACP,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;oBACrB,KAAK,EAAE,OAAO;oBACd,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,0DAA0D,KAAK,EAAE;iBAC7E,CAAC,CAAC;YACP,CAAC;QACL,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAEzB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QAEvB,kBAAM,CAAC,GAAG,CAAC;YACP,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,KAAK,EAAE,MAAM;YACb,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,iEAAiE,IAAI,CAAC,SAAS,EAAE;SAC7F,CAAC,CAAC;IACP,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,IAAI;QACN,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACnB,OAAO;QACX,CAAC;QAED,kBAAM,CAAC,GAAG,CAAC;YACP,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,KAAK,EAAE,MAAM;YACb,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,kEAAkE,IAAI,CAAC,SAAS,EAAE;SAC9F,CAAC,CAAC;QAEH,qBAAqB;QACrB,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAClC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC9B,CAAC;QAED,yBAAyB;QACzB,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACnB,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;YAC/B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC5B,CAAC;QAED,8BAA8B;QAC9B,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxB,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;YACnC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QACjC,CAAC;QAED,6BAA6B;QAC7B,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAEzB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QAExB,kBAAM,CAAC,GAAG,CAAC;YACP,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,KAAK,EAAE,MAAM;YACb,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,iEAAiE,IAAI,CAAC,SAAS,EAAE;SAC7F,CAAC,CAAC;IACP,CAAC;IAED;;;;OAIG;IACH,SAAS;QACL,OAAO,IAAI,CAAC,UAAU,CAAC;IAC3B,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,UAAU;QAKZ,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACzE,CAAC;QAED,OAAO,IAAI,CAAC,iBAAiB,EAAE,CAAC;IACpC,CAAC;IAED;;;;;;;;;;OAUG;IACH,MAAM,CAAC,0BAA0B,CAC7B,YAAoB,EACpB,SAAiB,EACjB,GAAY;QAEZ,MAAM,WAAW,GAAG,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACtC,MAAM,UAAU,GAAG,WAAW,GAAG,SAAS,CAAC;QAE3C,gDAAgD;QAChD,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;QAC/D,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;QAE7C,0EAA0E;QAC1E,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC,CAAC;QAEjE,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,CAAC;IAC7C,CAAC;IAED;;;;;;;;;;OAUG;IACH,MAAM,CAAC,gBAAgB,CAAC,cAAsB;QAC1C,MAAM,kBAAkB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC,CAAC;QACrE,6EAA6E;QAC7E,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,kBAAkB,CAAC,GAAG,QAAQ,CAAC,CAAC;IAC5D,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,kBAAkB,CAAC,cAAsB;QAC5C,MAAM,cAAc,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC,CAAC;QACjE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC,CAAC;IACrD,CAAC;IAED;;;;;;;;;OASG;IACH,MAAM,CAAC,cAAc,CACjB,OAAgB,EAChB,QAAgB;QAEhB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,kBAAkB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC;QAE/D,OAAO;YACH,OAAO;YACP,SAAS,EAAE;gBACP,gBAAgB,EAAE,kBAAkB;gBACpC,UAAU,EAAE,CAAC;gBACb,SAAS,EAAE,GAAG;gBACd,cAAc,EAAE,GAAG;aACtB;SACJ,CAAC;IACN,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,gBAAgB,CAAC,OAAgB;QACpC,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,WAAW,IAAI,OAAO,EAAE,CAAC;YAC5E,MAAM,KAAK,GAAI,OAAmC,CAAC,SAAS,CAAC;YAC7D,IACI,OAAO,KAAK,KAAK,QAAQ;gBACzB,KAAK,KAAK,IAAI;gBACd,kBAAkB,IAAI,KAAK;gBAC3B,YAAY,IAAI,KAAK;gBACrB,WAAW,IAAI,KAAK;gBACpB,gBAAgB,IAAI,KAAK,EAC3B,CAAC;gBACC,OAAO,KAAqB,CAAC;YACjC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,iBAAiB;QAK3B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,IAAI,eAAe,GAAG,CAAC,CAAC;QAExB,IAAI,CAAC;YACD,kCAAkC;YAClC,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;YAEzE,kBAAM,CAAC,GAAG,CAAC;gBACP,SAAS,EAAE,GAAG;gBACd,KAAK,EAAE,OAAO;gBACd,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,yCAAyC,WAAW,CAAC,MAAM,yBAAyB;aAChG,CAAC,CAAC;YAEH,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;gBAC5B,WAAW,EAAE,CAAC;gBAEd,MAAM,SAAS,GAAG,0BAA0B,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAExE,IAAI,CAAC,SAAS,EAAE,CAAC;oBACb,wCAAwC;oBACxC,SAAS;gBACb,CAAC;gBAED,MAAM,UAAU,GAAG,GAAG,GAAG,SAAS,CAAC,SAAS,CAAC;gBAC7C,eAAe,IAAI,UAAU,CAAC;gBAE9B,mCAAmC;gBACnC,MAAM,EAAE,iBAAiB,EAAE,UAAU,EAAE,GACnC,0BAA0B,CAAC,0BAA0B,CACjD,SAAS,CAAC,gBAAgB,EAC1B,SAAS,CAAC,SAAS,EACnB,GAAG,CACN,CAAC;gBAEN,qCAAqC;gBACrC,IAAI,UAAU,GAAG,SAAS,CAAC,UAAU,EAAE,CAAC;oBACpC,IAAI,CAAC;wBACD,8CAA8C;wBAC9C,MAAM,iBAAiB,GACnB,0BAA0B,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,CAAC;wBAEnE,2CAA2C;wBAC3C,MAAM,GAAG,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,iBAAiB,EAAE,CAAC,CAAC;wBAE1D,sCAAsC;wBACtC,MAAM,WAAW,GAAqB;4BAClC,GAAI,GAAG,CAAC,IAAyB;4BACjC,SAAS,EAAE;gCACP,GAAG,SAAS;gCACZ,UAAU;gCACV,cAAc,EAAE,GAAG;6BACtB;yBACJ,CAAC;wBAEF,+DAA+D;wBAC/D,qEAAqE;wBACrE,oEAAoE;wBACpE,mEAAmE;wBAEnE,WAAW,EAAE,CAAC;wBAEd,kBAAM,CAAC,GAAG,CAAC;4BACP,SAAS,EAAE,GAAG;4BACd,KAAK,EAAE,OAAO;4BACd,IAAI,EAAE,QAAQ;4BACd,OAAO,EAAE,4CAA4C,GAAG,CAAC,EAAE,cAAc,SAAS,CAAC,gBAAgB,MAAM,iBAAiB,YAAY,UAAU,GAAG;yBACtJ,CAAC,CAAC;oBACP,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACb,kBAAM,CAAC,GAAG,CAAC;4BACP,SAAS,EAAE,GAAG;4BACd,KAAK,EAAE,OAAO;4BACd,IAAI,EAAE,QAAQ;4BACd,OAAO,EAAE,kEAAkE,GAAG,CAAC,EAAE,KAAK,KAAK,EAAE;yBAChG,CAAC,CAAC;oBACP,CAAC;gBACL,CAAC;YACL,CAAC;YAED,MAAM,iBAAiB,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;YAE9E,IAAI,WAAW,GAAG,CAAC,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;gBACrC,kBAAM,CAAC,GAAG,CAAC;oBACP,SAAS,EAAE,GAAG;oBACd,KAAK,EAAE,MAAM;oBACb,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,sDAAsD,WAAW,aAAa,WAAW,uBAAuB,IAAI,CAAC,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC,GAAG;iBACnK,CAAC,CAAC;YACP,CAAC;YAED,OAAO;gBACH,WAAW;gBACX,WAAW;gBACX,iBAAiB;aACpB,CAAC;QACN,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,kBAAM,CAAC,GAAG,CAAC;gBACP,SAAS,EAAE,GAAG;gBACd,KAAK,EAAE,OAAO;gBACd,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,0DAA0D,KAAK,EAAE;aAC7E,CAAC,CAAC;YAEH,OAAO;gBACH,WAAW;gBACX,WAAW;gBACX,iBAAiB,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;aACzE,CAAC;QACN,CAAC;IACL,CAAC;CACJ;AAxaD,gEAwaC;AAED,kBAAe,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import Redis from "ioredis";
|
|
2
|
+
import { BullMQJobQueue } from "./bullmq-adapter.js";
|
|
3
|
+
/**
|
|
4
|
+
* Schedule preset values for common scheduling intervals
|
|
5
|
+
*/
|
|
6
|
+
export declare enum SchedulePreset {
|
|
7
|
+
RunNow = "RUN_NOW",
|
|
8
|
+
EveryMinute = "EVERY_MINUTE",
|
|
9
|
+
Every5Minutes = "EVERY_5_MINUTES",
|
|
10
|
+
Every10Minutes = "EVERY_10_MINUTES",
|
|
11
|
+
Every30Minutes = "EVERY_30_MINUTES",
|
|
12
|
+
Hourly = "HOURLY",
|
|
13
|
+
Every8Hours = "EVERY_8_HOURS",
|
|
14
|
+
Every16Hours = "EVERY_16_HOURS",
|
|
15
|
+
DailyMidnight = "DAILY_MIDNIGHT",
|
|
16
|
+
Weekly = "WEEKLY",
|
|
17
|
+
Monthly = "MONTHLY",
|
|
18
|
+
Quarterly = "QUARTERLY"
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Job configuration with cron expression
|
|
22
|
+
*/
|
|
23
|
+
type ScheduledJobCronConfig = {
|
|
24
|
+
name: string;
|
|
25
|
+
cron: string;
|
|
26
|
+
payload: unknown;
|
|
27
|
+
maxAttempts?: number;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Job configuration with schedule preset
|
|
31
|
+
*/
|
|
32
|
+
type ScheduledJobPresetConfig = {
|
|
33
|
+
name: string;
|
|
34
|
+
preset: SchedulePreset;
|
|
35
|
+
payload: unknown;
|
|
36
|
+
maxAttempts?: number;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Union type for scheduled job configurations
|
|
40
|
+
*/
|
|
41
|
+
export type ScheduledJob = ScheduledJobCronConfig | ScheduledJobPresetConfig;
|
|
42
|
+
/**
|
|
43
|
+
* BullMQ-based scheduler using JobSchedulers (v5.16+) for cron scheduling.
|
|
44
|
+
* Replaces setTimeout-based scheduling with persistent Redis-backed schedulers.
|
|
45
|
+
*/
|
|
46
|
+
export declare class BullMQScheduler {
|
|
47
|
+
private queue;
|
|
48
|
+
private scheduledJobNames;
|
|
49
|
+
/**
|
|
50
|
+
* Creates a new BullMQScheduler instance
|
|
51
|
+
* @param jobQueue - BullMQJobQueue adapter instance
|
|
52
|
+
* @param _connection - Redis connection (kept for interface compatibility)
|
|
53
|
+
*/
|
|
54
|
+
constructor(jobQueue: BullMQJobQueue, _connection: Redis);
|
|
55
|
+
/**
|
|
56
|
+
* Resolves a schedule preset to its cron expression
|
|
57
|
+
* @param preset - The schedule preset to resolve
|
|
58
|
+
* @returns The cron expression or null for RunNow
|
|
59
|
+
*/
|
|
60
|
+
private resolvePreset;
|
|
61
|
+
/**
|
|
62
|
+
* Validates and normalizes a scheduled job configuration
|
|
63
|
+
* @param job - The job configuration to validate
|
|
64
|
+
* @returns Normalized job configuration
|
|
65
|
+
*/
|
|
66
|
+
private validateJobConfig;
|
|
67
|
+
/**
|
|
68
|
+
* Schedules a job using either a cron expression or schedule preset.
|
|
69
|
+
* Uses BullMQ's upsertJobScheduler for persistent scheduling.
|
|
70
|
+
* @param job - The job configuration to schedule
|
|
71
|
+
*/
|
|
72
|
+
add(job: ScheduledJob): void;
|
|
73
|
+
/**
|
|
74
|
+
* Alias to schedule by functionName to align with function contexts.
|
|
75
|
+
* @param config - Configuration object with functionName and scheduling options
|
|
76
|
+
*/
|
|
77
|
+
schedule(config: {
|
|
78
|
+
functionName: string;
|
|
79
|
+
payload?: unknown;
|
|
80
|
+
maxAttempts?: number;
|
|
81
|
+
} & ({
|
|
82
|
+
preset: SchedulePreset;
|
|
83
|
+
cron?: never;
|
|
84
|
+
} | {
|
|
85
|
+
cron: string;
|
|
86
|
+
preset?: never;
|
|
87
|
+
})): void;
|
|
88
|
+
/**
|
|
89
|
+
* Cancels a scheduled job by name.
|
|
90
|
+
* Removes the JobScheduler from BullMQ.
|
|
91
|
+
* @param name - The name of the scheduled job to cancel
|
|
92
|
+
*/
|
|
93
|
+
cancel(name: string): void;
|
|
94
|
+
/**
|
|
95
|
+
* Stops all scheduled jobs.
|
|
96
|
+
* Removes all JobSchedulers from BullMQ.
|
|
97
|
+
*/
|
|
98
|
+
stopAll(): void;
|
|
99
|
+
/**
|
|
100
|
+
* Gets all scheduled job schedulers from BullMQ.
|
|
101
|
+
* @returns Array of scheduled job information
|
|
102
|
+
*/
|
|
103
|
+
getScheduledJobs(): Promise<Array<{
|
|
104
|
+
name: string;
|
|
105
|
+
pattern?: string;
|
|
106
|
+
every?: number;
|
|
107
|
+
nextRun?: number;
|
|
108
|
+
}>>;
|
|
109
|
+
}
|
|
110
|
+
export default BullMQScheduler;
|
|
111
|
+
//# sourceMappingURL=bullmq-scheduler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bullmq-scheduler.d.ts","sourceRoot":"","sources":["../../src/jobs/bullmq-scheduler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,SAAS,CAAC;AAE5B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD;;GAEG;AACH,oBAAY,cAAc;IACtB,MAAM,YAAY;IAClB,WAAW,iBAAiB;IAC5B,aAAa,oBAAoB;IACjC,cAAc,qBAAqB;IACnC,cAAc,qBAAqB;IACnC,MAAM,WAAW;IACjB,WAAW,kBAAkB;IAC7B,YAAY,mBAAmB;IAC/B,aAAa,mBAAmB;IAChC,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,SAAS,cAAc;CAC1B;AAoBD;;GAEG;AACH,KAAK,sBAAsB,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;GAEG;AACH,KAAK,wBAAwB,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,sBAAsB,GAAG,wBAAwB,CAAC;AAE7E;;;GAGG;AACH,qBAAa,eAAe;IACxB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,iBAAiB,CAA0B;IAEnD;;;;OAIG;gBACS,QAAQ,EAAE,cAAc,EAAE,WAAW,EAAE,KAAK;IAKxD;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAQrB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAoCzB;;;;OAIG;IACH,GAAG,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI;IAgF5B;;;OAGG;IACH,QAAQ,CACJ,MAAM,EAAE;QACJ,YAAY,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;KACxB,GAAG,CAAC;QAAE,MAAM,EAAE,cAAc,CAAC;QAAC,IAAI,CAAC,EAAE,KAAK,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,KAAK,CAAA;KAAE,CAAC,GAClF,IAAI;IAmBP;;;;OAIG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA4B1B;;;OAGG;IACH,OAAO,IAAI,IAAI;IAoCf;;;OAGG;IACG,gBAAgB,IAAI,OAAO,CAC7B,KAAK,CAAC;QACF,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC,CACL;CA4BJ;AAED,eAAe,eAAe,CAAC"}
|