@memberjunction/task-graph 6.1.2 → 6.2.0-edge.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 +8 -0
- package/dist/TaskClaimStore.d.ts +49 -30
- package/dist/TaskClaimStore.d.ts.map +1 -1
- package/dist/TaskClaimStore.js +259 -322
- package/dist/TaskClaimStore.js.map +1 -1
- package/dist/TaskGraphDispatcher.d.ts +16 -0
- package/dist/TaskGraphDispatcher.d.ts.map +1 -1
- package/dist/TaskGraphDispatcher.js +51 -0
- package/dist/TaskGraphDispatcher.js.map +1 -1
- package/package.json +11 -11
package/README.md
CHANGED
|
@@ -105,6 +105,14 @@ If A dies, its claim expires and reconciliation makes the task claimable again.
|
|
|
105
105
|
the row changed underneath it (cancelled, reassigned, reclaimed), the guarded completion refuses and
|
|
106
106
|
A defers — overwriting would undo a newer, deliberate decision.
|
|
107
107
|
|
|
108
|
+
**Every guarded write is a stored procedure** (`spTaskGraph*`, granted to `cdp_Developer` and
|
|
109
|
+
`cdp_Integration`), and the store's reads go through the `MJ: Tasks` entity. That is not a style
|
|
110
|
+
choice: MJ grants its runtime roles SELECT on views and EXECUTE on procedures and never table-level
|
|
111
|
+
DML, so the earlier raw SQL against the `Task` table was refused outright under a least-privilege
|
|
112
|
+
login — and, because a refusal returned the same zero rowcount a lost race does, the dispatcher
|
|
113
|
+
skipped every task forever without saying so (#4575). Adding a guarded write means adding a
|
|
114
|
+
procedure and its GRANT in a migration, not a statement in TypeScript.
|
|
115
|
+
|
|
108
116
|
---
|
|
109
117
|
|
|
110
118
|
## Runners are seams, not implementations
|
package/dist/TaskClaimStore.d.ts
CHANGED
|
@@ -104,10 +104,24 @@ export declare class TaskClaimStore {
|
|
|
104
104
|
private readonly instanceID;
|
|
105
105
|
private readonly claimTTLSeconds;
|
|
106
106
|
constructor(instanceID: string, claimTTLSeconds: number);
|
|
107
|
+
/** The last guarded write's failure, or null when the last one actually ran. */
|
|
108
|
+
private _lastWriteError;
|
|
109
|
+
private _consecutiveWriteFailures;
|
|
110
|
+
/**
|
|
111
|
+
* Whether the most recent guarded write FAILED, as opposed to losing its race.
|
|
112
|
+
*
|
|
113
|
+
* The dispatcher reads this after a false return: "another instance won" and "this process
|
|
114
|
+
* cannot write to the database at all" produce the same `false`, and treating the second as the
|
|
115
|
+
* first is what let a dispatcher skip every task in the table, forever, in silence.
|
|
116
|
+
*/
|
|
117
|
+
get LastWriteFailed(): boolean;
|
|
118
|
+
/** The last failure's message, for a caller that wants to say why it is stuck. */
|
|
119
|
+
get LastWriteError(): string | null;
|
|
120
|
+
/** How many guarded writes have failed in a row. Reset by the first one that runs. */
|
|
121
|
+
get ConsecutiveWriteFailures(): number;
|
|
107
122
|
private sql;
|
|
108
|
-
/**
|
|
109
|
-
private
|
|
110
|
-
private agentRunTable;
|
|
123
|
+
/** The claim TTL as whole seconds, which is what the procedures take. */
|
|
124
|
+
private ttlSeconds;
|
|
111
125
|
/**
|
|
112
126
|
* Writes a graph's cost rollup onto the submitting run, those four columns and no others.
|
|
113
127
|
*
|
|
@@ -404,28 +418,6 @@ export declare class TaskClaimStore {
|
|
|
404
418
|
* Paths are nested `JSON_MODIFY` calls, so the whole set lands in one statement.
|
|
405
419
|
*/
|
|
406
420
|
TryWriteDebugFields(provider: IMetadataProvider, parentTaskID: string, fields: readonly TaskGraphDebugFieldWrite[], workflowTaskTypeID: string, contextUser: UserInfo): Promise<boolean>;
|
|
407
|
-
/**
|
|
408
|
-
* Wraps a payload expression so every object CONTAINING one of these paths exists.
|
|
409
|
-
*
|
|
410
|
-
* `JSON_MODIFY` does not create intermediate objects: writing `$.debug.paused` into a payload
|
|
411
|
-
* with no `debug` key, or `$.debug.edgeOverrides."<id>"` with no override map yet, silently
|
|
412
|
-
* changes nothing — which for a control verb means the write reports success (rowcount 1, the
|
|
413
|
-
* row WAS updated, just not the way anyone meant) and the workflow never pauses. A graph only
|
|
414
|
-
* acquires a `debug` key the first time somebody debugs it, so this is the NORMAL first call,
|
|
415
|
-
* not an edge case.
|
|
416
|
-
*
|
|
417
|
-
* This hazard arrived WITH field-scoped writes and is the price of them: the whole-bag write
|
|
418
|
-
* they replaced targeted `$.debug`, one level down from a root that always exists, so it
|
|
419
|
-
* created the containing object as a side effect of every verb. Field-scoping is still the
|
|
420
|
-
* right trade — it removes the step-resurrection class outright — but it moves the
|
|
421
|
-
* container's existence from implicit to something this method has to guarantee.
|
|
422
|
-
*
|
|
423
|
-
* Each containing object is created only when absent, shallowest first, so an existing bag is
|
|
424
|
-
* never replaced.
|
|
425
|
-
*/
|
|
426
|
-
private ensureObjects;
|
|
427
|
-
/** Renders one debug value as a SQL literal `JSON_MODIFY` will store with the right JSON type. */
|
|
428
|
-
private renderDebugValue;
|
|
429
421
|
/**
|
|
430
422
|
* Consumes a paused graph's one-shot step allowance — exactly once, across every instance.
|
|
431
423
|
*
|
|
@@ -488,10 +480,37 @@ export declare class TaskClaimStore {
|
|
|
488
480
|
* closed rather than relocated.)
|
|
489
481
|
*/
|
|
490
482
|
TryForceComplete(provider: IMetadataProvider, taskID: string, outputPayload: string | null, workflowTaskTypeID: string, contextUser: UserInfo): Promise<boolean>;
|
|
491
|
-
/**
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
483
|
+
/**
|
|
484
|
+
* Runs one guarded procedure and returns whether THIS instance won.
|
|
485
|
+
*
|
|
486
|
+
* A false here means the guard did not match — someone else won the race, or the row had already
|
|
487
|
+
* moved on. It does NOT mean the write failed; a failure returns false too, but records itself
|
|
488
|
+
* (see {@link LastWriteFailed}) so the caller can tell the two apart.
|
|
489
|
+
*/
|
|
490
|
+
private guardedWrite;
|
|
491
|
+
/**
|
|
492
|
+
* Calls one of the task-graph procedures, returning its rows — or `null` when the call FAILED.
|
|
493
|
+
*
|
|
494
|
+
* **Why procedures and not raw SQL** (#4575). These statements used to be sent as direct DML
|
|
495
|
+
* against the `Task` and `AIAgentRun` base tables. MJ grants its runtime roles SELECT on views
|
|
496
|
+
* and EXECUTE on procedures and never table-level DML, so under a least-privilege login every
|
|
497
|
+
* write was refused — and, because a refusal was reported as rowcount 0, the dispatcher read it
|
|
498
|
+
* as a lost race and skipped every task forever. The guards themselves are unchanged; they moved
|
|
499
|
+
* into procedures the runtime roles can actually execute.
|
|
500
|
+
*
|
|
501
|
+
* **Why `null` and not 0.** A statement that never ran is not a lost race, and collapsing the two
|
|
502
|
+
* is what kept that defect invisible. Callers still get `false` from {@link guardedWrite} — the
|
|
503
|
+
* dispatch loop must not fault on one bad write — but the failure is recorded and logged as a
|
|
504
|
+
* failure, so an inert dispatcher can say so.
|
|
505
|
+
*/
|
|
506
|
+
private callProc;
|
|
507
|
+
/**
|
|
508
|
+
* Renders one debug-bag field for the procedure's `@Fields` argument.
|
|
509
|
+
*
|
|
510
|
+
* The `Kind` travels with the value because it decides the JSON type written: a boolean stored as
|
|
511
|
+
* the string `"true"` reads back as truthy-but-wrong, and an object stored as a string reads back
|
|
512
|
+
* as a string.
|
|
513
|
+
*/
|
|
514
|
+
private renderDebugField;
|
|
496
515
|
}
|
|
497
516
|
//# sourceMappingURL=TaskClaimStore.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TaskClaimStore.d.ts","sourceRoot":"","sources":["../src/TaskClaimStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"TaskClaimStore.d.ts","sourceRoot":"","sources":["../src/TaskClaimStore.ts"],"names":[],"mappings":"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"}
|