@pattern-stack/codegen 0.8.0 → 0.9.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/CHANGELOG.md +70 -0
- package/dist/runtime/subsystems/auth/controllers/auth.controller.d.ts +1 -0
- package/dist/runtime/subsystems/auth/index.d.ts +2 -0
- package/dist/runtime/subsystems/auth/index.js +55 -0
- package/dist/runtime/subsystems/auth/index.js.map +1 -1
- package/dist/runtime/subsystems/auth/middleware/requester-context.d.ts +81 -0
- package/dist/runtime/subsystems/auth/middleware/requester-context.js +60 -0
- package/dist/runtime/subsystems/auth/middleware/requester-context.js.map +1 -0
- package/dist/runtime/subsystems/auth/protocols/user-context.d.ts +18 -0
- package/dist/runtime/subsystems/bridge/bridge-delivery-handler.js.map +1 -1
- package/dist/runtime/subsystems/bridge/bridge-outbox-drain-hook.js.map +1 -1
- package/dist/runtime/subsystems/bridge/bridge.module.d.ts +3 -0
- package/dist/runtime/subsystems/bridge/bridge.module.js +930 -275
- package/dist/runtime/subsystems/bridge/bridge.module.js.map +1 -1
- package/dist/runtime/subsystems/bridge/event-flow.service.js.map +1 -1
- package/dist/runtime/subsystems/bridge/index.d.ts +3 -0
- package/dist/runtime/subsystems/bridge/index.js +837 -182
- package/dist/runtime/subsystems/bridge/index.js.map +1 -1
- package/dist/runtime/subsystems/events/event-bus.drizzle-backend.d.ts +3 -1
- package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js +92 -1
- package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js.map +1 -1
- package/dist/runtime/subsystems/events/event-bus.memory-backend.d.ts +3 -1
- package/dist/runtime/subsystems/events/event-bus.memory-backend.js +99 -0
- package/dist/runtime/subsystems/events/event-bus.memory-backend.js.map +1 -1
- package/dist/runtime/subsystems/events/event-bus.redis-backend.js.map +1 -1
- package/dist/runtime/subsystems/events/event-keyset-cursor.d.ts +32 -0
- package/dist/runtime/subsystems/events/event-keyset-cursor.js +38 -0
- package/dist/runtime/subsystems/events/event-keyset-cursor.js.map +1 -0
- package/dist/runtime/subsystems/events/event-read.protocol.d.ts +94 -0
- package/dist/runtime/subsystems/events/event-read.protocol.js +9 -0
- package/dist/runtime/subsystems/events/event-read.protocol.js.map +1 -0
- package/dist/runtime/subsystems/events/events.module.js +177 -3
- package/dist/runtime/subsystems/events/events.module.js.map +1 -1
- package/dist/runtime/subsystems/events/events.tokens.d.ts +16 -1
- package/dist/runtime/subsystems/events/events.tokens.js +2 -0
- package/dist/runtime/subsystems/events/events.tokens.js.map +1 -1
- package/dist/runtime/subsystems/events/generated/bus.js.map +1 -1
- package/dist/runtime/subsystems/events/generated/index.js.map +1 -1
- package/dist/runtime/subsystems/events/index.d.ts +2 -1
- package/dist/runtime/subsystems/events/index.js +178 -3
- package/dist/runtime/subsystems/events/index.js.map +1 -1
- package/dist/runtime/subsystems/index.d.ts +2 -0
- package/dist/runtime/subsystems/index.js +1198 -264
- package/dist/runtime/subsystems/index.js.map +1 -1
- package/dist/runtime/subsystems/jobs/bullmq.config.d.ts +98 -0
- package/dist/runtime/subsystems/jobs/bullmq.config.js +143 -0
- package/dist/runtime/subsystems/jobs/bullmq.config.js.map +1 -0
- package/dist/runtime/subsystems/jobs/index.d.ts +6 -2
- package/dist/runtime/subsystems/jobs/index.js +861 -201
- package/dist/runtime/subsystems/jobs/index.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.d.ts +107 -0
- package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js +922 -0
- package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js.map +1 -0
- package/dist/runtime/subsystems/jobs/job-run-keyset-cursor.d.ts +52 -0
- package/dist/runtime/subsystems/jobs/job-run-keyset-cursor.js +57 -0
- package/dist/runtime/subsystems/jobs/job-run-keyset-cursor.js.map +1 -0
- package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.d.ts +2 -1
- package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.js +81 -1
- package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.d.ts +2 -1
- package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.js +81 -0
- package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-run-service.protocol.d.ts +74 -1
- package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.d.ts +48 -0
- package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js +374 -0
- package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js.map +1 -0
- package/dist/runtime/subsystems/jobs/job-worker.module.d.ts +42 -4
- package/dist/runtime/subsystems/jobs/job-worker.module.js +832 -178
- package/dist/runtime/subsystems/jobs/job-worker.module.js.map +1 -1
- package/dist/runtime/subsystems/jobs/jobs-domain.module.d.ts +10 -1
- package/dist/runtime/subsystems/jobs/jobs-domain.module.js +519 -20
- package/dist/runtime/subsystems/jobs/jobs-domain.module.js.map +1 -1
- package/dist/runtime/subsystems/jobs/pool-config.loader.d.ts +9 -1
- package/dist/runtime/subsystems/jobs/pool-config.loader.js +4 -0
- package/dist/runtime/subsystems/jobs/pool-config.loader.js.map +1 -1
- package/dist/runtime/subsystems/observability/index.d.ts +4 -3
- package/dist/runtime/subsystems/observability/index.js +109 -2
- package/dist/runtime/subsystems/observability/index.js.map +1 -1
- package/dist/runtime/subsystems/observability/observability.module.js +109 -2
- package/dist/runtime/subsystems/observability/observability.module.js.map +1 -1
- package/dist/runtime/subsystems/observability/observability.protocol.d.ts +63 -2
- package/dist/runtime/subsystems/observability/observability.service.d.ts +21 -3
- package/dist/runtime/subsystems/observability/observability.service.js +109 -2
- package/dist/runtime/subsystems/observability/observability.service.js.map +1 -1
- package/dist/runtime/subsystems/observability/reporters/bridge-metrics.reporter.d.ts +1 -0
- package/dist/runtime/subsystems/observability/reporters/index.d.ts +1 -0
- package/dist/src/cli/index.js +43 -7
- package/dist/src/cli/index.js.map +1 -1
- package/package.json +1 -1
- package/runtime/subsystems/auth/index.ts +8 -0
- package/runtime/subsystems/auth/middleware/requester-context.ts +141 -0
- package/runtime/subsystems/auth/protocols/user-context.ts +17 -0
- package/runtime/subsystems/bridge/bridge.module.ts +5 -0
- package/runtime/subsystems/events/event-bus.drizzle-backend.ts +109 -3
- package/runtime/subsystems/events/event-bus.memory-backend.ts +103 -1
- package/runtime/subsystems/events/event-keyset-cursor.ts +59 -0
- package/runtime/subsystems/events/event-read.protocol.ts +97 -0
- package/runtime/subsystems/events/events.module.ts +18 -2
- package/runtime/subsystems/events/events.tokens.ts +16 -0
- package/runtime/subsystems/events/index.ts +7 -0
- package/runtime/subsystems/jobs/bullmq.config.ts +125 -0
- package/runtime/subsystems/jobs/index.ts +22 -0
- package/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.ts +381 -0
- package/runtime/subsystems/jobs/job-run-keyset-cursor.ts +88 -0
- package/runtime/subsystems/jobs/job-run-service.drizzle-backend.ts +59 -1
- package/runtime/subsystems/jobs/job-run-service.memory-backend.ts +53 -0
- package/runtime/subsystems/jobs/job-run-service.protocol.ts +77 -0
- package/runtime/subsystems/jobs/job-worker.bullmq-backend.ts +311 -0
- package/runtime/subsystems/jobs/job-worker.module.ts +124 -10
- package/runtime/subsystems/jobs/jobs-domain.module.ts +40 -21
- package/runtime/subsystems/jobs/pool-config.loader.ts +11 -0
- package/runtime/subsystems/observability/index.ts +8 -0
- package/runtime/subsystems/observability/observability.protocol.ts +76 -0
- package/runtime/subsystems/observability/observability.service.ts +148 -1
- package/templates/entity/new/clean-lite-ps/prompt-extension.js +14 -12
- package/templates/relationship/new/prompt.js +8 -5
- package/templates/subsystem/jobs/worker.ejs.t +30 -7
- package/templates/subsystem/sync/sync-audit.schema.ejs.t +12 -16
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { DynamicModule } from '@nestjs/common';
|
|
2
|
+
import { BullMqExtensionsConfig } from './bullmq.config.js';
|
|
3
|
+
import 'bullmq';
|
|
4
|
+
import './pool-config.loader.js';
|
|
2
5
|
|
|
3
6
|
/**
|
|
4
7
|
* JobsDomainModule — `DynamicModule.forRoot({ backend })` factory wiring
|
|
@@ -32,7 +35,7 @@ interface DrizzleBackendExtensions {
|
|
|
32
35
|
pollIntervalMs?: number;
|
|
33
36
|
}
|
|
34
37
|
interface JobsDomainModuleOptions {
|
|
35
|
-
backend: 'drizzle' | 'memory';
|
|
38
|
+
backend: 'drizzle' | 'memory' | 'bullmq';
|
|
36
39
|
/**
|
|
37
40
|
* Backend-specific extensions. Only the matching backend's extensions
|
|
38
41
|
* are read at boot; non-matching keys are ignored. This is the
|
|
@@ -40,6 +43,12 @@ interface JobsDomainModuleOptions {
|
|
|
40
43
|
*/
|
|
41
44
|
extensions?: {
|
|
42
45
|
drizzle?: DrizzleBackendExtensions;
|
|
46
|
+
/**
|
|
47
|
+
* BullMQ backend extensions (BULLMQ-1). Snake_case mirrors the YAML
|
|
48
|
+
* under `jobs.extensions.bullmq`. `redis_url` falls back to
|
|
49
|
+
* `process.env.REDIS_URL` then `redis://localhost:6379`.
|
|
50
|
+
*/
|
|
51
|
+
bullmq?: BullMqExtensionsConfig;
|
|
43
52
|
};
|
|
44
53
|
/** Multi-tenancy opt-in. Wired by JOB-8; module signature stays stable. */
|
|
45
54
|
multiTenant?: boolean;
|
|
@@ -565,7 +565,58 @@ function notInStatus(statuses) {
|
|
|
565
565
|
|
|
566
566
|
// runtime/subsystems/jobs/job-run-service.drizzle-backend.ts
|
|
567
567
|
import { Inject as Inject2, Injectable as Injectable2 } from "@nestjs/common";
|
|
568
|
-
import { and as and2, asc, desc as desc2, eq as eq2, inArray as inArray2, isNull, sql as sql3 } from "drizzle-orm";
|
|
568
|
+
import { and as and2, asc, desc as desc2, eq as eq2, gte, inArray as inArray2, isNull, lt, or, sql as sql3 } from "drizzle-orm";
|
|
569
|
+
|
|
570
|
+
// runtime/subsystems/jobs/job-run-keyset-cursor.ts
|
|
571
|
+
var DEFAULT_LIST_LIMIT = 50;
|
|
572
|
+
var MAX_LIST_LIMIT = 200;
|
|
573
|
+
function clampLimit(limit) {
|
|
574
|
+
if (typeof limit !== "number" || !Number.isFinite(limit)) {
|
|
575
|
+
return DEFAULT_LIST_LIMIT;
|
|
576
|
+
}
|
|
577
|
+
const floored = Math.floor(limit);
|
|
578
|
+
if (floored < 1) return 1;
|
|
579
|
+
if (floored > MAX_LIST_LIMIT) return MAX_LIST_LIMIT;
|
|
580
|
+
return floored;
|
|
581
|
+
}
|
|
582
|
+
function encodeKeysetCursor(keyset) {
|
|
583
|
+
const tuple = [keyset.createdAt.toISOString(), keyset.id];
|
|
584
|
+
return Buffer.from(JSON.stringify(tuple), "utf8").toString("base64url");
|
|
585
|
+
}
|
|
586
|
+
function decodeKeysetCursor(cursor) {
|
|
587
|
+
try {
|
|
588
|
+
const json = Buffer.from(cursor, "base64url").toString("utf8");
|
|
589
|
+
const parsed = JSON.parse(json);
|
|
590
|
+
if (!Array.isArray(parsed) || parsed.length !== 2) return null;
|
|
591
|
+
const [iso, id] = parsed;
|
|
592
|
+
if (typeof iso !== "string" || typeof id !== "string") return null;
|
|
593
|
+
const createdAt = new Date(iso);
|
|
594
|
+
if (Number.isNaN(createdAt.getTime())) return null;
|
|
595
|
+
return { createdAt, id };
|
|
596
|
+
} catch {
|
|
597
|
+
return null;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
function toJobRunSummary(r) {
|
|
601
|
+
return {
|
|
602
|
+
runId: r.id,
|
|
603
|
+
rootRunId: r.rootRunId,
|
|
604
|
+
jobType: r.jobType,
|
|
605
|
+
pool: r.pool,
|
|
606
|
+
status: r.status,
|
|
607
|
+
scopeEntityType: r.scopeEntityType,
|
|
608
|
+
scopeEntityId: r.scopeEntityId,
|
|
609
|
+
tenantId: r.tenantId,
|
|
610
|
+
attempts: r.attempts,
|
|
611
|
+
errorMessage: r.error?.message ?? null,
|
|
612
|
+
runAt: r.runAt,
|
|
613
|
+
startedAt: r.startedAt,
|
|
614
|
+
finishedAt: r.finishedAt,
|
|
615
|
+
createdAt: r.createdAt
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
// runtime/subsystems/jobs/job-run-service.drizzle-backend.ts
|
|
569
620
|
var NON_TERMINAL_STATUSES = [
|
|
570
621
|
"pending",
|
|
571
622
|
"running",
|
|
@@ -688,6 +739,37 @@ var DrizzleJobRunService = class {
|
|
|
688
739
|
createdAt: r.createdAt
|
|
689
740
|
}));
|
|
690
741
|
}
|
|
742
|
+
async listJobRuns(query = {}) {
|
|
743
|
+
const limit = clampLimit(query.limit);
|
|
744
|
+
const conditions = [];
|
|
745
|
+
const tenantCond = this.tenantCondition("listJobRuns", query.tenantId);
|
|
746
|
+
if (tenantCond) conditions.push(tenantCond);
|
|
747
|
+
if (query.poolId) conditions.push(eq2(jobRuns.pool, query.poolId));
|
|
748
|
+
if (query.rootRunId) conditions.push(eq2(jobRuns.rootRunId, query.rootRunId));
|
|
749
|
+
if (query.status) conditions.push(eq2(jobRuns.status, query.status));
|
|
750
|
+
if (query.since) conditions.push(gte(jobRuns.createdAt, query.since));
|
|
751
|
+
if (query.cursor) {
|
|
752
|
+
const keyset = decodeKeysetCursor(query.cursor);
|
|
753
|
+
if (keyset) {
|
|
754
|
+
conditions.push(
|
|
755
|
+
or(
|
|
756
|
+
lt(jobRuns.createdAt, keyset.createdAt),
|
|
757
|
+
and2(
|
|
758
|
+
eq2(jobRuns.createdAt, keyset.createdAt),
|
|
759
|
+
lt(jobRuns.id, keyset.id)
|
|
760
|
+
)
|
|
761
|
+
)
|
|
762
|
+
);
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
const rows = await this.db.select().from(jobRuns).where(conditions.length > 0 ? and2(...conditions) : void 0).orderBy(desc2(jobRuns.createdAt), desc2(jobRuns.id)).limit(limit + 1);
|
|
766
|
+
const hasMore = rows.length > limit;
|
|
767
|
+
const page = hasMore ? rows.slice(0, limit) : rows;
|
|
768
|
+
const items = page.map(toJobRunSummary);
|
|
769
|
+
const last = page[page.length - 1];
|
|
770
|
+
const nextCursor = hasMore && last ? encodeKeysetCursor({ createdAt: last.createdAt, id: last.id }) : null;
|
|
771
|
+
return { items, nextCursor };
|
|
772
|
+
}
|
|
691
773
|
/**
|
|
692
774
|
* Internal helper used by cascade paths (not on the public protocol).
|
|
693
775
|
* Exposed as a public method on the concrete class so infrastructure
|
|
@@ -749,9 +831,384 @@ DrizzleJobStepService = __decorateClass([
|
|
|
749
831
|
__decorateParam(0, Inject3(DRIZZLE))
|
|
750
832
|
], DrizzleJobStepService);
|
|
751
833
|
|
|
834
|
+
// runtime/subsystems/jobs/job-orchestrator.bullmq-backend.ts
|
|
835
|
+
import { createHash } from "crypto";
|
|
836
|
+
import { Inject as Inject4, Injectable as Injectable4, Logger as Logger2, Optional } from "@nestjs/common";
|
|
837
|
+
import { eq as eq4 } from "drizzle-orm";
|
|
838
|
+
|
|
839
|
+
// runtime/subsystems/jobs/pool-config.loader.ts
|
|
840
|
+
import { existsSync, readFileSync } from "fs";
|
|
841
|
+
import { resolve } from "path";
|
|
842
|
+
import { parse as parseYaml } from "yaml";
|
|
843
|
+
var FRAMEWORK_POOLS = Object.freeze({
|
|
844
|
+
events_inbound: Object.freeze({
|
|
845
|
+
queue: "jobs-events-inbound",
|
|
846
|
+
concurrency: 20,
|
|
847
|
+
reserved: true,
|
|
848
|
+
description: "Inbound events drain (events subsystem outbox)."
|
|
849
|
+
}),
|
|
850
|
+
events_change: Object.freeze({
|
|
851
|
+
queue: "jobs-events-change",
|
|
852
|
+
concurrency: 30,
|
|
853
|
+
reserved: true,
|
|
854
|
+
description: "Change events drain (events subsystem outbox)."
|
|
855
|
+
}),
|
|
856
|
+
events_outbound: Object.freeze({
|
|
857
|
+
queue: "jobs-events-outbound",
|
|
858
|
+
concurrency: 10,
|
|
859
|
+
reserved: true,
|
|
860
|
+
description: "Outbound events drain (events subsystem outbox)."
|
|
861
|
+
}),
|
|
862
|
+
interactive: Object.freeze({
|
|
863
|
+
queue: "jobs-interactive",
|
|
864
|
+
concurrency: 20,
|
|
865
|
+
reserved: false,
|
|
866
|
+
description: "User-facing latency-sensitive jobs."
|
|
867
|
+
}),
|
|
868
|
+
batch: Object.freeze({
|
|
869
|
+
queue: "jobs-batch",
|
|
870
|
+
concurrency: 5,
|
|
871
|
+
reserved: false,
|
|
872
|
+
description: "Default pool for background jobs."
|
|
873
|
+
})
|
|
874
|
+
});
|
|
875
|
+
var RESERVED_POOL_NAMES = new Set(
|
|
876
|
+
Object.entries(FRAMEWORK_POOLS).filter(([, def]) => def.reserved).map(([name]) => name)
|
|
877
|
+
);
|
|
878
|
+
var cache = /* @__PURE__ */ new Map();
|
|
879
|
+
function loadPoolConfig(configPath) {
|
|
880
|
+
const resolved = resolve(configPath ?? `${process.cwd()}/codegen.config.yaml`);
|
|
881
|
+
const cached = cache.get(resolved);
|
|
882
|
+
if (cached) return cached;
|
|
883
|
+
const merged = /* @__PURE__ */ new Map();
|
|
884
|
+
for (const [name, def] of Object.entries(FRAMEWORK_POOLS)) {
|
|
885
|
+
merged.set(name, { ...def });
|
|
886
|
+
}
|
|
887
|
+
if (!existsSync(resolved)) {
|
|
888
|
+
cache.set(resolved, merged);
|
|
889
|
+
return merged;
|
|
890
|
+
}
|
|
891
|
+
let raw;
|
|
892
|
+
try {
|
|
893
|
+
raw = parseYaml(readFileSync(resolved, "utf8"));
|
|
894
|
+
} catch (err) {
|
|
895
|
+
throw new Error(
|
|
896
|
+
`pool-config.loader: failed to parse YAML at ${resolved}: ${err.message}`
|
|
897
|
+
);
|
|
898
|
+
}
|
|
899
|
+
const userPools = extractUserPools(raw);
|
|
900
|
+
for (const [name, userDef] of Object.entries(userPools)) {
|
|
901
|
+
const existing = merged.get(name);
|
|
902
|
+
if (existing) {
|
|
903
|
+
const next = {
|
|
904
|
+
queue: existing.queue,
|
|
905
|
+
concurrency: typeof userDef.concurrency === "number" ? userDef.concurrency : existing.concurrency,
|
|
906
|
+
reserved: existing.reserved,
|
|
907
|
+
description: userDef.description ?? existing.description
|
|
908
|
+
};
|
|
909
|
+
merged.set(name, next);
|
|
910
|
+
continue;
|
|
911
|
+
}
|
|
912
|
+
if (typeof userDef.queue !== "string" || userDef.queue.length === 0) {
|
|
913
|
+
throw new Error(
|
|
914
|
+
`pool-config.loader: pool '${name}' must declare a non-empty 'queue'.`
|
|
915
|
+
);
|
|
916
|
+
}
|
|
917
|
+
if (typeof userDef.concurrency !== "number" || userDef.concurrency <= 0) {
|
|
918
|
+
throw new Error(
|
|
919
|
+
`pool-config.loader: pool '${name}' must declare a positive 'concurrency'.`
|
|
920
|
+
);
|
|
921
|
+
}
|
|
922
|
+
if (userDef.reserved === true) {
|
|
923
|
+
throw new Error(
|
|
924
|
+
`pool-config.loader: user-defined pool '${name}' cannot set 'reserved: true' \u2014 reserved is framework-only.`
|
|
925
|
+
);
|
|
926
|
+
}
|
|
927
|
+
merged.set(name, {
|
|
928
|
+
queue: userDef.queue,
|
|
929
|
+
concurrency: userDef.concurrency,
|
|
930
|
+
reserved: false,
|
|
931
|
+
description: userDef.description
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
cache.set(resolved, merged);
|
|
935
|
+
return merged;
|
|
936
|
+
}
|
|
937
|
+
function extractUserPools(raw) {
|
|
938
|
+
if (!raw || typeof raw !== "object") return {};
|
|
939
|
+
const jobs2 = raw.jobs;
|
|
940
|
+
if (!jobs2 || typeof jobs2 !== "object") return {};
|
|
941
|
+
const pools = jobs2.pools;
|
|
942
|
+
if (!pools || typeof pools !== "object") return {};
|
|
943
|
+
const out = {};
|
|
944
|
+
for (const [name, def] of Object.entries(pools)) {
|
|
945
|
+
if (!def || typeof def !== "object") continue;
|
|
946
|
+
out[name] = def;
|
|
947
|
+
}
|
|
948
|
+
return out;
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
// runtime/subsystems/jobs/bullmq.config.ts
|
|
952
|
+
var BULLMQ_CONNECTION = /* @__PURE__ */ Symbol("BULLMQ_CONNECTION");
|
|
953
|
+
var BULLMQ_RESOLVED_CONFIG = /* @__PURE__ */ Symbol("BULLMQ_RESOLVED_CONFIG");
|
|
954
|
+
var DEFAULT_REDIS_URL = "redis://localhost:6379";
|
|
955
|
+
var DEFAULT_BULL_BOARD_MOUNT = "/admin/queues";
|
|
956
|
+
function resolveBullMqConfig(ext) {
|
|
957
|
+
const url = ext?.redis_url ?? process.env.REDIS_URL ?? DEFAULT_REDIS_URL;
|
|
958
|
+
const resolved = {
|
|
959
|
+
connection: { url },
|
|
960
|
+
queuePrefix: ext?.queue_prefix
|
|
961
|
+
};
|
|
962
|
+
if (ext?.bull_board?.enabled) {
|
|
963
|
+
resolved.bullBoard = {
|
|
964
|
+
enabled: true,
|
|
965
|
+
mountPath: ext.bull_board.mount_path ?? DEFAULT_BULL_BOARD_MOUNT
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
return resolved;
|
|
969
|
+
}
|
|
970
|
+
function resolvePoolQueueName(pool, config, poolConfig = loadPoolConfig()) {
|
|
971
|
+
const alias = poolConfig.get(pool)?.queue ?? pool;
|
|
972
|
+
const prefix = config?.queuePrefix;
|
|
973
|
+
return prefix ? `${prefix}:${alias}` : alias;
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
// runtime/subsystems/jobs/job-orchestrator.bullmq-backend.ts
|
|
977
|
+
function sha1JobId(idempotencyKey) {
|
|
978
|
+
return createHash("sha1").update(idempotencyKey).digest("hex");
|
|
979
|
+
}
|
|
980
|
+
var BullMQJobOrchestrator = class extends DrizzleJobOrchestrator {
|
|
981
|
+
constructor(db, multiTenant, connection, bullConfig = null) {
|
|
982
|
+
super(db, multiTenant);
|
|
983
|
+
this.connection = connection;
|
|
984
|
+
this.bullConfig = bullConfig;
|
|
985
|
+
this.bullDb = db;
|
|
986
|
+
}
|
|
987
|
+
connection;
|
|
988
|
+
bullConfig;
|
|
989
|
+
// TODO(logging-subsystem): swap to ILogger once ADR-028 lands
|
|
990
|
+
bullLogger = new Logger2(BullMQJobOrchestrator.name);
|
|
991
|
+
/** Lazily-opened `Queue` handles, one per pool. */
|
|
992
|
+
queues = /* @__PURE__ */ new Map();
|
|
993
|
+
/** Single FlowProducer for parent/child hierarchies. Lazily opened. */
|
|
994
|
+
_flow = null;
|
|
995
|
+
/**
|
|
996
|
+
* Cached `bullmq` value constructors, populated by `loadBullMq()` on first
|
|
997
|
+
* use (the `start`/`cancel`/`replay` entrypoints `await` it before touching
|
|
998
|
+
* a queue). Kept off the import graph so a `drizzle`-only consumer never
|
|
999
|
+
* resolves the optional `'bullmq'` package.
|
|
1000
|
+
*/
|
|
1001
|
+
QueueCtor = null;
|
|
1002
|
+
FlowProducerCtor = null;
|
|
1003
|
+
bullMqLoad = null;
|
|
1004
|
+
/**
|
|
1005
|
+
* Own reference to the Drizzle client. `DrizzleJobOrchestrator.db` is
|
|
1006
|
+
* `private` (can't be redeclared even privately in a subclass), and the
|
|
1007
|
+
* spec forbids touching that file — so the subclass keeps its own handle
|
|
1008
|
+
* under a distinct name (same instance, passed through to `super`) for the
|
|
1009
|
+
* cancel-cascade snapshot + definition/run loads below.
|
|
1010
|
+
*/
|
|
1011
|
+
bullDb;
|
|
1012
|
+
/**
|
|
1013
|
+
* Lazily load the optional `bullmq` package and cache its value
|
|
1014
|
+
* constructors. Idempotent (single in-flight promise). Throws a friendly,
|
|
1015
|
+
* actionable error when the consumer selected `backend: 'bullmq'` but did
|
|
1016
|
+
* not install the package — mirrors `createRedisClient` in the redis event
|
|
1017
|
+
* backend. Must be `await`ed before any `queueFor`/`flow` access.
|
|
1018
|
+
*/
|
|
1019
|
+
async loadBullMq() {
|
|
1020
|
+
if (this.QueueCtor && this.FlowProducerCtor) return;
|
|
1021
|
+
if (!this.bullMqLoad) {
|
|
1022
|
+
this.bullMqLoad = (async () => {
|
|
1023
|
+
try {
|
|
1024
|
+
const mod = await import("bullmq");
|
|
1025
|
+
this.QueueCtor = mod.Queue;
|
|
1026
|
+
this.FlowProducerCtor = mod.FlowProducer;
|
|
1027
|
+
} catch {
|
|
1028
|
+
throw new Error(
|
|
1029
|
+
'BullMQ backend requires the "bullmq" package. Install it with: npm install bullmq'
|
|
1030
|
+
);
|
|
1031
|
+
}
|
|
1032
|
+
})();
|
|
1033
|
+
}
|
|
1034
|
+
await this.bullMqLoad;
|
|
1035
|
+
}
|
|
1036
|
+
/**
|
|
1037
|
+
* Open (or reuse) the `Queue` for a pool. Synchronous — callers `await
|
|
1038
|
+
* loadBullMq()` first so `QueueCtor` is populated.
|
|
1039
|
+
*/
|
|
1040
|
+
queueFor(pool) {
|
|
1041
|
+
if (!this.QueueCtor) {
|
|
1042
|
+
throw new Error("BullMQJobOrchestrator: queueFor called before loadBullMq()");
|
|
1043
|
+
}
|
|
1044
|
+
const name = resolvePoolQueueName(pool, this.bullConfig);
|
|
1045
|
+
let q = this.queues.get(name);
|
|
1046
|
+
if (!q) {
|
|
1047
|
+
q = new this.QueueCtor(name, { connection: this.connection });
|
|
1048
|
+
this.queues.set(name, q);
|
|
1049
|
+
}
|
|
1050
|
+
return q;
|
|
1051
|
+
}
|
|
1052
|
+
flow() {
|
|
1053
|
+
if (!this.FlowProducerCtor) {
|
|
1054
|
+
throw new Error("BullMQJobOrchestrator: flow called before loadBullMq()");
|
|
1055
|
+
}
|
|
1056
|
+
if (!this._flow) {
|
|
1057
|
+
this._flow = new this.FlowProducerCtor({ connection: this.connection });
|
|
1058
|
+
}
|
|
1059
|
+
return this._flow;
|
|
1060
|
+
}
|
|
1061
|
+
// ==========================================================================
|
|
1062
|
+
// start — Postgres insert (super) + BullMQ dispatch
|
|
1063
|
+
// ==========================================================================
|
|
1064
|
+
async start(type, input, opts = {}, tx) {
|
|
1065
|
+
const run = await super.start(type, input, opts, tx);
|
|
1066
|
+
await this.dispatch(run, type);
|
|
1067
|
+
return run;
|
|
1068
|
+
}
|
|
1069
|
+
/**
|
|
1070
|
+
* Map a `job_run` row onto a BullMQ job via `queue.add`. When the run has a
|
|
1071
|
+
* `parentRunId` we attach it to the parent's existing BullMQ job through the
|
|
1072
|
+
* `parent: { id, queue }` opt — BullMQ then tracks the parent/child link in
|
|
1073
|
+
* its own graph. (The FlowProducer is reserved for whole-tree atomic
|
|
1074
|
+
* submits, exposed as an opt-in extension via `flowProducer()`; runtime
|
|
1075
|
+
* `ctx.spawnChild` is incremental, so `queue.add` with a parent ref is the
|
|
1076
|
+
* correct primitive here.)
|
|
1077
|
+
*
|
|
1078
|
+
* The `jobId` is colon-safe + stable: `sha1(dedupeKey)` when a dedupe key is
|
|
1079
|
+
* present (so the same logical key dedups), else the `job_run.id` UUID
|
|
1080
|
+
* (already colon-free).
|
|
1081
|
+
*
|
|
1082
|
+
* The domain `parentClosePolicy` cascade is still enforced in Postgres by
|
|
1083
|
+
* the shared `cancel` path — BullMQ's parent link is dispatch bookkeeping,
|
|
1084
|
+
* not the authority.
|
|
1085
|
+
*/
|
|
1086
|
+
async dispatch(run, type) {
|
|
1087
|
+
await this.loadBullMq();
|
|
1088
|
+
const def = await this.loadDefinition(type);
|
|
1089
|
+
const jobId = run.dedupeKey ? sha1JobId(run.dedupeKey) : run.id;
|
|
1090
|
+
const jobOpts = {
|
|
1091
|
+
jobId,
|
|
1092
|
+
...this.retryOpts(def),
|
|
1093
|
+
...this.dedupeOpts(run, def)
|
|
1094
|
+
};
|
|
1095
|
+
if (run.parentRunId) {
|
|
1096
|
+
const parentRow = await this.loadRun(run.parentRunId);
|
|
1097
|
+
if (parentRow) {
|
|
1098
|
+
const parentJobId = parentRow.dedupeKey ? sha1JobId(parentRow.dedupeKey) : parentRow.id;
|
|
1099
|
+
jobOpts.parent = {
|
|
1100
|
+
id: parentJobId,
|
|
1101
|
+
queue: resolvePoolQueueName(parentRow.pool, this.bullConfig)
|
|
1102
|
+
};
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
const payload = { runId: run.id, type, input: run.input };
|
|
1106
|
+
await this.queueFor(run.pool).add(type, payload, jobOpts);
|
|
1107
|
+
}
|
|
1108
|
+
/**
|
|
1109
|
+
* Opt-in extension (spec §Extensions): expose the FlowProducer for
|
|
1110
|
+
* consumers that want to submit a whole parent/child DAG atomically up
|
|
1111
|
+
* front, rather than incrementally via `ctx.spawnChild`. Backend-specific —
|
|
1112
|
+
* code using it is not portable to the Drizzle backend. Async because it
|
|
1113
|
+
* lazily loads the optional `bullmq` package on first use.
|
|
1114
|
+
*/
|
|
1115
|
+
async flowProducer() {
|
|
1116
|
+
await this.loadBullMq();
|
|
1117
|
+
return this.flow();
|
|
1118
|
+
}
|
|
1119
|
+
retryOpts(def) {
|
|
1120
|
+
const policy = def.retryPolicy;
|
|
1121
|
+
if (!policy) return {};
|
|
1122
|
+
return {
|
|
1123
|
+
attempts: policy.attempts,
|
|
1124
|
+
backoff: {
|
|
1125
|
+
type: policy.backoff === "exponential" ? "exponential" : "fixed",
|
|
1126
|
+
delay: policy.baseMs
|
|
1127
|
+
}
|
|
1128
|
+
};
|
|
1129
|
+
}
|
|
1130
|
+
dedupeOpts(run, def) {
|
|
1131
|
+
if (!run.dedupeKey || !def.dedupeWindowMs) return {};
|
|
1132
|
+
return {
|
|
1133
|
+
deduplication: {
|
|
1134
|
+
id: sha1JobId(run.dedupeKey),
|
|
1135
|
+
ttl: def.dedupeWindowMs
|
|
1136
|
+
}
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1139
|
+
// ==========================================================================
|
|
1140
|
+
// cancel — Postgres cascade (super) + remove from queue
|
|
1141
|
+
// ==========================================================================
|
|
1142
|
+
async cancel(runId, opts = {}) {
|
|
1143
|
+
const target = await this.loadRun(runId);
|
|
1144
|
+
await super.cancel(runId, opts);
|
|
1145
|
+
if (!target) return;
|
|
1146
|
+
await this.loadBullMq();
|
|
1147
|
+
await this.removeFromQueue(target);
|
|
1148
|
+
if (opts.cascade === false) return;
|
|
1149
|
+
const descendants = await this.bullDb.select().from(jobRuns).where(eq4(jobRuns.rootRunId, target.rootRunId));
|
|
1150
|
+
for (const child of descendants) {
|
|
1151
|
+
if (child.id === runId) continue;
|
|
1152
|
+
await this.removeFromQueue(child);
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
async removeFromQueue(run) {
|
|
1156
|
+
const jobId = run.dedupeKey ? sha1JobId(run.dedupeKey) : run.id;
|
|
1157
|
+
try {
|
|
1158
|
+
const job = await this.queueFor(run.pool).getJob(jobId);
|
|
1159
|
+
if (job) await job.remove();
|
|
1160
|
+
} catch (err) {
|
|
1161
|
+
this.bullLogger.warn(
|
|
1162
|
+
`cancel: could not remove BullMQ job ${jobId} (pool=${run.pool}): ${err.message}`
|
|
1163
|
+
);
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
// ==========================================================================
|
|
1167
|
+
// replay — Postgres reset (super) + re-enqueue
|
|
1168
|
+
// ==========================================================================
|
|
1169
|
+
async replay(runId) {
|
|
1170
|
+
const run = await super.replay(runId);
|
|
1171
|
+
await this.dispatch(run, run.jobType);
|
|
1172
|
+
return run;
|
|
1173
|
+
}
|
|
1174
|
+
// ==========================================================================
|
|
1175
|
+
// Internals
|
|
1176
|
+
// ==========================================================================
|
|
1177
|
+
async loadDefinition(type) {
|
|
1178
|
+
const [def] = await this.bullDb.select().from(jobs).where(eq4(jobs.type, type)).limit(1);
|
|
1179
|
+
if (!def) {
|
|
1180
|
+
throw new Error(`BullMQJobOrchestrator: no job definition for '${type}'`);
|
|
1181
|
+
}
|
|
1182
|
+
return def;
|
|
1183
|
+
}
|
|
1184
|
+
async loadRun(id) {
|
|
1185
|
+
const [row] = await this.bullDb.select().from(jobRuns).where(eq4(jobRuns.id, id)).limit(1);
|
|
1186
|
+
return row ?? null;
|
|
1187
|
+
}
|
|
1188
|
+
/** Close all open queue + flow connections. Called on module destroy. */
|
|
1189
|
+
async closeConnections() {
|
|
1190
|
+
for (const q of this.queues.values()) {
|
|
1191
|
+
await q.close().catch(() => void 0);
|
|
1192
|
+
}
|
|
1193
|
+
this.queues.clear();
|
|
1194
|
+
if (this._flow) {
|
|
1195
|
+
await this._flow.close().catch(() => void 0);
|
|
1196
|
+
this._flow = null;
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
};
|
|
1200
|
+
BullMQJobOrchestrator = __decorateClass([
|
|
1201
|
+
Injectable4(),
|
|
1202
|
+
__decorateParam(0, Inject4(DRIZZLE)),
|
|
1203
|
+
__decorateParam(1, Inject4(JOBS_MULTI_TENANT)),
|
|
1204
|
+
__decorateParam(2, Inject4(BULLMQ_CONNECTION)),
|
|
1205
|
+
__decorateParam(3, Optional()),
|
|
1206
|
+
__decorateParam(3, Inject4(BULLMQ_RESOLVED_CONFIG))
|
|
1207
|
+
], BullMQJobOrchestrator);
|
|
1208
|
+
|
|
752
1209
|
// runtime/subsystems/jobs/job-orchestrator.memory-backend.ts
|
|
753
1210
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
754
|
-
import { Inject as
|
|
1211
|
+
import { Inject as Inject5, Injectable as Injectable5, Logger as Logger3, Optional as Optional2 } from "@nestjs/common";
|
|
755
1212
|
|
|
756
1213
|
// runtime/subsystems/jobs/job-handler.base.ts
|
|
757
1214
|
var JOB_HANDLER_REGISTRY = /* @__PURE__ */ new Map();
|
|
@@ -814,7 +1271,7 @@ var MemoryJobOrchestrator = class {
|
|
|
814
1271
|
stepService;
|
|
815
1272
|
multiTenant;
|
|
816
1273
|
moduleRef;
|
|
817
|
-
logger = new
|
|
1274
|
+
logger = new Logger3(MemoryJobOrchestrator.name);
|
|
818
1275
|
mutex = new PromiseMutex();
|
|
819
1276
|
handlerRegistry = /* @__PURE__ */ new Map();
|
|
820
1277
|
/**
|
|
@@ -1163,7 +1620,7 @@ var MemoryJobOrchestrator = class {
|
|
|
1163
1620
|
run,
|
|
1164
1621
|
step: this.makeStepFn(run),
|
|
1165
1622
|
spawnChild: this.makeSpawnFn(run),
|
|
1166
|
-
logger: new
|
|
1623
|
+
logger: new Logger3(`JobRun:${run.id}`)
|
|
1167
1624
|
};
|
|
1168
1625
|
const attemptsBefore = run.attempts ?? 0;
|
|
1169
1626
|
try {
|
|
@@ -1336,9 +1793,9 @@ var MemoryJobOrchestrator = class {
|
|
|
1336
1793
|
}
|
|
1337
1794
|
};
|
|
1338
1795
|
MemoryJobOrchestrator = __decorateClass([
|
|
1339
|
-
|
|
1340
|
-
__decorateParam(2,
|
|
1341
|
-
__decorateParam(3,
|
|
1796
|
+
Injectable5(),
|
|
1797
|
+
__decorateParam(2, Inject5(JOBS_MULTI_TENANT)),
|
|
1798
|
+
__decorateParam(3, Optional2())
|
|
1342
1799
|
], MemoryJobOrchestrator);
|
|
1343
1800
|
function classifyError(err, policy, currentAttempts) {
|
|
1344
1801
|
if (!policy) return "fail";
|
|
@@ -1372,7 +1829,7 @@ function serialiseError(err, attempt, retryable) {
|
|
|
1372
1829
|
}
|
|
1373
1830
|
|
|
1374
1831
|
// runtime/subsystems/jobs/job-run-service.memory-backend.ts
|
|
1375
|
-
import { Inject as
|
|
1832
|
+
import { Inject as Inject6, Injectable as Injectable6 } from "@nestjs/common";
|
|
1376
1833
|
var NON_TERMINAL_STATUSES2 = [
|
|
1377
1834
|
"pending",
|
|
1378
1835
|
"running",
|
|
@@ -1489,6 +1946,38 @@ var MemoryJobRunService = class {
|
|
|
1489
1946
|
createdAt: r.createdAt
|
|
1490
1947
|
}));
|
|
1491
1948
|
}
|
|
1949
|
+
async listJobRuns(query = {}) {
|
|
1950
|
+
const limit = clampLimit(query.limit);
|
|
1951
|
+
const tenantCheck = this.tenantPredicate("listJobRuns", query.tenantId);
|
|
1952
|
+
const keyset = query.cursor ? decodeKeysetCursor(query.cursor) : null;
|
|
1953
|
+
const matched = [];
|
|
1954
|
+
for (const r of this.store.runs.values()) {
|
|
1955
|
+
if (tenantCheck && !tenantCheck(r)) continue;
|
|
1956
|
+
if (query.poolId && r.pool !== query.poolId) continue;
|
|
1957
|
+
if (query.rootRunId && r.rootRunId !== query.rootRunId) continue;
|
|
1958
|
+
if (query.status && r.status !== query.status) continue;
|
|
1959
|
+
if (query.since && r.createdAt.getTime() < query.since.getTime()) continue;
|
|
1960
|
+
matched.push(r);
|
|
1961
|
+
}
|
|
1962
|
+
matched.sort((a, b) => {
|
|
1963
|
+
const dt = b.createdAt.getTime() - a.createdAt.getTime();
|
|
1964
|
+
if (dt !== 0) return dt;
|
|
1965
|
+
return a.id < b.id ? 1 : a.id > b.id ? -1 : 0;
|
|
1966
|
+
});
|
|
1967
|
+
const seeked = keyset ? matched.filter((r) => {
|
|
1968
|
+
const ct = r.createdAt.getTime();
|
|
1969
|
+
const kt = keyset.createdAt.getTime();
|
|
1970
|
+
if (ct < kt) return true;
|
|
1971
|
+
if (ct > kt) return false;
|
|
1972
|
+
return r.id < keyset.id;
|
|
1973
|
+
}) : matched;
|
|
1974
|
+
const hasMore = seeked.length > limit;
|
|
1975
|
+
const page = hasMore ? seeked.slice(0, limit) : seeked;
|
|
1976
|
+
const items = page.map(toJobRunSummary);
|
|
1977
|
+
const last = page[page.length - 1];
|
|
1978
|
+
const nextCursor = hasMore && last ? encodeKeysetCursor({ createdAt: last.createdAt, id: last.id }) : null;
|
|
1979
|
+
return { items, nextCursor };
|
|
1980
|
+
}
|
|
1492
1981
|
/**
|
|
1493
1982
|
* Direct lookup. Not on the protocol — concrete-class convenience for
|
|
1494
1983
|
* tests. Matches `DrizzleJobRunService.findByRootRunId` in spirit; both
|
|
@@ -1507,9 +1996,9 @@ var MemoryJobRunService = class {
|
|
|
1507
1996
|
}
|
|
1508
1997
|
};
|
|
1509
1998
|
MemoryJobRunService = __decorateClass([
|
|
1510
|
-
|
|
1511
|
-
__decorateParam(1,
|
|
1512
|
-
__decorateParam(2,
|
|
1999
|
+
Injectable6(),
|
|
2000
|
+
__decorateParam(1, Inject6(JOB_ORCHESTRATOR)),
|
|
2001
|
+
__decorateParam(2, Inject6(JOBS_MULTI_TENANT))
|
|
1513
2002
|
], MemoryJobRunService);
|
|
1514
2003
|
function compareBy(a, b, order) {
|
|
1515
2004
|
switch (order) {
|
|
@@ -1527,7 +2016,7 @@ function compareBy(a, b, order) {
|
|
|
1527
2016
|
|
|
1528
2017
|
// runtime/subsystems/jobs/job-step-service.memory-backend.ts
|
|
1529
2018
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
1530
|
-
import { Injectable as
|
|
2019
|
+
import { Injectable as Injectable7 } from "@nestjs/common";
|
|
1531
2020
|
var MemoryJobStepService = class {
|
|
1532
2021
|
constructor(store) {
|
|
1533
2022
|
this.store = store;
|
|
@@ -1620,7 +2109,7 @@ var MemoryJobStepService = class {
|
|
|
1620
2109
|
}
|
|
1621
2110
|
};
|
|
1622
2111
|
MemoryJobStepService = __decorateClass([
|
|
1623
|
-
|
|
2112
|
+
Injectable7()
|
|
1624
2113
|
], MemoryJobStepService);
|
|
1625
2114
|
|
|
1626
2115
|
// runtime/subsystems/jobs/memory-job-store.ts
|
|
@@ -1642,7 +2131,6 @@ var MemoryJobStore = class {
|
|
|
1642
2131
|
// runtime/subsystems/jobs/jobs-domain.module.ts
|
|
1643
2132
|
var JobsDomainModule = class {
|
|
1644
2133
|
static forRoot(opts) {
|
|
1645
|
-
void opts.extensions;
|
|
1646
2134
|
const multiTenant = opts.multiTenant ?? false;
|
|
1647
2135
|
const providers = [
|
|
1648
2136
|
// JOB-8 — boolean provider consumed by the four service-layer backends.
|
|
@@ -1661,21 +2149,32 @@ var JobsDomainModule = class {
|
|
|
1661
2149
|
providers.push({ provide: JOB_ORCHESTRATOR, useExisting: MemoryJobOrchestrator });
|
|
1662
2150
|
providers.push(MemoryJobRunService);
|
|
1663
2151
|
providers.push({ provide: JOB_RUN_SERVICE, useExisting: MemoryJobRunService });
|
|
2152
|
+
} else if (opts.backend === "bullmq") {
|
|
2153
|
+
const resolved = resolveBullMqConfig(opts.extensions?.bullmq);
|
|
2154
|
+
providers.push({ provide: BULLMQ_CONNECTION, useValue: resolved.connection });
|
|
2155
|
+
providers.push({ provide: BULLMQ_RESOLVED_CONFIG, useValue: resolved });
|
|
2156
|
+
providers.push({ provide: JOB_ORCHESTRATOR, useClass: BullMQJobOrchestrator });
|
|
2157
|
+
providers.push({ provide: JOB_RUN_SERVICE, useClass: DrizzleJobRunService });
|
|
2158
|
+
providers.push({ provide: JOB_STEP_SERVICE, useClass: DrizzleJobStepService });
|
|
1664
2159
|
} else {
|
|
1665
2160
|
providers.push({ provide: JOB_ORCHESTRATOR, useClass: DrizzleJobOrchestrator });
|
|
1666
2161
|
providers.push({ provide: JOB_RUN_SERVICE, useClass: DrizzleJobRunService });
|
|
1667
2162
|
providers.push({ provide: JOB_STEP_SERVICE, useClass: DrizzleJobStepService });
|
|
1668
2163
|
}
|
|
2164
|
+
const exports = [
|
|
2165
|
+
JOB_ORCHESTRATOR,
|
|
2166
|
+
JOB_RUN_SERVICE,
|
|
2167
|
+
JOB_STEP_SERVICE,
|
|
2168
|
+
JOBS_MULTI_TENANT
|
|
2169
|
+
];
|
|
2170
|
+
if (opts.backend === "bullmq") {
|
|
2171
|
+
exports.push(BULLMQ_CONNECTION, BULLMQ_RESOLVED_CONFIG);
|
|
2172
|
+
}
|
|
1669
2173
|
return {
|
|
1670
2174
|
module: JobsDomainModule,
|
|
1671
2175
|
global: true,
|
|
1672
2176
|
providers,
|
|
1673
|
-
exports
|
|
1674
|
-
JOB_ORCHESTRATOR,
|
|
1675
|
-
JOB_RUN_SERVICE,
|
|
1676
|
-
JOB_STEP_SERVICE,
|
|
1677
|
-
JOBS_MULTI_TENANT
|
|
1678
|
-
]
|
|
2177
|
+
exports
|
|
1679
2178
|
};
|
|
1680
2179
|
}
|
|
1681
2180
|
};
|