@superdurable/dex 1.14.0 → 1.15.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 CHANGED
@@ -214,9 +214,13 @@ Flow type names must be unique within one Dex server. `maxConcurrentTasks`
214
214
  defaults to the logical CPU count, and `idleStreamsPerQueue` defaults to one.
215
215
  Each stream runs one task at a time. When all slots are busy, the Worker rejects
216
216
  additional assignments for reassignment. The Worker keeps idle streams on each
217
- queue even when all slots are busy, so it can hold up to
218
- `(1 + F) * (idleStreamsPerQueue + maxConcurrentTasks)` streams, where `F` is the
219
- number of registered Flow types. Size both options for the server's stream cap.
217
+ queue even when all slots are busy. After tasks finish, it gracefully closes surplus
218
+ idle streams while preserving readiness. With `F` registered Flow types, the
219
+ steady-state bound after load drops is
220
+ `maxConcurrentTasks + (1 + F) * idleStreamsPerQueue` streams. The transient peak
221
+ during a burst remains bounded by the matching caps. Size both options for
222
+ `matching.maxConcurrentTasksCap` per app Worker ID per matching owner and
223
+ `matching.maxStreams` per Matching instance.
220
224
 
221
225
  The Worker rejects an unregistered Step or RPC by name. Dex retries that task
222
226
  on another pull Worker without consuming a Step attempt, including when the
@@ -246,6 +250,41 @@ remaining drain deadline. A handler that ignores cancellation can delay shutdown
246
250
  `StepOptions.waitForMethodTimeoutMs` and `executeMethodTimeoutMs` bound the two
247
251
  handler calls. Timer and channel conditions determine how long a Step waits.
248
252
 
253
+ #### Reserved RPC capacity
254
+
255
+ Set `reservedRpcTasks` when synchronous RPC latency must stay responsive behind
256
+ long-running Steps. When unset, it reserves one slot if the resolved task limit
257
+ is at least two, otherwise zero. With the CPU-count default, Steps get one fewer
258
+ slot than before. Set it explicitly to zero to opt out. With one slot and no
259
+ explicit reserve, Worker start logs one warning: RPCs may wait behind
260
+ long-running Steps; use a limit of at least two or set the reserve explicitly.
261
+ Flows must stay responsive; Dex cannot prioritize synchronous RPCs like workflow
262
+ engines prioritize reads. The value must be nonnegative and less than
263
+ `maxConcurrentTasks` after its CPU-count default is resolved; invalid values
264
+ fail construction. RPC and Step handlers count together: WaitFor and Execute
265
+ tasks, including local attempts, are declined with `NO_CAPACITY` when the busy
266
+ count reaches the task limit minus the reserve. API-direct and transactional
267
+ InvokeWorkerRPC tasks can use the full limit.
268
+
269
+ ```ts
270
+ const pull: PullWorkerOptions = { maxConcurrentTasks: 8, reservedRpcTasks: 2 };
271
+ ```
272
+
273
+ A decline lets Dex try another Worker without consuming an attempt. If all
274
+ Workers remain at their Step limit, a Step can wait until the dispatch wait
275
+ expires, then receive `NO_WORKER_AVAILABLE`, consume an attempt, and follow its
276
+ retry policy, as when all Workers are full. Local attempts wait the local
277
+ dispatch wait, then fall back according to their policy. Each queue still keeps
278
+ its configured idle streams; a reserve decline does not close a stream or change
279
+ registration readiness.
280
+
281
+ Each reserve decline records the Flow type through node:util debuglog under
282
+ dex:pull (enable with NODE_DEBUG=dex:pull). Export the cumulative
283
+ `pullReservedRpcDeclines` Worker value to distinguish reserve pressure from
284
+ full-capacity rejections. The count excludes full-capacity rejections and
285
+ unknown names, never resets, and remains available after shutdown. Listening
286
+ Workers return zero.
287
+
249
288
  ### Canceling Step executions
250
289
 
