@iworkflow/dbos 0.2.0 → 0.3.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/package.json +2 -2
- package/src/index.ts +28 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iworkflow/dbos",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "DBOS adapter for @iworkflow/core",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"workflow",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"test": "bun test"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@iworkflow/core": "^0.
|
|
32
|
+
"@iworkflow/core": "^0.3.0",
|
|
33
33
|
"pg": "^8.0.0"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
package/src/index.ts
CHANGED
|
@@ -167,7 +167,14 @@ async function withTimeout<T>(p: Promise<T>, ms: number): Promise<T> {
|
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
-
|
|
170
|
+
/** Повторы внутри одного runStep: процесс прерван (срок, отмена) — новых попыток нет. */
|
|
171
|
+
async function attempts(
|
|
172
|
+
fn: Activity,
|
|
173
|
+
args: unknown[],
|
|
174
|
+
opts: StepOptions,
|
|
175
|
+
pool: Semaphore | undefined,
|
|
176
|
+
alive: () => Promise<boolean>,
|
|
177
|
+
) {
|
|
171
178
|
const max = opts.attempts ?? 3;
|
|
172
179
|
const started = Date.now();
|
|
173
180
|
let interval = opts.retryIntervalMs ?? 200;
|
|
@@ -194,6 +201,9 @@ async function attempts(fn: Activity, args: unknown[], opts: StepOptions, pool:
|
|
|
194
201
|
details: e instanceof Failure ? e.details : undefined,
|
|
195
202
|
});
|
|
196
203
|
await sleepMs(interval);
|
|
204
|
+
// После паузы: за неё процесс мог выйти по сроку или быть отменён.
|
|
205
|
+
// Сбой чтения статуса — не повод бросать шаг: повторяем дальше.
|
|
206
|
+
if (!(await alive().catch(() => true))) throw new FlowError("процесс прерван — повторы шага остановлены", { reason: "terminated" });
|
|
197
207
|
interval = Math.min(interval * (opts.backoff ?? 1), opts.maxRetryIntervalMs ?? Infinity);
|
|
198
208
|
}
|
|
199
209
|
}
|
|
@@ -268,7 +278,23 @@ export function dbosRuntime(): EngineRuntime {
|
|
|
268
278
|
const pool = opts.pool ? pools[opts.pool] : undefined;
|
|
269
279
|
if (opts.pool && !pool) throw new Error(`пул "${opts.pool}" не объявлен в AppDefinition.pools модуля ${def.app}`);
|
|
270
280
|
// heartbeatTimeoutMs у DBOS не действует: умерший процесс ловится рестартом, шаг повторяется.
|
|
271
|
-
|
|
281
|
+
// Срок вышел, а DBOS ещё не отменил процесс — ждём отмены: иначе процесс поймает отказ и завершится успехом.
|
|
282
|
+
const alive = async () => {
|
|
283
|
+
for (;;) {
|
|
284
|
+
const st = (
|
|
285
|
+
await db.query(
|
|
286
|
+
"SELECT status, workflow_deadline_epoch_ms AS deadline FROM dbos.workflow_status WHERE workflow_uuid = $1",
|
|
287
|
+
[workflowId],
|
|
288
|
+
)
|
|
289
|
+
).rows[0];
|
|
290
|
+
if (!st || !["PENDING", "ENQUEUED"].includes(st.status)) return false;
|
|
291
|
+
if (st.deadline === null || Number(st.deadline) > Date.now()) return true;
|
|
292
|
+
// Отмену ставит DBOS; не поставил за минуту — не ждать вечно.
|
|
293
|
+
if (Date.now() - Number(st.deadline) > 60_000) return false;
|
|
294
|
+
await sleepMs(100);
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
return DBOS.runStep(() => attempts(def.activities[step]!, stepArgs, opts, pool, alive), {
|
|
272
298
|
name: step,
|
|
273
299
|
retriesAllowed: false,
|
|
274
300
|
}).catch((e) => {
|