@hotmeshio/hotmesh 0.8.0 → 0.10.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/README.md +178 -43
- package/build/index.d.ts +12 -11
- package/build/index.js +15 -13
- package/build/modules/enums.d.ts +23 -34
- package/build/modules/enums.js +26 -38
- package/build/modules/errors.d.ts +16 -16
- package/build/modules/errors.js +37 -37
- package/build/package.json +63 -67
- package/build/services/activities/activity.d.ts +58 -7
- package/build/services/activities/activity.js +67 -38
- package/build/services/activities/await.d.ts +101 -0
- package/build/services/activities/await.js +101 -0
- package/build/services/activities/cycle.d.ts +82 -0
- package/build/services/activities/cycle.js +86 -8
- package/build/services/activities/hook.d.ts +139 -1
- package/build/services/activities/hook.js +140 -2
- package/build/services/activities/interrupt.d.ts +112 -0
- package/build/services/activities/interrupt.js +118 -5
- package/build/services/activities/signal.d.ts +108 -3
- package/build/services/activities/signal.js +113 -8
- package/build/services/activities/trigger.d.ts +56 -4
- package/build/services/activities/trigger.js +119 -35
- package/build/services/activities/worker.d.ts +107 -0
- package/build/services/activities/worker.js +107 -0
- package/build/services/collator/index.d.ts +3 -15
- package/build/services/collator/index.js +7 -34
- package/build/services/dba/index.d.ts +171 -0
- package/build/services/dba/index.js +280 -0
- package/build/services/{memflow → durable}/client.d.ts +3 -3
- package/build/services/{memflow → durable}/client.js +15 -15
- package/build/services/{memflow → durable}/connection.d.ts +2 -2
- package/build/services/{memflow → durable}/connection.js +1 -1
- package/build/services/{memflow → durable}/exporter.d.ts +6 -6
- package/build/services/{memflow → durable}/exporter.js +2 -2
- package/build/services/{memflow → durable}/handle.d.ts +4 -4
- package/build/services/{memflow → durable}/handle.js +3 -3
- package/build/services/{memflow → durable}/index.d.ts +126 -34
- package/build/services/{memflow → durable}/index.js +146 -50
- package/build/services/{memflow → durable}/interceptor.d.ts +45 -22
- package/build/services/{memflow → durable}/interceptor.js +54 -21
- package/build/services/{memflow → durable}/schemas/factory.d.ts +4 -4
- package/build/services/{memflow → durable}/schemas/factory.js +5 -5
- package/build/services/{memflow → durable}/search.d.ts +1 -1
- package/build/services/{memflow → durable}/search.js +4 -4
- package/build/services/{memflow → durable}/worker.d.ts +11 -11
- package/build/services/{memflow → durable}/worker.js +61 -60
- package/build/services/durable/workflow/all.d.ts +32 -0
- package/build/services/durable/workflow/all.js +40 -0
- package/build/services/{memflow → durable}/workflow/common.d.ts +5 -5
- package/build/services/durable/workflow/common.js +47 -0
- package/build/services/durable/workflow/context.d.ts +49 -0
- package/build/services/durable/workflow/context.js +88 -0
- package/build/services/durable/workflow/didRun.d.ts +27 -0
- package/build/services/durable/workflow/didRun.js +42 -0
- package/build/services/durable/workflow/emit.d.ts +50 -0
- package/build/services/durable/workflow/emit.js +68 -0
- package/build/services/durable/workflow/enrich.d.ts +37 -0
- package/build/services/durable/workflow/enrich.js +45 -0
- package/build/services/durable/workflow/entityMethods.d.ts +61 -0
- package/build/services/durable/workflow/entityMethods.js +80 -0
- package/build/services/durable/workflow/execChild.d.ts +106 -0
- package/build/services/durable/workflow/execChild.js +194 -0
- package/build/services/durable/workflow/execHook.d.ts +80 -0
- package/build/services/durable/workflow/execHook.js +97 -0
- package/build/services/durable/workflow/execHookBatch.d.ts +107 -0
- package/build/services/durable/workflow/execHookBatch.js +129 -0
- package/build/services/durable/workflow/hook.d.ts +74 -0
- package/build/services/durable/workflow/hook.js +123 -0
- package/build/services/durable/workflow/index.d.ts +129 -0
- package/build/services/{memflow → durable}/workflow/index.js +66 -11
- package/build/services/durable/workflow/interrupt.d.ts +55 -0
- package/build/services/durable/workflow/interrupt.js +70 -0
- package/build/services/durable/workflow/interruption.d.ts +61 -0
- package/build/services/durable/workflow/interruption.js +76 -0
- package/build/services/durable/workflow/isSideEffectAllowed.d.ts +27 -0
- package/build/services/{memflow → durable}/workflow/isSideEffectAllowed.js +21 -4
- package/build/services/durable/workflow/proxyActivities.d.ts +119 -0
- package/build/services/durable/workflow/proxyActivities.js +214 -0
- package/build/services/durable/workflow/random.d.ts +36 -0
- package/build/services/durable/workflow/random.js +46 -0
- package/build/services/durable/workflow/searchMethods.d.ts +53 -0
- package/build/services/durable/workflow/searchMethods.js +72 -0
- package/build/services/durable/workflow/signal.d.ts +58 -0
- package/build/services/durable/workflow/signal.js +79 -0
- package/build/services/durable/workflow/sleepFor.d.ts +63 -0
- package/build/services/durable/workflow/sleepFor.js +91 -0
- package/build/services/durable/workflow/trace.d.ts +47 -0
- package/build/services/durable/workflow/trace.js +66 -0
- package/build/services/durable/workflow/waitFor.d.ts +66 -0
- package/build/services/durable/workflow/waitFor.js +93 -0
- package/build/services/engine/index.d.ts +18 -2
- package/build/services/engine/index.js +14 -4
- package/build/services/exporter/index.d.ts +2 -0
- package/build/services/exporter/index.js +1 -0
- package/build/services/hotmesh/index.d.ts +471 -236
- package/build/services/hotmesh/index.js +473 -238
- package/build/services/store/index.d.ts +1 -1
- package/build/services/store/providers/postgres/postgres.d.ts +1 -1
- package/build/services/store/providers/postgres/postgres.js +4 -3
- package/build/services/telemetry/index.js +6 -0
- package/build/services/{meshcall → virtual}/index.d.ts +29 -29
- package/build/services/{meshcall → virtual}/index.js +49 -49
- package/build/services/{meshcall → virtual}/schemas/factory.d.ts +1 -1
- package/build/services/{meshcall → virtual}/schemas/factory.js +1 -1
- package/build/types/activity.d.ts +1 -1
- package/build/types/dba.d.ts +64 -0
- package/build/types/{memflow.d.ts → durable.d.ts} +75 -19
- package/build/types/error.d.ts +5 -5
- package/build/types/exporter.d.ts +1 -1
- package/build/types/hotmesh.d.ts +1 -1
- package/build/types/index.d.ts +5 -4
- package/build/types/job.d.ts +1 -1
- package/build/types/quorum.d.ts +2 -2
- package/build/types/{meshcall.d.ts → virtual.d.ts} +15 -15
- package/build/types/virtual.js +2 -0
- package/index.ts +15 -13
- package/package.json +63 -67
- package/vitest.config.ts +17 -0
- package/.claude/settings.local.json +0 -7
- package/build/services/memflow/workflow/all.d.ts +0 -7
- package/build/services/memflow/workflow/all.js +0 -15
- package/build/services/memflow/workflow/common.js +0 -47
- package/build/services/memflow/workflow/context.d.ts +0 -6
- package/build/services/memflow/workflow/context.js +0 -45
- package/build/services/memflow/workflow/didRun.d.ts +0 -7
- package/build/services/memflow/workflow/didRun.js +0 -22
- package/build/services/memflow/workflow/emit.d.ts +0 -11
- package/build/services/memflow/workflow/emit.js +0 -29
- package/build/services/memflow/workflow/enrich.d.ts +0 -9
- package/build/services/memflow/workflow/enrich.js +0 -17
- package/build/services/memflow/workflow/entityMethods.d.ts +0 -14
- package/build/services/memflow/workflow/entityMethods.js +0 -33
- package/build/services/memflow/workflow/execChild.d.ts +0 -18
- package/build/services/memflow/workflow/execChild.js +0 -106
- package/build/services/memflow/workflow/execHook.d.ts +0 -65
- package/build/services/memflow/workflow/execHook.js +0 -83
- package/build/services/memflow/workflow/execHookBatch.d.ts +0 -54
- package/build/services/memflow/workflow/execHookBatch.js +0 -77
- package/build/services/memflow/workflow/hook.d.ts +0 -9
- package/build/services/memflow/workflow/hook.js +0 -58
- package/build/services/memflow/workflow/index.d.ts +0 -74
- package/build/services/memflow/workflow/interrupt.d.ts +0 -9
- package/build/services/memflow/workflow/interrupt.js +0 -24
- package/build/services/memflow/workflow/interruption.d.ts +0 -28
- package/build/services/memflow/workflow/interruption.js +0 -43
- package/build/services/memflow/workflow/isSideEffectAllowed.d.ts +0 -10
- package/build/services/memflow/workflow/proxyActivities.d.ts +0 -91
- package/build/services/memflow/workflow/proxyActivities.js +0 -176
- package/build/services/memflow/workflow/random.d.ts +0 -6
- package/build/services/memflow/workflow/random.js +0 -16
- package/build/services/memflow/workflow/searchMethods.d.ts +0 -6
- package/build/services/memflow/workflow/searchMethods.js +0 -25
- package/build/services/memflow/workflow/signal.d.ts +0 -29
- package/build/services/memflow/workflow/signal.js +0 -50
- package/build/services/memflow/workflow/sleepFor.d.ts +0 -24
- package/build/services/memflow/workflow/sleepFor.js +0 -52
- package/build/services/memflow/workflow/trace.d.ts +0 -14
- package/build/services/memflow/workflow/trace.js +0 -33
- package/build/services/memflow/workflow/waitFor.d.ts +0 -29
- package/build/services/memflow/workflow/waitFor.js +0 -56
- /package/build/services/{memflow → durable}/entity.d.ts +0 -0
- /package/build/services/{memflow → durable}/entity.js +0 -0
- /package/build/types/{memflow.js → dba.js} +0 -0
- /package/build/types/{meshcall.js → durable.js} +0 -0
package/README.md
CHANGED
|
@@ -4,27 +4,39 @@
|
|
|
4
4
|
|
|
5
5
|
Run durable workflows on Postgres. No servers, no queues, just your database.
|
|
6
6
|
|
|
7
|
+
```bash
|
|
8
|
+
npm install @hotmeshio/hotmesh
|
|
9
|
+
```
|
|
7
10
|
|
|
8
|
-
##
|
|
11
|
+
## Use HotMesh for
|
|
9
12
|
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
- **Durable pipelines** — Orchestrate long-running, multi-step pipelines transactionally.
|
|
14
|
+
- **Temporal replacement** — The `Durable` module provides a Temporal-compatible API (`Client`, `Worker`, `proxyActivities`, `sleepFor`, `startChild`, signals) that runs directly on Postgres. No app server required.
|
|
15
|
+
- **Distributed state machines** — Build stateful applications where every component can [fail and recover](https://github.com/hotmeshio/sdk-typescript/blob/main/services/collator/README.md).
|
|
16
|
+
- **AI and training pipelines** — Multi-step AI workloads where each stage is expensive and must not be repeated on failure. A crashed pipeline resumes from the last committed step, not from the beginning.
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
Get the power of Temporal without the infrastructure. HotMesh includes MemFlow, a Temporal-compatible API that runs directly on your Postgres database. No app server required.
|
|
18
|
+
## How it works in 30 seconds
|
|
15
19
|
|
|
16
|
-
|
|
17
|
-
|
|
20
|
+
1. **You write workflow functions.** Plain TypeScript — branching, loops, error handling. HotMesh also supports a YAML syntax for declarative, functional workflows.
|
|
21
|
+
2. **HotMesh compiles them into a transactional execution plan.** Each step becomes a committed database row. If the process crashes mid-workflow, it resumes from the last committed step.
|
|
22
|
+
3. **Your Postgres database is the engine.** It stores state, coordinates retries, and delivers messages. Every connected client participates in execution — there is no central server.
|
|
18
23
|
|
|
19
|
-
|
|
20
|
-
Choose your style: procedural workflows with MemFlow's Temporal API, or functional workflows with HotMesh's YAML syntax.
|
|
24
|
+
## Quickstart
|
|
21
25
|
|
|
22
|
-
|
|
26
|
+
Install the package:
|
|
23
27
|
|
|
24
28
|
```bash
|
|
25
29
|
npm install @hotmeshio/hotmesh
|
|
26
30
|
```
|
|
27
31
|
|
|
32
|
+
The repo includes a `docker-compose.yml` that starts Postgres, NATS, and a development container:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
docker compose up -d
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Then follow the [Quick Start guide](https://github.com/hotmeshio/sdk-typescript/blob/main/docs/quickstart.md) for a progressive walkthrough — from a single trigger to conditional, parallel, and compositional workflows.
|
|
39
|
+
|
|
28
40
|
## Two ways to write workflows
|
|
29
41
|
|
|
30
42
|
Both approaches reuse your activity functions:
|
|
@@ -48,17 +60,17 @@ export async function notifyBackorder(itemId: string): Promise<void> {
|
|
|
48
60
|
|
|
49
61
|
```typescript
|
|
50
62
|
// workflows.ts
|
|
51
|
-
import {
|
|
63
|
+
import { Durable } from '@hotmeshio/hotmesh';
|
|
52
64
|
import * as activities from './activities';
|
|
53
65
|
|
|
54
66
|
export async function orderWorkflow(itemId: string, qty: number) {
|
|
55
|
-
const { checkInventory, reserveItem, notifyBackorder } =
|
|
56
|
-
|
|
67
|
+
const { checkInventory, reserveItem, notifyBackorder } =
|
|
68
|
+
Durable.workflow.proxyActivities<typeof activities>({
|
|
57
69
|
taskQueue: 'inventory-tasks'
|
|
58
70
|
});
|
|
59
|
-
|
|
71
|
+
|
|
60
72
|
const available = await checkInventory(itemId);
|
|
61
|
-
|
|
73
|
+
|
|
62
74
|
if (available >= qty) {
|
|
63
75
|
return await reserveItem(itemId, qty);
|
|
64
76
|
} else {
|
|
@@ -73,18 +85,18 @@ const connection = {
|
|
|
73
85
|
options: { connectionString: 'postgresql://localhost:5432/mydb' }
|
|
74
86
|
};
|
|
75
87
|
|
|
76
|
-
await
|
|
88
|
+
await Durable.registerActivityWorker({
|
|
77
89
|
connection,
|
|
78
90
|
taskQueue: 'inventory-tasks'
|
|
79
91
|
}, activities, 'inventory-activities');
|
|
80
92
|
|
|
81
|
-
await
|
|
93
|
+
await Durable.Worker.create({
|
|
82
94
|
connection,
|
|
83
95
|
taskQueue: 'orders',
|
|
84
96
|
workflow: orderWorkflow
|
|
85
97
|
});
|
|
86
98
|
|
|
87
|
-
const client = new
|
|
99
|
+
const client = new Durable.Client({ connection });
|
|
88
100
|
const handle = await client.workflow.start({
|
|
89
101
|
args: ['item-123', 5],
|
|
90
102
|
taskQueue: 'orders',
|
|
@@ -102,23 +114,23 @@ const result = await handle.result();
|
|
|
102
114
|
activities:
|
|
103
115
|
trigger:
|
|
104
116
|
type: trigger
|
|
105
|
-
|
|
117
|
+
|
|
106
118
|
checkInventory:
|
|
107
119
|
type: worker
|
|
108
120
|
topic: inventory.check
|
|
109
|
-
|
|
121
|
+
|
|
110
122
|
reserveItem:
|
|
111
123
|
type: worker
|
|
112
124
|
topic: inventory.reserve
|
|
113
|
-
|
|
125
|
+
|
|
114
126
|
notifyBackorder:
|
|
115
127
|
type: worker
|
|
116
128
|
topic: inventory.backorder.notify
|
|
117
|
-
|
|
129
|
+
|
|
118
130
|
transitions:
|
|
119
131
|
trigger:
|
|
120
132
|
- to: checkInventory
|
|
121
|
-
|
|
133
|
+
|
|
122
134
|
checkInventory:
|
|
123
135
|
- to: reserveItem
|
|
124
136
|
conditions:
|
|
@@ -128,7 +140,7 @@ transitions:
|
|
|
128
140
|
'@pipe':
|
|
129
141
|
- ['{checkInventory.output.data.availableQty}', '{trigger.output.data.requestedQty}']
|
|
130
142
|
- ['{@conditional.gte}']
|
|
131
|
-
|
|
143
|
+
|
|
132
144
|
- to: notifyBackorder
|
|
133
145
|
conditions:
|
|
134
146
|
match:
|
|
@@ -139,6 +151,7 @@ transitions:
|
|
|
139
151
|
- ['{@conditional.gte}']
|
|
140
152
|
```
|
|
141
153
|
|
|
154
|
+
Deploy and run as follows:
|
|
142
155
|
```typescript
|
|
143
156
|
// main.ts (reuses same activities.ts)
|
|
144
157
|
import * as activities from './activities';
|
|
@@ -185,42 +198,164 @@ const result = await hotMesh.pubsub('order.requested', {
|
|
|
185
198
|
|
|
186
199
|
Both compile to the same distributed execution model.
|
|
187
200
|
|
|
188
|
-
##
|
|
201
|
+
## Common patterns
|
|
189
202
|
|
|
190
|
-
|
|
191
|
-
- **No infrastructure** - Runs on your existing Postgres
|
|
192
|
-
- **Temporal compatible** - Drop-in replacement for many use cases
|
|
193
|
-
- **Distributed** - Every client participates in execution
|
|
194
|
-
- **Observable** - Full execution history in your database
|
|
203
|
+
All snippets below run inside a workflow function (like `orderWorkflow` above). Durable methods are available as static imports:
|
|
195
204
|
|
|
196
|
-
|
|
205
|
+
```typescript
|
|
206
|
+
import { Durable } from '@hotmeshio/hotmesh';
|
|
207
|
+
```
|
|
197
208
|
|
|
198
|
-
**Long-running workflows**
|
|
209
|
+
**Long-running workflows** — `sleepFor` is durable. The process can restart; the timer survives.
|
|
199
210
|
|
|
200
211
|
```typescript
|
|
201
|
-
|
|
212
|
+
// sendFollowUp is a proxied activity from proxyActivities()
|
|
213
|
+
await Durable.workflow.sleepFor('30 days');
|
|
202
214
|
await sendFollowUp();
|
|
203
215
|
```
|
|
204
216
|
|
|
205
|
-
**Parallel execution**
|
|
217
|
+
**Parallel execution** — fan out to multiple activities and wait for all results.
|
|
206
218
|
|
|
207
219
|
```typescript
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
220
|
+
// proxied activities run as durable, retryable steps
|
|
221
|
+
const [payment, inventory, shipment] = await Promise.all([
|
|
222
|
+
processPayment(orderId),
|
|
223
|
+
updateInventory(orderId),
|
|
224
|
+
notifyWarehouse(orderId)
|
|
212
225
|
]);
|
|
213
226
|
```
|
|
214
227
|
|
|
215
|
-
**Child workflows**
|
|
228
|
+
**Child workflows** — compose workflows from other workflows.
|
|
216
229
|
|
|
217
230
|
```typescript
|
|
218
|
-
const childHandle = await startChild(validateOrder, {
|
|
231
|
+
const childHandle = await Durable.workflow.startChild(validateOrder, {
|
|
232
|
+
args: [orderId],
|
|
233
|
+
taskQueue: 'validation',
|
|
234
|
+
workflowId: `validate-${orderId}`
|
|
235
|
+
});
|
|
219
236
|
const validation = await childHandle.result();
|
|
220
237
|
```
|
|
221
238
|
|
|
222
|
-
|
|
239
|
+
**Signals** — pause a workflow until an external event arrives.
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
const approval = await Durable.workflow.waitFor<{ approved: boolean }>('manager-approval');
|
|
243
|
+
if (!approval.approved) return 'rejected';
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Retries and error handling
|
|
247
|
+
|
|
248
|
+
Activities retry automatically on failure. Configure the policy per activity or per worker:
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
// Durable: per-activity retry policy
|
|
252
|
+
const { reserveItem } = Durable.workflow.proxyActivities<typeof activities>({
|
|
253
|
+
taskQueue: 'inventory-tasks',
|
|
254
|
+
retryPolicy: {
|
|
255
|
+
maximumAttempts: 5,
|
|
256
|
+
backoffCoefficient: 2,
|
|
257
|
+
maximumInterval: '60s'
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
// HotMesh: worker-level retry policy
|
|
264
|
+
const hotMesh = await HotMesh.init({
|
|
265
|
+
appId: 'orders',
|
|
266
|
+
engine: { connection },
|
|
267
|
+
workers: [{
|
|
268
|
+
topic: 'inventory.reserve',
|
|
269
|
+
connection,
|
|
270
|
+
retryPolicy: {
|
|
271
|
+
maximumAttempts: 5,
|
|
272
|
+
backoffCoefficient: 2,
|
|
273
|
+
maximumInterval: '60s'
|
|
274
|
+
},
|
|
275
|
+
callback: async (data) => { /* ... */ }
|
|
276
|
+
}]
|
|
277
|
+
});
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Defaults: 3 attempts, coefficient 10, 120s cap. Delay formula: `min(coefficient ^ attempt, maximumInterval)`. Duration strings like `'5 seconds'`, `'2 minutes'`, and `'1 hour'` are supported.
|
|
281
|
+
|
|
282
|
+
If all retries are exhausted, the activity fails and the error propagates to the workflow function — handle it with a standard `try/catch`.
|
|
283
|
+
|
|
284
|
+
## Workflow state is queryable data
|
|
285
|
+
|
|
286
|
+
Workflow state lives in your database as ordinary rows — `jobs` and `jobs_attributes`. Query it directly, back it up with pg_dump, replicate it, join it against your application tables.
|
|
287
|
+
|
|
288
|
+
```sql
|
|
289
|
+
SELECT
|
|
290
|
+
j.key AS job_key,
|
|
291
|
+
j.status AS semaphore,
|
|
292
|
+
j.entity AS workflow,
|
|
293
|
+
a.field AS attribute,
|
|
294
|
+
a.value AS value,
|
|
295
|
+
j.created_at,
|
|
296
|
+
j.updated_at
|
|
297
|
+
FROM
|
|
298
|
+
jobs j
|
|
299
|
+
JOIN jobs_attributes a ON a.job_id = j.id
|
|
300
|
+
WHERE
|
|
301
|
+
j.key = 'order-456'
|
|
302
|
+
ORDER BY
|
|
303
|
+
a.field;
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
What happened? Consult the database. What's still running? Query the semaphore. What failed? Read the row. The execution state isn't reconstructed from a log — it was committed transactionally as each step ran.
|
|
307
|
+
|
|
308
|
+
You can also use the Temporal-compatible API:
|
|
309
|
+
|
|
310
|
+
```typescript
|
|
311
|
+
const handle = client.workflow.getHandle('orders', 'orderWorkflow', 'order-456');
|
|
312
|
+
|
|
313
|
+
const result = await handle.result(); // final output
|
|
314
|
+
const status = await handle.status(); // semaphore (0 = complete)
|
|
315
|
+
const state = await handle.state(true); // full state with metadata
|
|
316
|
+
const exported = await handle.export({ // selective export
|
|
317
|
+
allow: ['data', 'state', 'status', 'timeline']
|
|
318
|
+
});
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## Observability
|
|
322
|
+
|
|
323
|
+
There is no proprietary dashboard. Workflow state lives in Postgres, so use whatever tools you already have:
|
|
223
324
|
|
|
224
|
-
|
|
325
|
+
- **Direct SQL** — query `jobs` and `jobs_attributes` to inspect state, as shown above.
|
|
326
|
+
- **Handle API** — `handle.status()`, `handle.state(true)`, and `handle.export()` give programmatic access to any running or completed workflow.
|
|
327
|
+
- **Logging** — set `HMSH_LOGLEVEL` (`debug`, `info`, `warn`, `error`, `silent`) to control log verbosity.
|
|
328
|
+
- **OpenTelemetry** — set `HMSH_TELEMETRY=true` to emit spans and metrics. Plug in any OTel-compatible collector.
|
|
329
|
+
|
|
330
|
+
## Architecture
|
|
331
|
+
|
|
332
|
+
For a deep dive into the transactional execution model — how every step is crash-safe, how the monotonic collation ledger guarantees exactly-once delivery, and how cycles and retries remain correct under arbitrary failure — see the [Collation Design Document](https://github.com/hotmeshio/sdk-typescript/blob/main/services/collator/README.md). The symbolic system (how to design workflows) and lifecycle details (how to deploy workflows) are covered in the [Architectural Overview](https://zenodo.org/records/12168558).
|
|
333
|
+
|
|
334
|
+
## Familiar with Temporal?
|
|
335
|
+
|
|
336
|
+
Durable is designed as a drop-in-compatible alternative for common Temporal patterns.
|
|
337
|
+
|
|
338
|
+
**What's the same:** `Client`, `Worker`, `proxyActivities`, `sleepFor`, `startChild`/`execChild`, signals (`waitFor`/`signal`), retry policies, and the overall workflow-as-code programming model.
|
|
339
|
+
|
|
340
|
+
**What's different:** No Temporal server or cluster to operate. Postgres is the only infrastructure dependency — it stores state, coordinates workers, and delivers messages. HotMesh also offers a YAML-based approach for declarative workflows that compile to the same execution model.
|
|
341
|
+
|
|
342
|
+
## Running tests
|
|
343
|
+
|
|
344
|
+
Tests run inside Docker. Start the services and run the full suite:
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
docker compose up -d
|
|
348
|
+
docker compose exec hotmesh npm test
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
Run a specific test group:
|
|
352
|
+
|
|
353
|
+
```bash
|
|
354
|
+
docker compose exec hotmesh npm run test:durable # all Durable tests (Temporal pattern coverage proofs)
|
|
355
|
+
docker compose exec hotmesh npm run test:durable:hello # single Durable test (hello world proxyActivity proof)
|
|
356
|
+
docker compose exec hotmesh npm run test:virtual # all Virtual network function (VNF) tests
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
## License
|
|
225
360
|
|
|
226
|
-
|
|
361
|
+
HotMesh is source-available under the [HotMesh Source Available License](./LICENSE).
|
package/build/index.d.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { HotMesh } from './services/hotmesh';
|
|
2
2
|
import { HotMeshConfig } from './types/hotmesh';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
3
|
+
import { Virtual } from './services/virtual';
|
|
4
|
+
import { Durable } from './services/durable';
|
|
5
|
+
import { DBA } from './services/dba';
|
|
6
|
+
import { ClientService as Client } from './services/durable/client';
|
|
7
|
+
import { ConnectionService as Connection } from './services/durable/connection';
|
|
8
|
+
import { Search } from './services/durable/search';
|
|
9
|
+
import { Entity } from './services/durable/entity';
|
|
10
|
+
import { WorkerService as Worker } from './services/durable/worker';
|
|
11
|
+
import { WorkflowService as workflow } from './services/durable/workflow';
|
|
12
|
+
import { WorkflowHandleService as WorkflowHandle } from './services/durable/handle';
|
|
13
|
+
import { proxyActivities } from './services/durable/workflow/proxyActivities';
|
|
13
14
|
import * as Errors from './modules/errors';
|
|
14
15
|
import * as Utils from './modules/utils';
|
|
15
16
|
import * as Enums from './modules/enums';
|
|
@@ -18,5 +19,5 @@ import { ConnectorService as Connector } from './services/connector/factory';
|
|
|
18
19
|
import { PostgresConnection as ConnectorPostgres } from './services/connector/providers/postgres';
|
|
19
20
|
import { NatsConnection as ConnectorNATS } from './services/connector/providers/nats';
|
|
20
21
|
export { Connector, //factory
|
|
21
|
-
ConnectorNATS, ConnectorPostgres, HotMesh, HotMeshConfig,
|
|
22
|
+
ConnectorNATS, ConnectorPostgres, HotMesh, HotMeshConfig, Virtual, Durable, DBA, Client, Connection, proxyActivities, Search, Entity, Worker, workflow, WorkflowHandle, Enums, Errors, Utils, KeyStore, };
|
|
22
23
|
export * as Types from './types';
|
package/build/index.js
CHANGED
|
@@ -23,28 +23,30 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.Types = exports.KeyStore = exports.Utils = exports.Errors = exports.Enums = exports.WorkflowHandle = exports.workflow = exports.Worker = exports.Entity = exports.Search = exports.proxyActivities = exports.Connection = exports.Client = exports.
|
|
26
|
+
exports.Types = exports.KeyStore = exports.Utils = exports.Errors = exports.Enums = exports.WorkflowHandle = exports.workflow = exports.Worker = exports.Entity = exports.Search = exports.proxyActivities = exports.Connection = exports.Client = exports.DBA = exports.Durable = exports.Virtual = exports.HotMesh = exports.ConnectorPostgres = exports.ConnectorNATS = exports.Connector = void 0;
|
|
27
27
|
const hotmesh_1 = require("./services/hotmesh");
|
|
28
28
|
Object.defineProperty(exports, "HotMesh", { enumerable: true, get: function () { return hotmesh_1.HotMesh; } });
|
|
29
|
-
const
|
|
30
|
-
Object.defineProperty(exports, "
|
|
31
|
-
const
|
|
32
|
-
Object.defineProperty(exports, "
|
|
33
|
-
const
|
|
29
|
+
const virtual_1 = require("./services/virtual");
|
|
30
|
+
Object.defineProperty(exports, "Virtual", { enumerable: true, get: function () { return virtual_1.Virtual; } });
|
|
31
|
+
const durable_1 = require("./services/durable");
|
|
32
|
+
Object.defineProperty(exports, "Durable", { enumerable: true, get: function () { return durable_1.Durable; } });
|
|
33
|
+
const dba_1 = require("./services/dba");
|
|
34
|
+
Object.defineProperty(exports, "DBA", { enumerable: true, get: function () { return dba_1.DBA; } });
|
|
35
|
+
const client_1 = require("./services/durable/client");
|
|
34
36
|
Object.defineProperty(exports, "Client", { enumerable: true, get: function () { return client_1.ClientService; } });
|
|
35
|
-
const connection_1 = require("./services/
|
|
37
|
+
const connection_1 = require("./services/durable/connection");
|
|
36
38
|
Object.defineProperty(exports, "Connection", { enumerable: true, get: function () { return connection_1.ConnectionService; } });
|
|
37
|
-
const search_1 = require("./services/
|
|
39
|
+
const search_1 = require("./services/durable/search");
|
|
38
40
|
Object.defineProperty(exports, "Search", { enumerable: true, get: function () { return search_1.Search; } });
|
|
39
|
-
const entity_1 = require("./services/
|
|
41
|
+
const entity_1 = require("./services/durable/entity");
|
|
40
42
|
Object.defineProperty(exports, "Entity", { enumerable: true, get: function () { return entity_1.Entity; } });
|
|
41
|
-
const worker_1 = require("./services/
|
|
43
|
+
const worker_1 = require("./services/durable/worker");
|
|
42
44
|
Object.defineProperty(exports, "Worker", { enumerable: true, get: function () { return worker_1.WorkerService; } });
|
|
43
|
-
const workflow_1 = require("./services/
|
|
45
|
+
const workflow_1 = require("./services/durable/workflow");
|
|
44
46
|
Object.defineProperty(exports, "workflow", { enumerable: true, get: function () { return workflow_1.WorkflowService; } });
|
|
45
|
-
const handle_1 = require("./services/
|
|
47
|
+
const handle_1 = require("./services/durable/handle");
|
|
46
48
|
Object.defineProperty(exports, "WorkflowHandle", { enumerable: true, get: function () { return handle_1.WorkflowHandleService; } });
|
|
47
|
-
const proxyActivities_1 = require("./services/
|
|
49
|
+
const proxyActivities_1 = require("./services/durable/workflow/proxyActivities");
|
|
48
50
|
Object.defineProperty(exports, "proxyActivities", { enumerable: true, get: function () { return proxyActivities_1.proxyActivities; } });
|
|
49
51
|
const Errors = __importStar(require("./modules/errors"));
|
|
50
52
|
exports.Errors = Errors;
|
package/build/modules/enums.d.ts
CHANGED
|
@@ -11,10 +11,6 @@ export declare const HMSH_TELEMETRY: "debug" | "info";
|
|
|
11
11
|
* Default cleanup time for signal in the db when its associated job is completed.
|
|
12
12
|
*/
|
|
13
13
|
export declare const HMSH_SIGNAL_EXPIRE = 3600;
|
|
14
|
-
/**
|
|
15
|
-
* Determines if the system is running in cluster mode (for Redis cluster support).
|
|
16
|
-
*/
|
|
17
|
-
export declare const HMSH_IS_CLUSTER: boolean;
|
|
18
14
|
export declare const HMSH_CODE_SUCCESS = 200;
|
|
19
15
|
export declare const HMSH_CODE_PENDING = 202;
|
|
20
16
|
export declare const HMSH_CODE_NOTFOUND = 404;
|
|
@@ -23,43 +19,43 @@ export declare const HMSH_CODE_UNKNOWN = 500;
|
|
|
23
19
|
export declare const HMSH_CODE_TIMEOUT = 504;
|
|
24
20
|
export declare const HMSH_CODE_UNACKED = 999;
|
|
25
21
|
/**
|
|
26
|
-
* This is thrown when a
|
|
22
|
+
* This is thrown when a Durable has been interrupted by a sleepFor call.
|
|
27
23
|
*/
|
|
28
|
-
export declare const
|
|
24
|
+
export declare const HMSH_CODE_DURABLE_SLEEP = 588;
|
|
29
25
|
/**
|
|
30
|
-
* This is thrown when a
|
|
26
|
+
* This is thrown when a Durable has been interrupted by a Promise.all call.
|
|
31
27
|
*/
|
|
32
|
-
export declare const
|
|
28
|
+
export declare const HMSH_CODE_DURABLE_ALL = 589;
|
|
33
29
|
/**
|
|
34
|
-
* This is thrown when a
|
|
30
|
+
* This is thrown when a Durable has been interrupted by an execChild or startChild call.
|
|
35
31
|
*/
|
|
36
|
-
export declare const
|
|
32
|
+
export declare const HMSH_CODE_DURABLE_CHILD = 590;
|
|
37
33
|
/**
|
|
38
|
-
* This is thrown when a
|
|
34
|
+
* This is thrown when a Durable has been interrupted by a proxyActivity call.
|
|
39
35
|
*/
|
|
40
|
-
export declare const
|
|
36
|
+
export declare const HMSH_CODE_DURABLE_PROXY = 591;
|
|
41
37
|
/**
|
|
42
|
-
* This is thrown when a
|
|
38
|
+
* This is thrown when a Durable has been interrupted by a waitForSignal call.
|
|
43
39
|
*/
|
|
44
|
-
export declare const
|
|
40
|
+
export declare const HMSH_CODE_DURABLE_WAIT = 595;
|
|
45
41
|
/**
|
|
46
|
-
* The timeout status code for
|
|
42
|
+
* The timeout status code for Durable. This status code is thrown when Durable has encountered a timeout error and needs to aler the caller why the call failed.
|
|
47
43
|
*/
|
|
48
|
-
export declare const
|
|
44
|
+
export declare const HMSH_CODE_DURABLE_TIMEOUT = 596;
|
|
49
45
|
/**
|
|
50
|
-
* The maxed status code for
|
|
46
|
+
* The maxed status code for Durable. This status code is used to indicate that the Durable has reached the maximum
|
|
51
47
|
* number of attempts and should be halted. Thrown from a proxied activity or a flow to halt standard execution
|
|
52
48
|
* and prevent further attempts.
|
|
53
49
|
*/
|
|
54
|
-
export declare const
|
|
50
|
+
export declare const HMSH_CODE_DURABLE_MAXED = 597;
|
|
55
51
|
/**
|
|
56
|
-
* The fatal status code for
|
|
52
|
+
* The fatal status code for Durable. This status code is used to indicate that the Durable has encountered a fatal error. Throw from a proxied activity or a flow to halt standard execution.
|
|
57
53
|
*/
|
|
58
|
-
export declare const
|
|
54
|
+
export declare const HMSH_CODE_DURABLE_FATAL = 598;
|
|
59
55
|
/**
|
|
60
|
-
* The retryable status code for
|
|
56
|
+
* The retryable status code for Durable. This status code is used to indicate that the Durable has encountered a retryable error (essentially unknown and covered by the standard retry policy).
|
|
61
57
|
*/
|
|
62
|
-
export declare const
|
|
58
|
+
export declare const HMSH_CODE_DURABLE_RETRYABLE = 599;
|
|
63
59
|
export declare const HMSH_STATUS_UNKNOWN = "unknown";
|
|
64
60
|
/**
|
|
65
61
|
* The number of cycles to re/try for a quorum to be established.
|
|
@@ -85,20 +81,20 @@ export declare const HMSH_MAX_RETRIES: number;
|
|
|
85
81
|
export declare const HMSH_MAX_TIMEOUT_MS: number;
|
|
86
82
|
export declare const HMSH_GRADUATED_INTERVAL_MS: number;
|
|
87
83
|
/**
|
|
88
|
-
* The maximum number of attempts to retry a
|
|
84
|
+
* The maximum number of attempts to retry a Durable job before it is considered failed.
|
|
89
85
|
* @default 3
|
|
90
86
|
*/
|
|
91
|
-
export declare const
|
|
87
|
+
export declare const HMSH_DURABLE_MAX_ATTEMPTS = 3;
|
|
92
88
|
/**
|
|
93
|
-
* The maximum interval to wait before retrying a
|
|
89
|
+
* The maximum interval to wait before retrying a Durable job.
|
|
94
90
|
* @default 120s
|
|
95
91
|
*/
|
|
96
|
-
export declare const
|
|
92
|
+
export declare const HMSH_DURABLE_MAX_INTERVAL = "120s";
|
|
97
93
|
/**
|
|
98
94
|
* The exponential backoff factor to apply to the interval between retries.
|
|
99
95
|
* @default 10
|
|
100
96
|
*/
|
|
101
|
-
export declare const
|
|
97
|
+
export declare const HMSH_DURABLE_EXP_BACKOFF = 10;
|
|
102
98
|
export declare const HMSH_BLOCK_TIME_MS: number;
|
|
103
99
|
export declare const HMSH_XCLAIM_DELAY_MS: number;
|
|
104
100
|
export declare const HMSH_XCLAIM_COUNT: number;
|
|
@@ -124,10 +120,3 @@ export declare const HMSH_NOTIFY_PAYLOAD_LIMIT: number;
|
|
|
124
120
|
* Used when LISTEN/NOTIFY is unavailable or fails. Default 30 seconds.
|
|
125
121
|
*/
|
|
126
122
|
export declare const HMSH_ROUTER_POLL_FALLBACK_INTERVAL: number;
|
|
127
|
-
/**
|
|
128
|
-
* Serializer compression threshold. When a stringified object exceeds this size
|
|
129
|
-
* in bytes, it will be gzipped and base64 encoded (with /b prefix) to reduce
|
|
130
|
-
* Redis hash storage size. Default 100 bytes - small enough to catch most
|
|
131
|
-
* workflow state but compression only applies if it actually reduces size.
|
|
132
|
-
*/
|
|
133
|
-
export declare const HMSH_SERIALIZER_COMPRESSION_THRESHOLD: number;
|
package/build/modules/enums.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.HMSH_NOTIFY_PAYLOAD_LIMIT = exports.DEFAULT_TASK_QUEUE = exports.HMSH_GUID_SIZE = exports.HMSH_ROUTER_SCOUT_INTERVAL_MS = exports.HMSH_ROUTER_SCOUT_INTERVAL_SECONDS = exports.HMSH_SCOUT_INTERVAL_SECONDS = exports.HMSH_FIDELITY_SECONDS = exports.HMSH_EXPIRE_DURATION = exports.HMSH_XPENDING_COUNT = exports.HMSH_XCLAIM_COUNT = exports.HMSH_XCLAIM_DELAY_MS = exports.HMSH_BLOCK_TIME_MS = exports.
|
|
4
|
-
exports.HMSH_SERIALIZER_COMPRESSION_THRESHOLD = exports.HMSH_ROUTER_POLL_FALLBACK_INTERVAL = void 0;
|
|
3
|
+
exports.HMSH_ROUTER_POLL_FALLBACK_INTERVAL = exports.HMSH_NOTIFY_PAYLOAD_LIMIT = exports.DEFAULT_TASK_QUEUE = exports.HMSH_GUID_SIZE = exports.HMSH_ROUTER_SCOUT_INTERVAL_MS = exports.HMSH_ROUTER_SCOUT_INTERVAL_SECONDS = exports.HMSH_SCOUT_INTERVAL_SECONDS = exports.HMSH_FIDELITY_SECONDS = exports.HMSH_EXPIRE_DURATION = exports.HMSH_XPENDING_COUNT = exports.HMSH_XCLAIM_COUNT = exports.HMSH_XCLAIM_DELAY_MS = exports.HMSH_BLOCK_TIME_MS = exports.HMSH_DURABLE_EXP_BACKOFF = exports.HMSH_DURABLE_MAX_INTERVAL = exports.HMSH_DURABLE_MAX_ATTEMPTS = exports.HMSH_GRADUATED_INTERVAL_MS = exports.HMSH_MAX_TIMEOUT_MS = exports.HMSH_MAX_RETRIES = exports.MAX_DELAY = exports.MAX_STREAM_RETRIES = exports.INITIAL_STREAM_BACKOFF = exports.MAX_STREAM_BACKOFF = exports.HMSH_EXPIRE_JOB_SECONDS = exports.HMSH_OTT_WAIT_TIME = exports.HMSH_DEPLOYMENT_PAUSE = exports.HMSH_DEPLOYMENT_DELAY = exports.HMSH_ACTIVATION_MAX_RETRY = exports.HMSH_QUORUM_DELAY_MS = exports.HMSH_QUORUM_ROLLCALL_CYCLES = exports.HMSH_STATUS_UNKNOWN = exports.HMSH_CODE_DURABLE_RETRYABLE = exports.HMSH_CODE_DURABLE_FATAL = exports.HMSH_CODE_DURABLE_MAXED = exports.HMSH_CODE_DURABLE_TIMEOUT = exports.HMSH_CODE_DURABLE_WAIT = exports.HMSH_CODE_DURABLE_PROXY = exports.HMSH_CODE_DURABLE_CHILD = exports.HMSH_CODE_DURABLE_ALL = exports.HMSH_CODE_DURABLE_SLEEP = exports.HMSH_CODE_UNACKED = exports.HMSH_CODE_TIMEOUT = exports.HMSH_CODE_UNKNOWN = exports.HMSH_CODE_INTERRUPT = exports.HMSH_CODE_NOTFOUND = exports.HMSH_CODE_PENDING = exports.HMSH_CODE_SUCCESS = exports.HMSH_SIGNAL_EXPIRE = exports.HMSH_TELEMETRY = exports.HMSH_LOGLEVEL = void 0;
|
|
5
4
|
/**
|
|
6
5
|
* Determines the log level for the application. The default is 'info'.
|
|
7
6
|
*/
|
|
@@ -14,10 +13,6 @@ exports.HMSH_TELEMETRY = process.env.HMSH_TELEMETRY || 'info';
|
|
|
14
13
|
* Default cleanup time for signal in the db when its associated job is completed.
|
|
15
14
|
*/
|
|
16
15
|
exports.HMSH_SIGNAL_EXPIRE = 3600; //seconds
|
|
17
|
-
/**
|
|
18
|
-
* Determines if the system is running in cluster mode (for Redis cluster support).
|
|
19
|
-
*/
|
|
20
|
-
exports.HMSH_IS_CLUSTER = process.env.HMSH_IS_CLUSTER === 'true';
|
|
21
16
|
// HOTMESH STATUS CODES
|
|
22
17
|
exports.HMSH_CODE_SUCCESS = 200;
|
|
23
18
|
exports.HMSH_CODE_PENDING = 202;
|
|
@@ -26,45 +21,45 @@ exports.HMSH_CODE_INTERRUPT = 410;
|
|
|
26
21
|
exports.HMSH_CODE_UNKNOWN = 500;
|
|
27
22
|
exports.HMSH_CODE_TIMEOUT = 504;
|
|
28
23
|
exports.HMSH_CODE_UNACKED = 999;
|
|
29
|
-
//
|
|
24
|
+
// DURABLE STATUS CODES
|
|
30
25
|
/**
|
|
31
|
-
* This is thrown when a
|
|
26
|
+
* This is thrown when a Durable has been interrupted by a sleepFor call.
|
|
32
27
|
*/
|
|
33
|
-
exports.
|
|
28
|
+
exports.HMSH_CODE_DURABLE_SLEEP = 588;
|
|
34
29
|
/**
|
|
35
|
-
* This is thrown when a
|
|
30
|
+
* This is thrown when a Durable has been interrupted by a Promise.all call.
|
|
36
31
|
*/
|
|
37
|
-
exports.
|
|
32
|
+
exports.HMSH_CODE_DURABLE_ALL = 589;
|
|
38
33
|
/**
|
|
39
|
-
* This is thrown when a
|
|
34
|
+
* This is thrown when a Durable has been interrupted by an execChild or startChild call.
|
|
40
35
|
*/
|
|
41
|
-
exports.
|
|
36
|
+
exports.HMSH_CODE_DURABLE_CHILD = 590;
|
|
42
37
|
/**
|
|
43
|
-
* This is thrown when a
|
|
38
|
+
* This is thrown when a Durable has been interrupted by a proxyActivity call.
|
|
44
39
|
*/
|
|
45
|
-
exports.
|
|
40
|
+
exports.HMSH_CODE_DURABLE_PROXY = 591;
|
|
46
41
|
/**
|
|
47
|
-
* This is thrown when a
|
|
42
|
+
* This is thrown when a Durable has been interrupted by a waitForSignal call.
|
|
48
43
|
*/
|
|
49
|
-
exports.
|
|
44
|
+
exports.HMSH_CODE_DURABLE_WAIT = 595;
|
|
50
45
|
/**
|
|
51
|
-
* The timeout status code for
|
|
46
|
+
* The timeout status code for Durable. This status code is thrown when Durable has encountered a timeout error and needs to aler the caller why the call failed.
|
|
52
47
|
*/
|
|
53
|
-
exports.
|
|
48
|
+
exports.HMSH_CODE_DURABLE_TIMEOUT = 596;
|
|
54
49
|
/**
|
|
55
|
-
* The maxed status code for
|
|
50
|
+
* The maxed status code for Durable. This status code is used to indicate that the Durable has reached the maximum
|
|
56
51
|
* number of attempts and should be halted. Thrown from a proxied activity or a flow to halt standard execution
|
|
57
52
|
* and prevent further attempts.
|
|
58
53
|
*/
|
|
59
|
-
exports.
|
|
54
|
+
exports.HMSH_CODE_DURABLE_MAXED = 597;
|
|
60
55
|
/**
|
|
61
|
-
* The fatal status code for
|
|
56
|
+
* The fatal status code for Durable. This status code is used to indicate that the Durable has encountered a fatal error. Throw from a proxied activity or a flow to halt standard execution.
|
|
62
57
|
*/
|
|
63
|
-
exports.
|
|
58
|
+
exports.HMSH_CODE_DURABLE_FATAL = 598;
|
|
64
59
|
/**
|
|
65
|
-
* The retryable status code for
|
|
60
|
+
* The retryable status code for Durable. This status code is used to indicate that the Durable has encountered a retryable error (essentially unknown and covered by the standard retry policy).
|
|
66
61
|
*/
|
|
67
|
-
exports.
|
|
62
|
+
exports.HMSH_CODE_DURABLE_RETRYABLE = 599;
|
|
68
63
|
// HOTMESH MESSAGES
|
|
69
64
|
exports.HMSH_STATUS_UNKNOWN = 'unknown';
|
|
70
65
|
// QUORUM
|
|
@@ -94,22 +89,22 @@ exports.MAX_DELAY = 2147483647; // Maximum allowed delay in milliseconds for set
|
|
|
94
89
|
exports.HMSH_MAX_RETRIES = parseInt(process.env.HMSH_MAX_RETRIES, 10) || 3;
|
|
95
90
|
exports.HMSH_MAX_TIMEOUT_MS = parseInt(process.env.HMSH_MAX_TIMEOUT_MS, 10) || 60000;
|
|
96
91
|
exports.HMSH_GRADUATED_INTERVAL_MS = parseInt(process.env.HMSH_GRADUATED_INTERVAL_MS, 10) || 5000;
|
|
97
|
-
//
|
|
92
|
+
// DURABLE
|
|
98
93
|
/**
|
|
99
|
-
* The maximum number of attempts to retry a
|
|
94
|
+
* The maximum number of attempts to retry a Durable job before it is considered failed.
|
|
100
95
|
* @default 3
|
|
101
96
|
*/
|
|
102
|
-
exports.
|
|
97
|
+
exports.HMSH_DURABLE_MAX_ATTEMPTS = 3;
|
|
103
98
|
/**
|
|
104
|
-
* The maximum interval to wait before retrying a
|
|
99
|
+
* The maximum interval to wait before retrying a Durable job.
|
|
105
100
|
* @default 120s
|
|
106
101
|
*/
|
|
107
|
-
exports.
|
|
102
|
+
exports.HMSH_DURABLE_MAX_INTERVAL = '120s';
|
|
108
103
|
/**
|
|
109
104
|
* The exponential backoff factor to apply to the interval between retries.
|
|
110
105
|
* @default 10
|
|
111
106
|
*/
|
|
112
|
-
exports.
|
|
107
|
+
exports.HMSH_DURABLE_EXP_BACKOFF = 10;
|
|
113
108
|
const BASE_BLOCK_DURATION = 10000;
|
|
114
109
|
const TEST_BLOCK_DURATION = 1000;
|
|
115
110
|
exports.HMSH_BLOCK_TIME_MS = process.env.HMSH_BLOCK_TIME_MS
|
|
@@ -156,10 +151,3 @@ exports.HMSH_NOTIFY_PAYLOAD_LIMIT = parseInt(process.env.HMSH_NOTIFY_PAYLOAD_LIM
|
|
|
156
151
|
* Used when LISTEN/NOTIFY is unavailable or fails. Default 30 seconds.
|
|
157
152
|
*/
|
|
158
153
|
exports.HMSH_ROUTER_POLL_FALLBACK_INTERVAL = parseInt(process.env.HOTMESH_POSTGRES_FALLBACK_INTERVAL, 10) || 30000;
|
|
159
|
-
/**
|
|
160
|
-
* Serializer compression threshold. When a stringified object exceeds this size
|
|
161
|
-
* in bytes, it will be gzipped and base64 encoded (with /b prefix) to reduce
|
|
162
|
-
* Redis hash storage size. Default 100 bytes - small enough to catch most
|
|
163
|
-
* workflow state but compression only applies if it actually reduces size.
|
|
164
|
-
*/
|
|
165
|
-
exports.HMSH_SERIALIZER_COMPRESSION_THRESHOLD = parseInt(process.env.HMSH_SERIALIZER_COMPRESSION_THRESHOLD, 10) || 100000000;
|