251
290
  A successful Step can cancel queued or active executions while continuing with
@@ -117,6 +117,12 @@ export declare enum PendingStepMethodPhase {
117
117
  PENDING_STEP_METHOD_PHASE_STARTED = 2,
118
118
  UNRECOGNIZED = -1
119
119
  }
120
+ export declare enum PullRoutingSource {
121
+ PULL_ROUTING_SOURCE_UNSPECIFIED = 0,
122
+ PULL_ROUTING_SOURCE_STICKY_QUEUE = 1,
123
+ PULL_ROUTING_SOURCE_FLOW_TYPE_QUEUE = 2,
124
+ UNRECOGNIZED = -1
125
+ }
120
126
  export declare enum ActiveStepPhase {
121
127
  ACTIVE_STEP_PHASE_UNSPECIFIED = 0,
122
128
  ACTIVE_STEP_PHASE_ACTIVE = 1,
@@ -897,6 +903,7 @@ export interface FlowContinuedStart {
897
903
  };
898
904
  attributes: KV[];
899
905
  completedSteps: StepCompletionOutput[];
906
+ stickyAppWorkerId: string;
900
907
  }
901
908
  export interface FlowContinuedStart_PendingChannelMessagesEntry {
902
909
  key: string;
@@ -908,6 +915,7 @@ export interface FlowClosedHistoryEvent {
908
915
  errorType: FlowErrorType;
909
916
  errorMessage: string;
910
917
  continuedToRunId: string;
918
+ stickyAppWorkerId: string;
911
919
  }
912
920
  /** StepMethodPendingEvent describes a regular Step activity unresolved at flow closure. */
913
921
  export interface StepMethodPendingEvent {
@@ -919,6 +927,7 @@ export interface StepMethodFailure {
919
927
  backendError: string;
920
928
  details: ServiceErrorResponse | undefined;
921
929
  attempt: number;
930
+ pullRouting: PullRouting | undefined;
922
931
  }
923
932
  export interface StepMethodOptions {
924
933
  timeoutSeconds: number;
@@ -932,6 +941,11 @@ export interface StepMethodEventInput {
932
941
  attributes: KV[];
933
942
  stepExecutionLocals: KV[];
934
943
  }
944
+ export interface PullRouting {
945
+ stickyAppWorkerId: string;
946
+ servedByAppWorkerId: string;
947
+ source: PullRoutingSource;
948
+ }
935
949
  export interface StepMethodEventContext {
936
950
  stepExecutionId: string;
937
951
  fromStepExecutionId: string;
@@ -942,6 +956,7 @@ export interface StepMethodEventContext {
942
956
  duration: Duration | undefined;
943
957
  methodOptions: StepMethodOptions | undefined;
944
958
  lastFailureInfo: StepMethodFailure | undefined;
959
+ pullRouting: PullRouting | undefined;
945
960
  }
946
961
  export interface StepWaitForCompletedOutput {
947
962
  waitForCondition: WaitingCondition | undefined;
@@ -996,6 +1011,7 @@ export interface RpcExecutionCompletedEvent {
996
1011
  publishToChannel: ChannelMessage[];
997
1012
  isSetAttributeApi: boolean;
998
1013
  deleteFromChannel: ChannelMessageDeletion[];
1014
+ servedByAppWorkerId: string;
999
1015
  }
1000
1016
  export interface ChannelExternalPublishEvent {
1001
1017
  messages: ChannelMessage[];
@@ -1024,6 +1040,8 @@ export interface ActiveStepExecutionState {
1024
1040
  stepExecutionLocals: KV[];
1025
1041
  timers: TimerInfo[];
1026
1042
  lastFailureInfo: StepMethodFailure | undefined;
1043
+ waitForPullRouting: PullRouting | undefined;
1044
+ executePullRouting: PullRouting | undefined;
1027
1045
  }
1028
1046
  export interface GetFlowStateRequest {
1029
1047
  flowId: string;
@@ -1038,6 +1056,7 @@ export interface GetFlowStateResponse {
1038
1056
  [key: string]: ChannelValues;
1039
1057
  };
1040
1058
  completedSteps: StepCompletionOutput[];
1059
+ stickyAppWorkerId: string;
1041
1060
  }
1042
1061
  export interface GetFlowStateResponse_PendingChannelMessagesEntry {
1043
1062
  key: string;
@@ -1182,6 +1201,7 @@ export interface InternalActivityError {
1182
1201
  serverDetail: string;
1183
1202
  workerGrpcStatus: number;
1184
1203
  workerError: InternalWorkerError | undefined;
1204
+ pullRouting: PullRouting | undefined;
1185
1205
  }
1186
1206
  export interface InternalWorkerError {
1187
1207
  detail: string;
@@ -1468,6 +1488,7 @@ export interface StepExecutionResumeInfo {
1468
1488
  completedConditions: StepExecutionCompletedConditions | undefined;
1469
1489
  waitingCondition: WaitingConditionState | undefined;
1470
1490
  stepExeLocals: KV[];
1491
+ waitForPullRouting: PullRouting | undefined;
1471
1492
  }
1472
1493
  export interface StepExecutionCounterInfo {
1473
1494
  stepTypeStartedCount: {
@@ -1557,6 +1578,7 @@ export interface InvokeWaitForMethodActivityOutput {
1557
1578
  response: InvokeWaitForMethodResponse | undefined;
1558
1579
  /** Identifies the Worker that completed this pull task for sticky routing. */
1559
1580
  servedByAppWorkerId: string;
1581
+ pullRouting: PullRouting | undefined;
1560
1582
  }
1561
1583
  export interface InvokeExecuteMethodActivityInput {
1562
1584
  workerTarget: WorkerTarget | undefined;
@@ -1578,11 +1600,13 @@ export interface InternalLocalStepActivityFailure {
1578
1600
  methodOptions: StepMethodOptions | undefined;
1579
1601
  attempt: number;
1580
1602
  activityError: InternalActivityError | undefined;
1603
+ pullRouting: PullRouting | undefined;
1581
1604
  }
1582
1605
  export interface InvokeExecuteMethodActivityOutput {
1583
1606
  response: InvokeExecuteMethodResponse | undefined;
1584
1607
  /** Identifies the Worker that completed this pull task for sticky routing. */
1585
1608
  servedByAppWorkerId: string;
1609
+ pullRouting: PullRouting | undefined;
1586
1610
  }
1587
1611
  export interface DumpFlowForContinueAsNewActivityInput {
1588
1612
  request: ContinueAsNewDumpRequest | undefined;
@@ -1648,6 +1672,7 @@ export interface ExecuteRpcSignalRequest {
1648
1672
  deleteFromChannel: ChannelMessageDeletion[];
1649
1673
  isDeleteChannelMessageApi: boolean;
1650
1674
  actionPermissionMappings: ActionPermissionMappings | undefined;
1675
+ servedByAppWorkerId: string;
1651
1676
  }
1652
1677
  export interface SkipTimerSignalRequest {
1653
1678
  stepExecutionId: string;
@@ -1814,6 +1839,7 @@ export declare const StepMethodPendingEvent: MessageFns<StepMethodPendingEvent>;
1814
1839
  export declare const StepMethodFailure: MessageFns<StepMethodFailure>;
1815
1840
  export declare const StepMethodOptions: MessageFns<StepMethodOptions>;
1816
1841
  export declare const StepMethodEventInput: MessageFns<StepMethodEventInput>;
1842
+ export declare const PullRouting: MessageFns<PullRouting>;
1817
1843
  export declare const StepMethodEventContext: MessageFns<StepMethodEventContext>;
1818
1844
  export declare const StepWaitForCompletedOutput: MessageFns<StepWaitForCompletedOutput>;
1819
1845
  export declare const StepExecuteCompletedOutput: MessageFns<StepExecuteCompletedOutput>;