@hotmeshio/hotmesh 0.0.20 → 0.0.21
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/build/package.json +1 -1
- package/build/services/durable/search.js +2 -3
- package/build/services/durable/workflow.d.ts +5 -1
- package/build/services/durable/workflow.js +45 -3
- package/build/types/durable.d.ts +1 -1
- package/package.json +1 -1
- package/services/durable/search.ts +2 -3
- package/services/durable/workflow.ts +48 -3
- package/types/durable.ts +1 -1
package/build/package.json
CHANGED
|
@@ -12,10 +12,9 @@ class Search {
|
|
|
12
12
|
this.searchSessionIndex = 0;
|
|
13
13
|
const keyParams = {
|
|
14
14
|
appId: hotMeshClient.appId,
|
|
15
|
-
jobId:
|
|
15
|
+
jobId: workflowId
|
|
16
16
|
};
|
|
17
|
-
|
|
18
|
-
this.jobId = `${hotMeshPrefix}${workflowId}`;
|
|
17
|
+
this.jobId = key_1.KeyService.mintKey(hotMeshClient.namespace, key_1.KeyType.JOB_STATE, keyParams);
|
|
19
18
|
this.searchSessionId = searchSessionId;
|
|
20
19
|
this.hotMeshClient = hotMeshClient;
|
|
21
20
|
this.store = hotMeshClient.engine.store;
|
|
@@ -3,9 +3,13 @@ import { HotMeshService as HotMesh } from '../hotmesh';
|
|
|
3
3
|
import { ActivityConfig, HookOptions, ProxyType, WorkflowOptions } from "../../types/durable";
|
|
4
4
|
export declare class WorkflowService {
|
|
5
5
|
/**
|
|
6
|
-
* Spawn a child workflow. await the result.
|
|
6
|
+
* Spawn a child workflow. await and return the result.
|
|
7
7
|
*/
|
|
8
8
|
static executeChild<T>(options: WorkflowOptions): Promise<T>;
|
|
9
|
+
/**
|
|
10
|
+
* spawn a child workflow. return the childJobId.
|
|
11
|
+
*/
|
|
12
|
+
static startChild<T>(options: WorkflowOptions): Promise<string>;
|
|
9
13
|
static proxyActivities<ACT>(options?: ActivityConfig): ProxyType<ACT>;
|
|
10
14
|
static search(): Promise<Search>;
|
|
11
15
|
/**
|
|
@@ -16,37 +16,79 @@ const worker_1 = require("./worker");
|
|
|
16
16
|
const stream_1 = require("../../types/stream");
|
|
17
17
|
class WorkflowService {
|
|
18
18
|
/**
|
|
19
|
-
* Spawn a child workflow. await the result.
|
|
19
|
+
* Spawn a child workflow. await and return the result.
|
|
20
20
|
*/
|
|
21
21
|
static async executeChild(options) {
|
|
22
22
|
const store = asyncLocalStorage_1.asyncLocalStorage.getStore();
|
|
23
|
+
const namespace = store.get('namespace');
|
|
23
24
|
const workflowId = store.get('workflowId');
|
|
24
25
|
const workflowDimension = store.get('workflowDimension') ?? '';
|
|
25
26
|
const workflowTrace = store.get('workflowTrace');
|
|
26
27
|
const workflowSpan = store.get('workflowSpan');
|
|
27
28
|
const COUNTER = store.get('counter');
|
|
28
29
|
const execIndex = COUNTER.counter = COUNTER.counter + 1;
|
|
29
|
-
|
|
30
|
+
//this is risky but MUST be allowed. Users MAY set the workflowId,
|
|
31
|
+
//but if there is a naming collision, the data from the target entity will be used
|
|
32
|
+
//as there is know way of knowing if the item was generated via a prior run of the workflow
|
|
33
|
+
const childJobId = options.workflowId ?? `${workflowId}-$${options.workflowName}${workflowDimension}-${execIndex}`;
|
|
30
34
|
const parentWorkflowId = `${workflowId}-f`;
|
|
31
35
|
const client = new client_1.ClientService({
|
|
32
36
|
connection: await connection_1.ConnectionService.connect(worker_1.WorkerService.connection),
|
|
33
37
|
});
|
|
34
|
-
let handle = await client.workflow.getHandle(options.taskQueue, options.workflowName, childJobId);
|
|
38
|
+
let handle = await client.workflow.getHandle(options.taskQueue, options.workflowName, childJobId, namespace);
|
|
35
39
|
try {
|
|
36
40
|
return await handle.result(true);
|
|
37
41
|
}
|
|
38
42
|
catch (error) {
|
|
39
43
|
handle = await client.workflow.start({
|
|
40
44
|
...options,
|
|
45
|
+
namespace,
|
|
41
46
|
workflowId: childJobId,
|
|
42
47
|
parentWorkflowId,
|
|
43
48
|
workflowTrace,
|
|
44
49
|
workflowSpan,
|
|
45
50
|
});
|
|
51
|
+
//todo: options.startToCloseTimeout
|
|
46
52
|
const result = await handle.result();
|
|
47
53
|
return result;
|
|
48
54
|
}
|
|
49
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* spawn a child workflow. return the childJobId.
|
|
58
|
+
*/
|
|
59
|
+
static async startChild(options) {
|
|
60
|
+
const store = asyncLocalStorage_1.asyncLocalStorage.getStore();
|
|
61
|
+
const namespace = store.get('namespace');
|
|
62
|
+
const workflowId = store.get('workflowId');
|
|
63
|
+
const workflowDimension = store.get('workflowDimension') ?? '';
|
|
64
|
+
const workflowTrace = store.get('workflowTrace');
|
|
65
|
+
const workflowSpan = store.get('workflowSpan');
|
|
66
|
+
const COUNTER = store.get('counter');
|
|
67
|
+
const execIndex = COUNTER.counter = COUNTER.counter + 1;
|
|
68
|
+
const childJobId = options.workflowId ?? `${workflowId}-$${options.workflowName}${workflowDimension}-${execIndex}`;
|
|
69
|
+
const parentWorkflowId = `${workflowId}-f`;
|
|
70
|
+
const workflowTopic = `${options.taskQueue}-${options.workflowName}`;
|
|
71
|
+
try {
|
|
72
|
+
//get the status; if there is no error, return childJobId (what was spawned)
|
|
73
|
+
const hotMeshClient = await worker_1.WorkerService.getHotMesh(workflowTopic, { namespace });
|
|
74
|
+
await hotMeshClient.getStatus(childJobId);
|
|
75
|
+
return childJobId;
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
const client = new client_1.ClientService({
|
|
79
|
+
connection: await connection_1.ConnectionService.connect(worker_1.WorkerService.connection),
|
|
80
|
+
});
|
|
81
|
+
await client.workflow.start({
|
|
82
|
+
...options,
|
|
83
|
+
namespace,
|
|
84
|
+
workflowId: childJobId,
|
|
85
|
+
parentWorkflowId,
|
|
86
|
+
workflowTrace,
|
|
87
|
+
workflowSpan,
|
|
88
|
+
});
|
|
89
|
+
return childJobId;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
50
92
|
static proxyActivities(options) {
|
|
51
93
|
if (options.activities) {
|
|
52
94
|
worker_1.WorkerService.registerActivities(options.activities);
|
package/build/types/durable.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -19,10 +19,9 @@ export class Search {
|
|
|
19
19
|
constructor(workflowId: string, hotMeshClient: HotMesh, searchSessionId: string) {
|
|
20
20
|
const keyParams = {
|
|
21
21
|
appId: hotMeshClient.appId,
|
|
22
|
-
jobId:
|
|
22
|
+
jobId: workflowId
|
|
23
23
|
}
|
|
24
|
-
|
|
25
|
-
this.jobId = `${hotMeshPrefix}${workflowId}`;
|
|
24
|
+
this.jobId = KeyService.mintKey(hotMeshClient.namespace, KeyType.JOB_STATE, keyParams);
|
|
26
25
|
this.searchSessionId = searchSessionId;
|
|
27
26
|
this.hotMeshClient = hotMeshClient;
|
|
28
27
|
this.store = hotMeshClient.engine.store as StoreService<RedisClient, RedisMulti>;
|
|
@@ -23,17 +23,21 @@ import { StreamStatus } from '../../types/stream';
|
|
|
23
23
|
export class WorkflowService {
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
|
-
* Spawn a child workflow. await the result.
|
|
26
|
+
* Spawn a child workflow. await and return the result.
|
|
27
27
|
*/
|
|
28
28
|
static async executeChild<T>(options: WorkflowOptions): Promise<T> {
|
|
29
29
|
const store = asyncLocalStorage.getStore();
|
|
30
|
+
const namespace = store.get('namespace');
|
|
30
31
|
const workflowId = store.get('workflowId');
|
|
31
32
|
const workflowDimension = store.get('workflowDimension') ?? '';
|
|
32
33
|
const workflowTrace = store.get('workflowTrace');
|
|
33
34
|
const workflowSpan = store.get('workflowSpan');
|
|
34
35
|
const COUNTER = store.get('counter');
|
|
35
36
|
const execIndex = COUNTER.counter = COUNTER.counter + 1;
|
|
36
|
-
|
|
37
|
+
//this is risky but MUST be allowed. Users MAY set the workflowId,
|
|
38
|
+
//but if there is a naming collision, the data from the target entity will be used
|
|
39
|
+
//as there is know way of knowing if the item was generated via a prior run of the workflow
|
|
40
|
+
const childJobId = options.workflowId ?? `${workflowId}-$${options.workflowName}${workflowDimension}-${execIndex}`;
|
|
37
41
|
const parentWorkflowId = `${workflowId}-f`;
|
|
38
42
|
|
|
39
43
|
const client = new Client({
|
|
@@ -43,7 +47,8 @@ export class WorkflowService {
|
|
|
43
47
|
let handle = await client.workflow.getHandle(
|
|
44
48
|
options.taskQueue,
|
|
45
49
|
options.workflowName,
|
|
46
|
-
childJobId
|
|
50
|
+
childJobId,
|
|
51
|
+
namespace,
|
|
47
52
|
);
|
|
48
53
|
|
|
49
54
|
try {
|
|
@@ -51,16 +56,56 @@ export class WorkflowService {
|
|
|
51
56
|
} catch (error) {
|
|
52
57
|
handle = await client.workflow.start({
|
|
53
58
|
...options,
|
|
59
|
+
namespace,
|
|
54
60
|
workflowId: childJobId,
|
|
55
61
|
parentWorkflowId,
|
|
56
62
|
workflowTrace,
|
|
57
63
|
workflowSpan,
|
|
58
64
|
});
|
|
65
|
+
//todo: options.startToCloseTimeout
|
|
59
66
|
const result = await handle.result();
|
|
60
67
|
return result as T;
|
|
61
68
|
}
|
|
62
69
|
}
|
|
63
70
|
|
|
71
|
+
/**
|
|
72
|
+
* spawn a child workflow. return the childJobId.
|
|
73
|
+
*/
|
|
74
|
+
static async startChild<T>(options: WorkflowOptions): Promise<string> {
|
|
75
|
+
const store = asyncLocalStorage.getStore();
|
|
76
|
+
const namespace = store.get('namespace');
|
|
77
|
+
const workflowId = store.get('workflowId');
|
|
78
|
+
const workflowDimension = store.get('workflowDimension') ?? '';
|
|
79
|
+
const workflowTrace = store.get('workflowTrace');
|
|
80
|
+
const workflowSpan = store.get('workflowSpan');
|
|
81
|
+
const COUNTER = store.get('counter');
|
|
82
|
+
const execIndex = COUNTER.counter = COUNTER.counter + 1;
|
|
83
|
+
const childJobId = options.workflowId ?? `${workflowId}-$${options.workflowName}${workflowDimension}-${execIndex}`;
|
|
84
|
+
const parentWorkflowId = `${workflowId}-f`;
|
|
85
|
+
const workflowTopic = `${options.taskQueue}-${options.workflowName}`;
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
//get the status; if there is no error, return childJobId (what was spawned)
|
|
89
|
+
const hotMeshClient = await WorkerService.getHotMesh(workflowTopic, { namespace });
|
|
90
|
+
await hotMeshClient.getStatus(childJobId);
|
|
91
|
+
return childJobId;
|
|
92
|
+
} catch (error) {
|
|
93
|
+
const client = new Client({
|
|
94
|
+
connection: await Connection.connect(WorkerService.connection),
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
await client.workflow.start({
|
|
98
|
+
...options,
|
|
99
|
+
namespace,
|
|
100
|
+
workflowId: childJobId,
|
|
101
|
+
parentWorkflowId,
|
|
102
|
+
workflowTrace,
|
|
103
|
+
workflowSpan,
|
|
104
|
+
});
|
|
105
|
+
return childJobId;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
64
109
|
static proxyActivities<ACT>(options?: ActivityConfig): ProxyType<ACT> {
|
|
65
110
|
if (options.activities) {
|
|
66
111
|
WorkerService.registerActivities(options.activities)
|
package/types/durable.ts
CHANGED
|
@@ -18,7 +18,7 @@ type WorkflowOptions = {
|
|
|
18
18
|
namespace?: string; //'durable' is the default namespace if not provided; similar to setting `appid` in the YAML
|
|
19
19
|
taskQueue: string;
|
|
20
20
|
args: any[]; //input arguments to pass in
|
|
21
|
-
workflowId
|
|
21
|
+
workflowId?: string; //execution id (the job id)
|
|
22
22
|
workflowName?: string; //the name of the user's workflow function
|
|
23
23
|
parentWorkflowId?: string; //system reserved; the id of the parent; if present the flow will not self-clean until the parent that spawned it self-cleans
|
|
24
24
|
workflowTrace?: string;
|