@medusajs/workflow-engine-redis 0.0.2-next-20240124093206
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 +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/initialize/index.d.ts +6 -0
- package/dist/initialize/index.d.ts.map +1 -0
- package/dist/initialize/index.js +18 -0
- package/dist/joiner-config.d.ts +8 -0
- package/dist/joiner-config.d.ts.map +1 -0
- package/dist/joiner-config.js +34 -0
- package/dist/loaders/connection.d.ts +5 -0
- package/dist/loaders/connection.d.ts.map +1 -0
- package/dist/loaders/connection.js +41 -0
- package/dist/loaders/container.d.ts +3 -0
- package/dist/loaders/container.d.ts.map +1 -0
- package/dist/loaders/container.js +33 -0
- package/dist/loaders/index.d.ts +5 -0
- package/dist/loaders/index.d.ts.map +1 -0
- package/dist/loaders/index.js +20 -0
- package/dist/loaders/redis.d.ts +4 -0
- package/dist/loaders/redis.d.ts.map +1 -0
- package/dist/loaders/redis.js +54 -0
- package/dist/loaders/utils.d.ts +5 -0
- package/dist/loaders/utils.d.ts.map +1 -0
- package/dist/loaders/utils.js +9 -0
- package/dist/migrations/Migration20231228143900.d.ts +6 -0
- package/dist/migrations/Migration20231228143900.d.ts.map +1 -0
- package/dist/migrations/Migration20231228143900.js +39 -0
- package/dist/models/index.d.ts +2 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js +8 -0
- package/dist/models/workflow-execution.d.ts +19 -0
- package/dist/models/workflow-execution.d.ts.map +1 -0
- package/dist/models/workflow-execution.js +97 -0
- package/dist/module-definition.d.ts +3 -0
- package/dist/module-definition.d.ts.map +1 -0
- package/dist/module-definition.js +22 -0
- package/dist/repositories/index.d.ts +3 -0
- package/dist/repositories/index.d.ts.map +1 -0
- package/dist/repositories/index.js +7 -0
- package/dist/repositories/workflow-execution.d.ts +35 -0
- package/dist/repositories/workflow-execution.d.ts.map +1 -0
- package/dist/repositories/workflow-execution.js +9 -0
- package/dist/schema/index.d.ts +3 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +28 -0
- package/dist/services/index.d.ts +4 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +19 -0
- package/dist/services/workflow-execution.d.ts +16 -0
- package/dist/services/workflow-execution.d.ts.map +1 -0
- package/dist/services/workflow-execution.js +13 -0
- package/dist/services/workflow-orchestrator.d.ts +73 -0
- package/dist/services/workflow-orchestrator.d.ts.map +1 -0
- package/dist/services/workflow-orchestrator.js +381 -0
- package/dist/services/workflows-module.d.ts +43 -0
- package/dist/services/workflows-module.d.ts.map +1 -0
- package/dist/services/workflows-module.js +128 -0
- package/dist/types/index.d.ts +30 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +17 -0
- package/dist/utils/workflow-orchestrator-storage.d.ts +35 -0
- package/dist/utils/workflow-orchestrator-storage.d.ts.map +1 -0
- package/dist/utils/workflow-orchestrator-storage.js +182 -0
- package/package.json +61 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
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;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var _a;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.WorkflowsModuleService = void 0;
|
|
17
|
+
const utils_1 = require("@medusajs/utils");
|
|
18
|
+
const joiner_config_1 = require("../joiner-config");
|
|
19
|
+
class WorkflowsModuleService {
|
|
20
|
+
constructor({ baseRepository, workflowExecutionService, workflowOrchestratorService, }, moduleDeclaration) {
|
|
21
|
+
this.moduleDeclaration = moduleDeclaration;
|
|
22
|
+
this.baseRepository_ = baseRepository;
|
|
23
|
+
this.workflowExecutionService_ = workflowExecutionService;
|
|
24
|
+
this.workflowOrchestratorService_ = workflowOrchestratorService;
|
|
25
|
+
}
|
|
26
|
+
__joinerConfig() {
|
|
27
|
+
return joiner_config_1.joinerConfig;
|
|
28
|
+
}
|
|
29
|
+
async listWorkflowExecution(filters = {}, config = {}, sharedContext = {}) {
|
|
30
|
+
const wfExecutions = await this.workflowExecutionService_.list(filters, config, sharedContext);
|
|
31
|
+
return this.baseRepository_.serialize(wfExecutions, {
|
|
32
|
+
populate: true,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
async listAndCountWorkflowExecution(filters = {}, config = {}, sharedContext = {}) {
|
|
36
|
+
const [wfExecutions, count] = await this.workflowExecutionService_.listAndCount(filters, config, sharedContext);
|
|
37
|
+
return [
|
|
38
|
+
await this.baseRepository_.serialize(wfExecutions, {
|
|
39
|
+
populate: true,
|
|
40
|
+
}),
|
|
41
|
+
count,
|
|
42
|
+
];
|
|
43
|
+
}
|
|
44
|
+
async run(workflowIdOrWorkflow, options = {}, context = {}) {
|
|
45
|
+
const ret = await this.workflowOrchestratorService_.run(workflowIdOrWorkflow, options, context);
|
|
46
|
+
return ret;
|
|
47
|
+
}
|
|
48
|
+
async getRunningTransaction(workflowId, transactionId, context = {}) {
|
|
49
|
+
return this.workflowOrchestratorService_.getRunningTransaction(workflowId, transactionId, context);
|
|
50
|
+
}
|
|
51
|
+
async setStepSuccess({ idempotencyKey, stepResponse, options, }, context = {}) {
|
|
52
|
+
return this.workflowOrchestratorService_.setStepSuccess({
|
|
53
|
+
idempotencyKey,
|
|
54
|
+
stepResponse,
|
|
55
|
+
options,
|
|
56
|
+
}, context);
|
|
57
|
+
}
|
|
58
|
+
async setStepFailure({ idempotencyKey, stepResponse, options, }, context = {}) {
|
|
59
|
+
return this.workflowOrchestratorService_.setStepFailure({
|
|
60
|
+
idempotencyKey,
|
|
61
|
+
stepResponse,
|
|
62
|
+
options,
|
|
63
|
+
}, context);
|
|
64
|
+
}
|
|
65
|
+
async subscribe(args, context = {}) {
|
|
66
|
+
return this.workflowOrchestratorService_.subscribe(args, context);
|
|
67
|
+
}
|
|
68
|
+
async unsubscribe(args, context = {}) {
|
|
69
|
+
return this.workflowOrchestratorService_.unsubscribe(args, context);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.WorkflowsModuleService = WorkflowsModuleService;
|
|
73
|
+
__decorate([
|
|
74
|
+
(0, utils_1.InjectManager)("baseRepository_"),
|
|
75
|
+
__param(2, (0, utils_1.MedusaContext)()),
|
|
76
|
+
__metadata("design:type", Function),
|
|
77
|
+
__metadata("design:paramtypes", [Object, Object, Object]),
|
|
78
|
+
__metadata("design:returntype", Promise)
|
|
79
|
+
], WorkflowsModuleService.prototype, "listWorkflowExecution", null);
|
|
80
|
+
__decorate([
|
|
81
|
+
(0, utils_1.InjectManager)("baseRepository_"),
|
|
82
|
+
__param(2, (0, utils_1.MedusaContext)()),
|
|
83
|
+
__metadata("design:type", Function),
|
|
84
|
+
__metadata("design:paramtypes", [Object, Object, Object]),
|
|
85
|
+
__metadata("design:returntype", Promise)
|
|
86
|
+
], WorkflowsModuleService.prototype, "listAndCountWorkflowExecution", null);
|
|
87
|
+
__decorate([
|
|
88
|
+
(0, utils_1.InjectSharedContext)(),
|
|
89
|
+
__param(2, (0, utils_1.MedusaContext)()),
|
|
90
|
+
__metadata("design:type", Function),
|
|
91
|
+
__metadata("design:paramtypes", [typeof (_a = typeof TWorkflow !== "undefined" && TWorkflow) === "function" ? _a : Object, Object, Object]),
|
|
92
|
+
__metadata("design:returntype", Promise)
|
|
93
|
+
], WorkflowsModuleService.prototype, "run", null);
|
|
94
|
+
__decorate([
|
|
95
|
+
(0, utils_1.InjectSharedContext)(),
|
|
96
|
+
__param(2, (0, utils_1.MedusaContext)()),
|
|
97
|
+
__metadata("design:type", Function),
|
|
98
|
+
__metadata("design:paramtypes", [String, String, Object]),
|
|
99
|
+
__metadata("design:returntype", Promise)
|
|
100
|
+
], WorkflowsModuleService.prototype, "getRunningTransaction", null);
|
|
101
|
+
__decorate([
|
|
102
|
+
(0, utils_1.InjectSharedContext)(),
|
|
103
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
104
|
+
__metadata("design:type", Function),
|
|
105
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
106
|
+
__metadata("design:returntype", Promise)
|
|
107
|
+
], WorkflowsModuleService.prototype, "setStepSuccess", null);
|
|
108
|
+
__decorate([
|
|
109
|
+
(0, utils_1.InjectSharedContext)(),
|
|
110
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
111
|
+
__metadata("design:type", Function),
|
|
112
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
113
|
+
__metadata("design:returntype", Promise)
|
|
114
|
+
], WorkflowsModuleService.prototype, "setStepFailure", null);
|
|
115
|
+
__decorate([
|
|
116
|
+
(0, utils_1.InjectSharedContext)(),
|
|
117
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
118
|
+
__metadata("design:type", Function),
|
|
119
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
120
|
+
__metadata("design:returntype", Promise)
|
|
121
|
+
], WorkflowsModuleService.prototype, "subscribe", null);
|
|
122
|
+
__decorate([
|
|
123
|
+
(0, utils_1.InjectSharedContext)(),
|
|
124
|
+
__param(1, (0, utils_1.MedusaContext)()),
|
|
125
|
+
__metadata("design:type", Function),
|
|
126
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
127
|
+
__metadata("design:returntype", Promise)
|
|
128
|
+
], WorkflowsModuleService.prototype, "unsubscribe", null);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Logger } from "@medusajs/types";
|
|
2
|
+
import { RedisOptions } from "ioredis";
|
|
3
|
+
export type InitializeModuleInjectableDependencies = {
|
|
4
|
+
logger?: Logger;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Module config type
|
|
8
|
+
*/
|
|
9
|
+
export type RedisWorkflowsOptions = {
|
|
10
|
+
/**
|
|
11
|
+
* Redis connection string
|
|
12
|
+
*/
|
|
13
|
+
url?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Queue name used for retries and timeouts
|
|
16
|
+
*/
|
|
17
|
+
queueName?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Redis client options
|
|
20
|
+
*/
|
|
21
|
+
options?: RedisOptions;
|
|
22
|
+
/**
|
|
23
|
+
* Optiona connection string and options to pub/sub
|
|
24
|
+
*/
|
|
25
|
+
pubsub?: {
|
|
26
|
+
url: string;
|
|
27
|
+
options?: RedisOptions;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAEtC,MAAM,MAAM,sCAAsC,GAAG;IACnD,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IAEZ;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;OAEG;IACH,OAAO,CAAC,EAAE,YAAY,CAAA;IAEtB;;OAEG;IACH,MAAM,CAAC,EAAE;QACP,GAAG,EAAE,MAAM,CAAA;QACX,OAAO,CAAC,EAAE,YAAY,CAAA;KACvB,CAAA;CACF,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./workflow-orchestrator-storage"), exports);
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { DistributedTransaction, DistributedTransactionStorage, TransactionCheckpoint, TransactionStep } from "@medusajs/orchestration";
|
|
2
|
+
import { WorkflowExecutionService } from "../services";
|
|
3
|
+
import Redis from "ioredis";
|
|
4
|
+
export declare class RedisDistributedTransactionStorage extends DistributedTransactionStorage {
|
|
5
|
+
private static TTL_AFTER_COMPLETED;
|
|
6
|
+
private workflowExecutionService_;
|
|
7
|
+
private workflowOrchestratorService_;
|
|
8
|
+
private redisClient;
|
|
9
|
+
private queue;
|
|
10
|
+
private worker;
|
|
11
|
+
constructor({ workflowExecutionService, redisConnection, redisWorkerConnection, redisQueueName, }: {
|
|
12
|
+
workflowExecutionService: WorkflowExecutionService;
|
|
13
|
+
redisConnection: Redis;
|
|
14
|
+
redisWorkerConnection: Redis;
|
|
15
|
+
redisQueueName: string;
|
|
16
|
+
});
|
|
17
|
+
setWorkflowOrchestratorService(workflowOrchestratorService: any): void;
|
|
18
|
+
private saveToDb;
|
|
19
|
+
private deleteFromDb;
|
|
20
|
+
private executeTransaction;
|
|
21
|
+
private stringifyWithSymbol;
|
|
22
|
+
private jsonWithSymbol;
|
|
23
|
+
get(key: string): Promise<TransactionCheckpoint | undefined>;
|
|
24
|
+
list(): Promise<TransactionCheckpoint[]>;
|
|
25
|
+
save(key: string, data: TransactionCheckpoint, ttl?: number): Promise<void>;
|
|
26
|
+
scheduleRetry(transaction: DistributedTransaction, step: TransactionStep, timestamp: number, interval: number): Promise<void>;
|
|
27
|
+
clearRetry(transaction: DistributedTransaction, step: TransactionStep): Promise<void>;
|
|
28
|
+
scheduleTransactionTimeout(transaction: DistributedTransaction, timestamp: number, interval: number): Promise<void>;
|
|
29
|
+
clearTransactionTimeout(transaction: DistributedTransaction): Promise<void>;
|
|
30
|
+
scheduleStepTimeout(transaction: DistributedTransaction, step: TransactionStep, timestamp: number, interval: number): Promise<void>;
|
|
31
|
+
clearStepTimeout(transaction: DistributedTransaction, step: TransactionStep): Promise<void>;
|
|
32
|
+
private getJobId;
|
|
33
|
+
private removeJob;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=workflow-orchestrator-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-orchestrator-storage.d.ts","sourceRoot":"","sources":["../../src/utils/workflow-orchestrator-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,6BAA6B,EAC7B,qBAAqB,EACrB,eAAe,EAChB,MAAM,yBAAyB,CAAA;AAEhC,OAAO,EACL,wBAAwB,EAEzB,MAAM,WAAW,CAAA;AAElB,OAAO,KAAK,MAAM,SAAS,CAAA;AAS3B,qBAAa,kCAAmC,SAAQ,6BAA6B;IACnF,OAAO,CAAC,MAAM,CAAC,mBAAmB,CAAU;IAC5C,OAAO,CAAC,yBAAyB,CAA0B;IAC3D,OAAO,CAAC,4BAA4B,CAA6B;IAEjE,OAAO,CAAC,WAAW,CAAO;IAC1B,OAAO,CAAC,KAAK,CAAO;IACpB,OAAO,CAAC,MAAM,CAAQ;gBAEV,EACV,wBAAwB,EACxB,eAAe,EACf,qBAAqB,EACrB,cAAc,GACf,EAAE;QACD,wBAAwB,EAAE,wBAAwB,CAAA;QAClD,eAAe,EAAE,KAAK,CAAA;QACtB,qBAAqB,EAAE,KAAK,CAAA;QAC5B,cAAc,EAAE,MAAM,CAAA;KACvB;IA4BD,8BAA8B,CAAC,2BAA2B,KAAA;YAI5C,QAAQ;YAeR,YAAY;YASZ,kBAAkB;IAOhC,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,cAAc;IAQhB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC;IAM5D,IAAI,IAAI,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAcxC,IAAI,CACR,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,qBAAqB,EAC3B,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;IAqDV,aAAa,CACjB,WAAW,EAAE,sBAAsB,EACnC,IAAI,EAAE,eAAe,EACrB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAgBV,UAAU,CACd,WAAW,EAAE,sBAAsB,EACnC,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,IAAI,CAAC;IAIV,0BAA0B,CAC9B,WAAW,EAAE,sBAAsB,EACnC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAeV,uBAAuB,CAC3B,WAAW,EAAE,sBAAsB,GAClC,OAAO,CAAC,IAAI,CAAC;IAIV,mBAAmB,CACvB,WAAW,EAAE,sBAAsB,EACnC,IAAI,EAAE,eAAe,EACrB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAgBV,gBAAgB,CACpB,WAAW,EAAE,sBAAsB,EACnC,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,IAAI,CAAC;IAIhB,OAAO,CAAC,QAAQ;YAcF,SAAS;CAYxB"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RedisDistributedTransactionStorage = void 0;
|
|
4
|
+
const orchestration_1 = require("@medusajs/orchestration");
|
|
5
|
+
const utils_1 = require("@medusajs/utils");
|
|
6
|
+
const bullmq_1 = require("bullmq");
|
|
7
|
+
var JobType;
|
|
8
|
+
(function (JobType) {
|
|
9
|
+
JobType["RETRY"] = "retry";
|
|
10
|
+
JobType["STEP_TIMEOUT"] = "step_timeout";
|
|
11
|
+
JobType["TRANSACTION_TIMEOUT"] = "transaction_timeout";
|
|
12
|
+
})(JobType || (JobType = {}));
|
|
13
|
+
// eslint-disable-next-line max-len
|
|
14
|
+
class RedisDistributedTransactionStorage extends orchestration_1.DistributedTransactionStorage {
|
|
15
|
+
constructor({ workflowExecutionService, redisConnection, redisWorkerConnection, redisQueueName, }) {
|
|
16
|
+
super();
|
|
17
|
+
this.workflowExecutionService_ = workflowExecutionService;
|
|
18
|
+
this.redisClient = redisConnection;
|
|
19
|
+
this.queue = new bullmq_1.Queue(redisQueueName, { connection: this.redisClient });
|
|
20
|
+
this.worker = new bullmq_1.Worker(redisQueueName, async (job) => {
|
|
21
|
+
const allJobs = [
|
|
22
|
+
JobType.RETRY,
|
|
23
|
+
JobType.STEP_TIMEOUT,
|
|
24
|
+
JobType.TRANSACTION_TIMEOUT,
|
|
25
|
+
];
|
|
26
|
+
if (allJobs.includes(job.name)) {
|
|
27
|
+
await this.executeTransaction(job.data.workflowId, job.data.transactionId);
|
|
28
|
+
}
|
|
29
|
+
}, { connection: redisWorkerConnection });
|
|
30
|
+
}
|
|
31
|
+
setWorkflowOrchestratorService(workflowOrchestratorService) {
|
|
32
|
+
this.workflowOrchestratorService_ = workflowOrchestratorService;
|
|
33
|
+
}
|
|
34
|
+
async saveToDb(data) {
|
|
35
|
+
await this.workflowExecutionService_.upsert([
|
|
36
|
+
{
|
|
37
|
+
workflow_id: data.flow.modelId,
|
|
38
|
+
transaction_id: data.flow.transactionId,
|
|
39
|
+
execution: data.flow,
|
|
40
|
+
context: {
|
|
41
|
+
data: data.context,
|
|
42
|
+
errors: data.errors,
|
|
43
|
+
},
|
|
44
|
+
state: data.flow.state,
|
|
45
|
+
},
|
|
46
|
+
]);
|
|
47
|
+
}
|
|
48
|
+
async deleteFromDb(data) {
|
|
49
|
+
await this.workflowExecutionService_.delete([
|
|
50
|
+
{
|
|
51
|
+
workflow_id: data.flow.modelId,
|
|
52
|
+
transaction_id: data.flow.transactionId,
|
|
53
|
+
},
|
|
54
|
+
]);
|
|
55
|
+
}
|
|
56
|
+
async executeTransaction(workflowId, transactionId) {
|
|
57
|
+
return await this.workflowOrchestratorService_.run(workflowId, {
|
|
58
|
+
transactionId,
|
|
59
|
+
throwOnError: false,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
stringifyWithSymbol(key, value) {
|
|
63
|
+
if (key === "__type" && typeof value === "symbol") {
|
|
64
|
+
return Symbol.keyFor(value);
|
|
65
|
+
}
|
|
66
|
+
return value;
|
|
67
|
+
}
|
|
68
|
+
jsonWithSymbol(key, value) {
|
|
69
|
+
if (key === "__type" && typeof value === "string") {
|
|
70
|
+
return Symbol.for(value);
|
|
71
|
+
}
|
|
72
|
+
return value;
|
|
73
|
+
}
|
|
74
|
+
async get(key) {
|
|
75
|
+
const data = await this.redisClient.get(key);
|
|
76
|
+
return data ? JSON.parse(data, this.jsonWithSymbol) : undefined;
|
|
77
|
+
}
|
|
78
|
+
async list() {
|
|
79
|
+
const keys = await this.redisClient.keys(orchestration_1.DistributedTransaction.keyPrefix + ":*");
|
|
80
|
+
const transactions = [];
|
|
81
|
+
for (const key of keys) {
|
|
82
|
+
const data = await this.redisClient.get(key);
|
|
83
|
+
if (data) {
|
|
84
|
+
transactions.push(JSON.parse(data, this.jsonWithSymbol));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return transactions;
|
|
88
|
+
}
|
|
89
|
+
async save(key, data, ttl) {
|
|
90
|
+
let retentionTime;
|
|
91
|
+
/**
|
|
92
|
+
* Store the retention time only if the transaction is done, failed or reverted.
|
|
93
|
+
* From that moment, this tuple can be later on archived or deleted after the retention time.
|
|
94
|
+
*/
|
|
95
|
+
const hasFinished = [
|
|
96
|
+
utils_1.TransactionState.DONE,
|
|
97
|
+
utils_1.TransactionState.FAILED,
|
|
98
|
+
utils_1.TransactionState.REVERTED,
|
|
99
|
+
].includes(data.flow.state);
|
|
100
|
+
if (hasFinished) {
|
|
101
|
+
retentionTime = data.flow.options?.retentionTime;
|
|
102
|
+
Object.assign(data, {
|
|
103
|
+
retention_time: retentionTime,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
if (!hasFinished) {
|
|
107
|
+
if (ttl) {
|
|
108
|
+
await this.redisClient.set(key, JSON.stringify(data, this.stringifyWithSymbol), "EX", ttl);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
await this.redisClient.set(key, JSON.stringify(data, this.stringifyWithSymbol));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (hasFinished && !retentionTime) {
|
|
115
|
+
await this.deleteFromDb(data);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
await this.saveToDb(data);
|
|
119
|
+
}
|
|
120
|
+
if (hasFinished) {
|
|
121
|
+
// await this.redisClient.del(key)
|
|
122
|
+
await this.redisClient.set(key, JSON.stringify(data, this.stringifyWithSymbol), "EX", RedisDistributedTransactionStorage.TTL_AFTER_COMPLETED);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
async scheduleRetry(transaction, step, timestamp, interval) {
|
|
126
|
+
await this.queue.add(JobType.RETRY, {
|
|
127
|
+
workflowId: transaction.modelId,
|
|
128
|
+
transactionId: transaction.transactionId,
|
|
129
|
+
stepId: step.id,
|
|
130
|
+
}, {
|
|
131
|
+
delay: interval * 1000,
|
|
132
|
+
jobId: this.getJobId(JobType.RETRY, transaction, step),
|
|
133
|
+
removeOnComplete: true,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
async clearRetry(transaction, step) {
|
|
137
|
+
await this.removeJob(JobType.RETRY, transaction, step);
|
|
138
|
+
}
|
|
139
|
+
async scheduleTransactionTimeout(transaction, timestamp, interval) {
|
|
140
|
+
await this.queue.add(JobType.TRANSACTION_TIMEOUT, {
|
|
141
|
+
workflowId: transaction.modelId,
|
|
142
|
+
transactionId: transaction.transactionId,
|
|
143
|
+
}, {
|
|
144
|
+
delay: interval * 1000,
|
|
145
|
+
jobId: this.getJobId(JobType.TRANSACTION_TIMEOUT, transaction),
|
|
146
|
+
removeOnComplete: true,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
async clearTransactionTimeout(transaction) {
|
|
150
|
+
await this.removeJob(JobType.TRANSACTION_TIMEOUT, transaction);
|
|
151
|
+
}
|
|
152
|
+
async scheduleStepTimeout(transaction, step, timestamp, interval) {
|
|
153
|
+
await this.queue.add(JobType.STEP_TIMEOUT, {
|
|
154
|
+
workflowId: transaction.modelId,
|
|
155
|
+
transactionId: transaction.transactionId,
|
|
156
|
+
stepId: step.id,
|
|
157
|
+
}, {
|
|
158
|
+
delay: interval * 1000,
|
|
159
|
+
jobId: this.getJobId(JobType.STEP_TIMEOUT, transaction, step),
|
|
160
|
+
removeOnComplete: true,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
async clearStepTimeout(transaction, step) {
|
|
164
|
+
await this.removeJob(JobType.STEP_TIMEOUT, transaction, step);
|
|
165
|
+
}
|
|
166
|
+
getJobId(type, transaction, step) {
|
|
167
|
+
const key = [type, transaction.modelId, transaction.transactionId];
|
|
168
|
+
if (step) {
|
|
169
|
+
key.push(step.id);
|
|
170
|
+
}
|
|
171
|
+
return key.join(":");
|
|
172
|
+
}
|
|
173
|
+
async removeJob(type, transaction, step) {
|
|
174
|
+
const jobId = this.getJobId(type, transaction, step);
|
|
175
|
+
const job = await this.queue.getJob(jobId);
|
|
176
|
+
if (job && job.attemptsStarted === 0) {
|
|
177
|
+
await job.remove();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
exports.RedisDistributedTransactionStorage = RedisDistributedTransactionStorage;
|
|
182
|
+
RedisDistributedTransactionStorage.TTL_AFTER_COMPLETED = 60 * 15; // 15 minutes
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@medusajs/workflow-engine-redis",
|
|
3
|
+
"version": "0.0.2-next-20240124093206",
|
|
4
|
+
"description": "Medusa Workflow Orchestrator module using Redis to track workflows executions",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"engines": {
|
|
11
|
+
"node": ">=16"
|
|
12
|
+
},
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/medusajs/medusa",
|
|
16
|
+
"directory": "packages/workflow-engine-redis"
|
|
17
|
+
},
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"author": "Medusa",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"scripts": {
|
|
24
|
+
"watch": "tsc --build --watch",
|
|
25
|
+
"watch:test": "tsc --build tsconfig.spec.json --watch",
|
|
26
|
+
"prepublishOnly": "cross-env NODE_ENV=production tsc --build && tsc-alias -p tsconfig.json",
|
|
27
|
+
"build": "rimraf dist && tsc --build && tsc-alias -p tsconfig.json",
|
|
28
|
+
"test": "jest --passWithNoTests --runInBand --bail --forceExit -- src/**/__tests__/**/*.ts",
|
|
29
|
+
"test:integration": "jest --runInBand --forceExit -- integration-tests/**/__tests__/**/*.ts",
|
|
30
|
+
"migration:generate": " MIKRO_ORM_CLI=./mikro-orm.config.dev.ts mikro-orm migration:generate",
|
|
31
|
+
"migration:initial": " MIKRO_ORM_CLI=./mikro-orm.config.dev.ts mikro-orm migration:create --initial",
|
|
32
|
+
"migration:create": " MIKRO_ORM_CLI=./mikro-orm.config.dev.ts mikro-orm migration:create",
|
|
33
|
+
"migration:up": " MIKRO_ORM_CLI=./mikro-orm.config.dev.ts mikro-orm migration:up",
|
|
34
|
+
"orm:cache:clear": " MIKRO_ORM_CLI=./mikro-orm.config.dev.ts mikro-orm cache:clear"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@mikro-orm/cli": "5.9.7",
|
|
38
|
+
"cross-env": "^5.2.1",
|
|
39
|
+
"jest": "^29.6.3",
|
|
40
|
+
"medusa-test-utils": "^1.1.40",
|
|
41
|
+
"rimraf": "^3.0.2",
|
|
42
|
+
"ts-jest": "^29.1.1",
|
|
43
|
+
"ts-node": "^10.9.1",
|
|
44
|
+
"tsc-alias": "^1.8.6",
|
|
45
|
+
"typescript": "^5.1.6"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@medusajs/modules-sdk": "1.12.7-next-20240124093206",
|
|
49
|
+
"@medusajs/types": "1.11.11-next-20240124093206",
|
|
50
|
+
"@medusajs/utils": "1.11.4-next-20240124093206",
|
|
51
|
+
"@medusajs/workflows-sdk": "0.1.2-next-20240124093206",
|
|
52
|
+
"@mikro-orm/core": "5.9.7",
|
|
53
|
+
"@mikro-orm/migrations": "5.9.7",
|
|
54
|
+
"@mikro-orm/postgresql": "5.9.7",
|
|
55
|
+
"awilix": "^8.0.0",
|
|
56
|
+
"bullmq": "^5.1.3",
|
|
57
|
+
"dotenv": "^16.1.4",
|
|
58
|
+
"ioredis": "^5.3.2",
|
|
59
|
+
"knex": "2.4.2"
|
|
60
|
+
}
|
|
61
|
+
}
|