@hatchet-dev/typescript-sdk 1.36.0 → 1.37.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.
@@ -1,4 +1,4 @@
1
- import { APIErrors, APIMeta, AcceptInviteRequest, BulkCreateEventRequest, CancelEventRequest, CreateAPITokenRequest, CreateAPITokenResponse, CreateCronWorkflowTriggerRequest, CreateEventRequest, CreateSNSIntegrationRequest, CreateTenantAlertEmailGroupRequest, CreateTenantInviteRequest, CreateTenantRequest, CronWorkflows, CronWorkflowsList, CronWorkflowsOrderByField, Event, EventData, EventKey, EventKeyList, EventList, EventOrderByDirection, EventOrderByField, EventSearch, Events, FeatureFlagEvaluationResult, FeatureFlagId, ListAPIMetaIntegration, ListAPITokensResponse, ListSNSIntegrations, ListSlackWebhooks, OtelSpanList, RateLimitList, RateLimitOrderByDirection, RateLimitOrderByField, RejectInviteRequest, ReplayEventRequest, ReplayWorkflowRunsRequest, ReplayWorkflowRunsResponse, RerunStepRunRequest, SNSIntegration, ScheduleWorkflowRunRequest, ScheduledRunStatus, ScheduledWorkflows, ScheduledWorkflowsBulkDeleteRequest, ScheduledWorkflowsBulkDeleteResponse, ScheduledWorkflowsBulkUpdateRequest, ScheduledWorkflowsBulkUpdateResponse, ScheduledWorkflowsList, ScheduledWorkflowsOrderByField, StepRun, StepRunArchiveList, StepRunEventList, TaskStats, Tenant, TenantAlertEmailGroup, TenantAlertEmailGroupList, TenantAlertingSettings, TenantInvite, TenantInviteList, TenantMember, TenantMemberList, TenantQueueMetrics, TenantResourcePolicy, TenantStepRunQueueMetrics, TriggerRunResult, TriggerWorkflowRunRequest, UpdateCronWorkflowTriggerRequest, UpdateScheduledWorkflowRunRequest, UpdateTenantAlertEmailGroupRequest, UpdateTenantInviteRequest, UpdateTenantMemberRequest, UpdateTenantRequest, UpdateWorkerRequest, User, UserChangePasswordRequest, UserLoginRequest, UserRegisterRequest, UserTenantMembershipsList, V1AdditionalMetadataOperator, V1BranchDurableTaskRequest, V1BranchDurableTaskResponse, V1CELDebugRequest, V1CELDebugResponse, V1CancelTaskRequest, V1CancelledTasks, V1CreateFilterRequest, V1CreateWebhookRequest, V1DagChildren, V1DurableEventLogList, V1Event, V1EventList, V1Filter, V1FilterList, V1LogLineLevel, V1LogLineList, V1LogLineOrderByDirection, V1LogsPointMetrics, V1ReplayTaskRequest, V1ReplayedTasks, V1RestoreTaskResponse, V1RunningFilter, V1StreamPayloadRef, V1TaskEventList, V1TaskPointMetrics, V1TaskRunMetrics, V1TaskStatus, V1TaskSummary, V1TaskSummaryList, V1TaskTimingList, V1TriggerWorkflowRunRequest, V1UpdateFilterRequest, V1UpdateWebhookRequest, V1Webhook, V1WebhookList, V1WebhookResponse, V1WebhookSourceName, V1WorkflowRunDetails, V1WorkflowRunDisplayNameList, V1WorkflowRunExternalIdList, WebhookWorkerCreateRequest, WebhookWorkerCreated, WebhookWorkerListResponse, WebhookWorkerRequestListResponse, Worker, WorkerList, WorkerStatus, Workflow, WorkflowID, WorkflowKindList, WorkflowList, WorkflowMetrics, WorkflowRun, WorkflowRunList, WorkflowRunOrderByDirection, WorkflowRunOrderByField, WorkflowRunShape, WorkflowRunStatus, WorkflowRunStatusList, WorkflowRunsCancelRequest, WorkflowRunsMetrics, WorkflowUpdateRequest, WorkflowVersion, WorkflowWorkersCount } from './data-contracts';
1
+ import { APIErrors, APIMeta, AcceptInviteRequest, BulkCreateEventRequest, CancelEventRequest, CreateAPITokenRequest, CreateAPITokenResponse, CreateCronWorkflowTriggerRequest, CreateEventRequest, CreateSNSIntegrationRequest, CreateTenantAlertEmailGroupRequest, CreateTenantInviteRequest, CreateTenantRequest, CronWorkflows, CronWorkflowsList, CronWorkflowsOrderByField, Event, EventData, EventKey, EventKeyList, EventList, EventOrderByDirection, EventOrderByField, EventSearch, Events, FeatureFlagEvaluationResult, FeatureFlagId, ListAPIMetaIntegration, ListAPITokensResponse, ListSNSIntegrations, ListSlackWebhooks, OtelSpanList, RateLimitList, RateLimitOrderByDirection, RateLimitOrderByField, RejectInviteRequest, ReplayEventRequest, ReplayWorkflowRunsRequest, ReplayWorkflowRunsResponse, RerunStepRunRequest, SNSIntegration, ScheduleWorkflowRunRequest, ScheduledRunStatus, ScheduledWorkflows, ScheduledWorkflowsBulkDeleteRequest, ScheduledWorkflowsBulkDeleteResponse, ScheduledWorkflowsBulkUpdateRequest, ScheduledWorkflowsBulkUpdateResponse, ScheduledWorkflowsList, ScheduledWorkflowsOrderByField, StepRun, StepRunArchiveList, StepRunEventList, TaskStats, Tenant, TenantAlertEmailGroup, TenantAlertEmailGroupList, TenantAlertingSettings, TenantInvite, TenantInviteList, TenantMember, TenantMemberList, TenantQueueMetrics, TenantResourcePolicy, TenantStepRunQueueMetrics, TriggerRunResult, TriggerWorkflowRunRequest, UpdateCronWorkflowTriggerRequest, UpdateScheduledWorkflowRunRequest, UpdateTenantAlertEmailGroupRequest, UpdateTenantInviteRequest, UpdateTenantMemberRequest, UpdateTenantRequest, UpdateWorkerRequest, User, UserChangePasswordRequest, UserLoginRequest, UserRegisterRequest, UserTenantMembershipsList, V1AdditionalMetadataOperator, V1BranchDurableTaskRequest, V1BranchDurableTaskResponse, V1CELDebugRequest, V1CELDebugResponse, V1CancelTaskRequest, V1CancelledTasks, V1CreateFilterRequest, V1CreateWebhookRequest, V1DagChildren, V1DurableEventLogList, V1Event, V1EventList, V1Filter, V1FilterList, V1LogLineLevel, V1LogLineList, V1LogLineOrderByDirection, V1LogsPointMetrics, V1ReplayTaskRequest, V1ReplayedTasks, V1RestoreTaskResponse, V1RunningFilter, V1StreamPayloadRef, V1TaskEventList, V1TaskPointMetrics, V1TaskRunMetrics, V1TaskStatus, V1TaskSummary, V1TaskSummaryList, V1TaskTimingList, V1TriggerWorkflowRunRequest, V1UpdateFilterRequest, V1UpdateWebhookRequest, V1Webhook, V1WebhookList, V1WebhookResponse, V1WebhookSourceName, V1WorkflowRunCount, V1WorkflowRunDetails, V1WorkflowRunDisplayNameList, V1WorkflowRunExternalIdList, WebhookWorkerCreateRequest, WebhookWorkerCreated, WebhookWorkerListResponse, WebhookWorkerRequestListResponse, Worker, WorkerList, WorkerStatus, Workflow, WorkflowID, WorkflowKindList, WorkflowList, WorkflowMetrics, WorkflowRun, WorkflowRunList, WorkflowRunOrderByDirection, WorkflowRunOrderByField, WorkflowRunShape, WorkflowRunStatus, WorkflowRunStatusList, WorkflowRunsCancelRequest, WorkflowRunsMetrics, WorkflowUpdateRequest, WorkflowVersion, WorkflowWorkersCount } from './data-contracts';
2
2
  import { HttpClient, RequestParams } from './http-client';
3
3
  export declare class Api<SecurityDataType = unknown> extends HttpClient<SecurityDataType> {
4
4
  /**
@@ -257,7 +257,65 @@ export declare class Api<SecurityDataType = unknown> extends HttpClient<Security
257
257
  running_filter?: V1RunningFilter;
258
258
  /** The idempotency key(s) to filter for */
259
259
  idempotency_keys?: string[];
260
+ /** A flag for whether or not to count the matching runs in order to populate `pagination.num_pages`. Defaults to `true` if unset. When `false`, `pagination.num_pages` is `0`, and the count can be fetched separately from the count endpoint. */
261
+ include_num_pages?: boolean;
260
262
  }, params?: RequestParams) => Promise<import("axios").AxiosResponse<V1TaskSummaryList, any, {}>>;
263
+ /**
264
+ * @description Counts the workflow runs for a tenant matching the provided filters. The count is capped, so it is a lower bound when it reaches the cap.
265
+ *
266
+ * @tags Workflow Runs
267
+ * @name V1WorkflowRunCountGet
268
+ * @summary Count workflow runs
269
+ * @request GET:/api/v1/stable/tenants/{tenant}/workflow-runs/count
270
+ * @secure
271
+ */
272
+ v1WorkflowRunCountGet: (tenant: string, query: {
273
+ /** A list of statuses to filter by */
274
+ statuses?: V1TaskStatus[];
275
+ /**
276
+ * The earliest date to filter by
277
+ * @format date-time
278
+ */
279
+ since: string;
280
+ /**
281
+ * The latest date to filter by
282
+ * @format date-time
283
+ */
284
+ until?: string;
285
+ /** Additional metadata k-v pairs to filter by */
286
+ additional_metadata?: string[];
287
+ /** How to combine multiple additional_metadata pairs. OR matches runs containing any pair, AND matches runs containing all pairs. Defaults to OR. */
288
+ additional_metadata_operator?: V1AdditionalMetadataOperator;
289
+ /** The workflow ids to find runs for */
290
+ workflow_ids?: string[];
291
+ /**
292
+ * The worker id to filter by
293
+ * @format uuid
294
+ * @minLength 36
295
+ * @maxLength 36
296
+ */
297
+ worker_id?: string;
298
+ /** Whether to include DAGs or only to include tasks */
299
+ only_tasks: boolean;
300
+ /**
301
+ * The parent task external id to filter by
302
+ * @format uuid
303
+ * @minLength 36
304
+ * @maxLength 36
305
+ */
306
+ parent_task_external_id?: string;
307
+ /**
308
+ * The external id of the event that triggered the workflow run
309
+ * @format uuid
310
+ * @minLength 36
311
+ * @maxLength 36
312
+ */
313
+ triggering_event_external_id?: string;
314
+ /** Filter within the RUNNING status bucket. ALL returns both on-worker and evicted tasks, ON_WORKER returns only tasks running on a worker, EVICTED returns only evicted tasks. Defaults to ALL. */
315
+ running_filter?: V1RunningFilter;
316
+ /** The idempotency key(s) to filter for */
317
+ idempotency_keys?: string[];
318
+ }, params?: RequestParams) => Promise<import("axios").AxiosResponse<V1WorkflowRunCount, any, {}>>;
261
319
  /**
262
320
  * @description Lists displayable names of workflow runs for a tenant
263
321
  *
@@ -116,6 +116,16 @@ class Api extends http_client_1.HttpClient {
116
116
  * @secure
117
117
  */
118
118
  this.v1WorkflowRunList = (tenant, query, params = {}) => this.request(Object.assign({ path: `/api/v1/stable/tenants/${tenant}/workflow-runs`, method: 'GET', query: query, secure: true, format: 'json' }, params));
119
+ /**
120
+ * @description Counts the workflow runs for a tenant matching the provided filters. The count is capped, so it is a lower bound when it reaches the cap.
121
+ *
122
+ * @tags Workflow Runs
123
+ * @name V1WorkflowRunCountGet
124
+ * @summary Count workflow runs
125
+ * @request GET:/api/v1/stable/tenants/{tenant}/workflow-runs/count
126
+ * @secure
127
+ */
128
+ this.v1WorkflowRunCountGet = (tenant, query, params = {}) => this.request(Object.assign({ path: `/api/v1/stable/tenants/${tenant}/workflow-runs/count`, method: 'GET', query: query, secure: true, format: 'json' }, params));
119
129
  /**
120
130
  * @description Lists displayable names of workflow runs for a tenant
121
131
  *
@@ -574,6 +574,13 @@ export interface V1TaskSummaryList {
574
574
  /** The list of tasks */
575
575
  rows: V1TaskSummary[];
576
576
  }
577
+ export interface V1WorkflowRunCount {
578
+ /**
579
+ * The number of workflow runs matching the filters
580
+ * @format int64
581
+ */
582
+ count: number;
583
+ }
577
584
  export interface V1WorkflowRunDisplayName {
578
585
  metadata: APIResourceMeta;
579
586
  displayName: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hatchet-dev/typescript-sdk",
3
- "version": "1.36.0",
3
+ "version": "1.37.0",
4
4
  "engines": {
5
5
  "node": ">=20"
6
6
  },
@@ -252,6 +252,8 @@ export interface StepActionEvent {
252
252
  retryCount?: number | undefined;
253
253
  /** a flag indicating if the task should _not_ be retried */
254
254
  shouldNotRetry?: boolean | undefined;
255
+ /** the delay in milliseconds before the next attempt (FAILED only) */
256
+ retryAfterMs?: number | undefined;
255
257
  }
256
258
  export interface BatchActionEventItem {
257
259
  /** the task external run id */
@@ -262,6 +264,8 @@ export interface BatchActionEventItem {
262
264
  retryCount?: number | undefined;
263
265
  /** a flag indicating if the task should _not_ be retried (FAILED only) */
264
266
  shouldNotRetry?: boolean | undefined;
267
+ /** the delay in milliseconds before the next attempt (FAILED only) */
268
+ retryAfterMs?: number | undefined;
265
269
  }
266
270
  export interface BatchActionEvent {
267
271
  /** the id of the worker */
@@ -2322,6 +2322,7 @@ function createBaseStepActionEvent() {
2322
2322
  eventPayload: '',
2323
2323
  retryCount: undefined,
2324
2324
  shouldNotRetry: undefined,
2325
+ retryAfterMs: undefined,
2325
2326
  };
2326
2327
  }
2327
2328
  exports.StepActionEvent = {
@@ -2359,6 +2360,9 @@ exports.StepActionEvent = {
2359
2360
  if (message.shouldNotRetry !== undefined) {
2360
2361
  writer.uint32(88).bool(message.shouldNotRetry);
2361
2362
  }
2363
+ if (message.retryAfterMs !== undefined) {
2364
+ writer.uint32(96).int64(message.retryAfterMs);
2365
+ }
2362
2366
  return writer;
2363
2367
  },
2364
2368
  decode(input, length) {
@@ -2445,6 +2449,13 @@ exports.StepActionEvent = {
2445
2449
  message.shouldNotRetry = reader.bool();
2446
2450
  continue;
2447
2451
  }
2452
+ case 12: {
2453
+ if (tag !== 96) {
2454
+ break;
2455
+ }
2456
+ message.retryAfterMs = longToNumber(reader.int64());
2457
+ continue;
2458
+ }
2448
2459
  }
2449
2460
  if ((tag & 7) === 4 || tag === 0) {
2450
2461
  break;
@@ -2510,6 +2521,11 @@ exports.StepActionEvent = {
2510
2521
  : isSet(object.should_not_retry)
2511
2522
  ? globalThis.Boolean(object.should_not_retry)
2512
2523
  : undefined,
2524
+ retryAfterMs: isSet(object.retryAfterMs)
2525
+ ? globalThis.Number(object.retryAfterMs)
2526
+ : isSet(object.retry_after_ms)
2527
+ ? globalThis.Number(object.retry_after_ms)
2528
+ : undefined,
2513
2529
  };
2514
2530
  },
2515
2531
  toJSON(message) {
@@ -2547,13 +2563,16 @@ exports.StepActionEvent = {
2547
2563
  if (message.shouldNotRetry !== undefined) {
2548
2564
  obj.shouldNotRetry = message.shouldNotRetry;
2549
2565
  }
2566
+ if (message.retryAfterMs !== undefined) {
2567
+ obj.retryAfterMs = Math.round(message.retryAfterMs);
2568
+ }
2550
2569
  return obj;
2551
2570
  },
2552
2571
  create(base) {
2553
2572
  return exports.StepActionEvent.fromPartial(base !== null && base !== void 0 ? base : {});
2554
2573
  },
2555
2574
  fromPartial(object) {
2556
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
2575
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
2557
2576
  const message = createBaseStepActionEvent();
2558
2577
  message.workerId = (_a = object.workerId) !== null && _a !== void 0 ? _a : '';
2559
2578
  message.jobId = (_b = object.jobId) !== null && _b !== void 0 ? _b : '';
@@ -2566,6 +2585,7 @@ exports.StepActionEvent = {
2566
2585
  message.eventPayload = (_j = object.eventPayload) !== null && _j !== void 0 ? _j : '';
2567
2586
  message.retryCount = (_k = object.retryCount) !== null && _k !== void 0 ? _k : undefined;
2568
2587
  message.shouldNotRetry = (_l = object.shouldNotRetry) !== null && _l !== void 0 ? _l : undefined;
2588
+ message.retryAfterMs = (_m = object.retryAfterMs) !== null && _m !== void 0 ? _m : undefined;
2569
2589
  return message;
2570
2590
  },
2571
2591
  };
@@ -2575,6 +2595,7 @@ function createBaseBatchActionEventItem() {
2575
2595
  eventPayload: '',
2576
2596
  retryCount: undefined,
2577
2597
  shouldNotRetry: undefined,
2598
+ retryAfterMs: undefined,
2578
2599
  };
2579
2600
  }
2580
2601
  exports.BatchActionEventItem = {
@@ -2591,6 +2612,9 @@ exports.BatchActionEventItem = {
2591
2612
  if (message.shouldNotRetry !== undefined) {
2592
2613
  writer.uint32(32).bool(message.shouldNotRetry);
2593
2614
  }
2615
+ if (message.retryAfterMs !== undefined) {
2616
+ writer.uint32(40).int64(message.retryAfterMs);
2617
+ }
2594
2618
  return writer;
2595
2619
  },
2596
2620
  decode(input, length) {
@@ -2628,6 +2652,13 @@ exports.BatchActionEventItem = {
2628
2652
  message.shouldNotRetry = reader.bool();
2629
2653
  continue;
2630
2654
  }
2655
+ case 5: {
2656
+ if (tag !== 40) {
2657
+ break;
2658
+ }
2659
+ message.retryAfterMs = longToNumber(reader.int64());
2660
+ continue;
2661
+ }
2631
2662
  }
2632
2663
  if ((tag & 7) === 4 || tag === 0) {
2633
2664
  break;
@@ -2658,6 +2689,11 @@ exports.BatchActionEventItem = {
2658
2689
  : isSet(object.should_not_retry)
2659
2690
  ? globalThis.Boolean(object.should_not_retry)
2660
2691
  : undefined,
2692
+ retryAfterMs: isSet(object.retryAfterMs)
2693
+ ? globalThis.Number(object.retryAfterMs)
2694
+ : isSet(object.retry_after_ms)
2695
+ ? globalThis.Number(object.retry_after_ms)
2696
+ : undefined,
2661
2697
  };
2662
2698
  },
2663
2699
  toJSON(message) {
@@ -2674,18 +2710,22 @@ exports.BatchActionEventItem = {
2674
2710
  if (message.shouldNotRetry !== undefined) {
2675
2711
  obj.shouldNotRetry = message.shouldNotRetry;
2676
2712
  }
2713
+ if (message.retryAfterMs !== undefined) {
2714
+ obj.retryAfterMs = Math.round(message.retryAfterMs);
2715
+ }
2677
2716
  return obj;
2678
2717
  },
2679
2718
  create(base) {
2680
2719
  return exports.BatchActionEventItem.fromPartial(base !== null && base !== void 0 ? base : {});
2681
2720
  },
2682
2721
  fromPartial(object) {
2683
- var _a, _b, _c, _d;
2722
+ var _a, _b, _c, _d, _e;
2684
2723
  const message = createBaseBatchActionEventItem();
2685
2724
  message.taskRunExternalId = (_a = object.taskRunExternalId) !== null && _a !== void 0 ? _a : '';
2686
2725
  message.eventPayload = (_b = object.eventPayload) !== null && _b !== void 0 ? _b : '';
2687
2726
  message.retryCount = (_c = object.retryCount) !== null && _c !== void 0 ? _c : undefined;
2688
2727
  message.shouldNotRetry = (_d = object.shouldNotRetry) !== null && _d !== void 0 ? _d : undefined;
2728
+ message.retryAfterMs = (_e = object.retryAfterMs) !== null && _e !== void 0 ? _e : undefined;
2689
2729
  return message;
2690
2730
  },
2691
2731
  };
@@ -568,6 +568,12 @@ export type StepActionEvent = Message<"StepActionEvent"> & {
568
568
  * @generated from field: optional bool should_not_retry = 11;
569
569
  */
570
570
  shouldNotRetry?: boolean | undefined;
571
+ /**
572
+ * the delay in milliseconds before the next attempt (FAILED only)
573
+ *
574
+ * @generated from field: optional int64 retry_after_ms = 12;
575
+ */
576
+ retryAfterMs?: bigint | undefined;
571
577
  };
572
578
  /**
573
579
  * Describes the message StepActionEvent.
@@ -602,6 +608,12 @@ export type BatchActionEventItem = Message<"BatchActionEventItem"> & {
602
608
  * @generated from field: optional bool should_not_retry = 4;
603
609
  */
604
610
  shouldNotRetry?: boolean | undefined;
611
+ /**
612
+ * the delay in milliseconds before the next attempt (FAILED only)
613
+ *
614
+ * @generated from field: optional int64 retry_after_ms = 5;
615
+ */
616
+ retryAfterMs?: bigint | undefined;
605
617
  };
606
618
  /**
607
619
  * Describes the message BatchActionEventItem.
@@ -9,7 +9,7 @@ const wkt_1 = require("@bufbuild/protobuf/wkt");
9
9
  /**
10
10
  * Describes the file dispatcher/dispatcher.proto.
11
11
  */
12
- exports.file_dispatcher_dispatcher = (0, codegenv2_1.fileDesc)("ChtkaXNwYXRjaGVyL2Rpc3BhdGNoZXIucHJvdG8iWgoMV29ya2VyTGFiZWxzEhYKCXN0cl92YWx1ZRgBIAEoCUgAiAEBEhYKCWludF92YWx1ZRgCIAEoBUgBiAEBQgwKCl9zdHJfdmFsdWVCDAoKX2ludF92YWx1ZSLMAQoLUnVudGltZUluZm8SGAoLc2RrX3ZlcnNpb24YASABKAlIAIgBARIcCghsYW5ndWFnZRgCIAEoDjIFLlNES1NIAYgBARIdChBsYW5ndWFnZV92ZXJzaW9uGAMgASgJSAKIAQESDwoCb3MYBCABKAlIA4gBARISCgVleHRyYRgFIAEoCUgEiAEBQg4KDF9zZGtfdmVyc2lvbkILCglfbGFuZ3VhZ2VCEwoRX2xhbmd1YWdlX3ZlcnNpb25CBQoDX29zQggKBl9leHRyYSKxAwoVV29ya2VyUmVnaXN0ZXJSZXF1ZXN0EhMKC3dvcmtlcl9uYW1lGAEgASgJEg8KB2FjdGlvbnMYAiADKAkSEAoIc2VydmljZXMYAyADKAkSEgoFc2xvdHMYBCABKAVIAIgBARIyCgZsYWJlbHMYBSADKAsyIi5Xb3JrZXJSZWdpc3RlclJlcXVlc3QuTGFiZWxzRW50cnkSFwoKd2ViaG9va19pZBgGIAEoCUgBiAEBEicKDHJ1bnRpbWVfaW5mbxgHIAEoCzIMLlJ1bnRpbWVJbmZvSAKIAQESOwoLc2xvdF9jb25maWcYCSADKAsyJi5Xb3JrZXJSZWdpc3RlclJlcXVlc3QuU2xvdENvbmZpZ0VudHJ5GjwKC0xhYmVsc0VudHJ5EgsKA2tleRgBIAEoCRIcCgV2YWx1ZRgCIAEoCzINLldvcmtlckxhYmVsczoCOAEaMQoPU2xvdENvbmZpZ0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoBToCOAFCCAoGX3Nsb3RzQg0KC193ZWJob29rX2lkQg8KDV9ydW50aW1lX2luZm8iUwoWV29ya2VyUmVnaXN0ZXJSZXNwb25zZRIRCgl0ZW5hbnRfaWQYASABKAkSEQoJd29ya2VyX2lkGAIgASgJEhMKC3dvcmtlcl9uYW1lGAMgASgJIqQBChlVcHNlcnRXb3JrZXJMYWJlbHNSZXF1ZXN0EhEKCXdvcmtlcl9pZBgBIAEoCRI2CgZsYWJlbHMYAiADKAsyJi5VcHNlcnRXb3JrZXJMYWJlbHNSZXF1ZXN0LkxhYmVsc0VudHJ5GjwKC0xhYmVsc0VudHJ5EgsKA2tleRgBIAEoCRIcCgV2YWx1ZRgCIAEoCzINLldvcmtlckxhYmVsczoCOAEiQgoaVXBzZXJ0V29ya2VyTGFiZWxzUmVzcG9uc2USEQoJdGVuYW50X2lkGAEgASgJEhEKCXdvcmtlcl9pZBgCIAEoCSKcCQoOQXNzaWduZWRBY3Rpb24SEQoJdGVuYW50X2lkGAEgASgJEhcKD3dvcmtmbG93X3J1bl9pZBgCIAEoCRIcChRnZXRfZ3JvdXBfa2V5X3J1bl9pZBgDIAEoCRIOCgZqb2JfaWQYBCABKAkSEAoIam9iX25hbWUYBSABKAkSEgoKam9iX3J1bl9pZBgGIAEoCRIPCgd0YXNrX2lkGAcgASgJEhwKFHRhc2tfcnVuX2V4dGVybmFsX2lkGAggASgJEhEKCWFjdGlvbl9pZBgJIAEoCRIgCgthY3Rpb25fdHlwZRgKIAEoDjILLkFjdGlvblR5cGUSFgoOYWN0aW9uX3BheWxvYWQYCyABKAkSEQoJdGFza19uYW1lGAwgASgJEhMKC3JldHJ5X2NvdW50GA0gASgFEiAKE2FkZGl0aW9uYWxfbWV0YWRhdGEYDiABKAlIAIgBARIhChRjaGlsZF93b3JrZmxvd19pbmRleBgPIAEoBUgBiAEBEh8KEmNoaWxkX3dvcmtmbG93X2tleRgQIAEoCUgCiAEBEiMKFnBhcmVudF93b3JrZmxvd19ydW5faWQYESABKAlIA4gBARIQCghwcmlvcml0eRgSIAEoBRIYCgt3b3JrZmxvd19pZBgTIAEoCUgEiAEBEiAKE3dvcmtmbG93X3ZlcnNpb25faWQYFCABKAlIBYgBARIqCh1kdXJhYmxlX3Rhc2tfaW52b2NhdGlvbl9jb3VudBgVIAEoBUgGiAEBEikKHHRyaWdnZXJpbmdfZXZlbnRfZXh0ZXJuYWxfaWQYFiABKAlIB4gBARIhChR0cmlnZ2VyaW5nX2V2ZW50X2tleRgXIAEoCUgIiAEBEhQKB2JhdGNoSWQYGCABKAlICYgBARIWCgliYXRjaFNpemUYGSABKAVICogBARIXCgpiYXRjaEluZGV4GBogASgFSAuIAQESMgoRYmF0Y2hTdGFydFBheWxvYWQYGyABKAsyEi5CYXRjaFN0YXJ0UGF5bG9hZEgMiAEBEhUKCGJhdGNoS2V5GBwgASgJSA2IAQESOQoQdGFza19pbnNlcnRlZF9hdBgdIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBIDogBAUIWChRfYWRkaXRpb25hbF9tZXRhZGF0YUIXChVfY2hpbGRfd29ya2Zsb3dfaW5kZXhCFQoTX2NoaWxkX3dvcmtmbG93X2tleUIZChdfcGFyZW50X3dvcmtmbG93X3J1bl9pZEIOCgxfd29ya2Zsb3dfaWRCFgoUX3dvcmtmbG93X3ZlcnNpb25faWRCIAoeX2R1cmFibGVfdGFza19pbnZvY2F0aW9uX2NvdW50Qh8KHV90cmlnZ2VyaW5nX2V2ZW50X2V4dGVybmFsX2lkQhcKFV90cmlnZ2VyaW5nX2V2ZW50X2tleUIKCghfYmF0Y2hJZEIMCgpfYmF0Y2hTaXplQg0KC19iYXRjaEluZGV4QhQKEl9iYXRjaFN0YXJ0UGF5bG9hZEILCglfYmF0Y2hLZXlCEwoRX3Rhc2tfaW5zZXJ0ZWRfYXQicQoRQmF0Y2hTdGFydFBheWxvYWQSFQoNdHJpZ2dlclJlYXNvbhgBIAEoCRIvCgt0cmlnZ2VyVGltZRgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASFAoMZXhwZWN0ZWRTaXplGAMgASgFIigKE1dvcmtlckxpc3RlblJlcXVlc3QSEQoJd29ya2VyX2lkGAEgASgJIi0KGFdvcmtlclVuc3Vic2NyaWJlUmVxdWVzdBIRCgl3b3JrZXJfaWQYASABKAkiQQoZV29ya2VyVW5zdWJzY3JpYmVSZXNwb25zZRIRCgl0ZW5hbnRfaWQYASABKAkSEQoJd29ya2VyX2lkGAIgASgJIuwBChNHcm91cEtleUFjdGlvbkV2ZW50EhEKCXdvcmtlcl9pZBgBIAEoCRIXCg93b3JrZmxvd19ydW5faWQYAiABKAkSHAoUZ2V0X2dyb3VwX2tleV9ydW5faWQYAyABKAkSEQoJYWN0aW9uX2lkGAQgASgJEjMKD2V2ZW50X3RpbWVzdGFtcBgFIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLAoKZXZlbnRfdHlwZRgGIAEoDjIYLkdyb3VwS2V5QWN0aW9uRXZlbnRUeXBlEhUKDWV2ZW50X3BheWxvYWQYByABKAki3gIKD1N0ZXBBY3Rpb25FdmVudBIRCgl3b3JrZXJfaWQYASABKAkSDgoGam9iX2lkGAIgASgJEhIKCmpvYl9ydW5faWQYAyABKAkSDwoHdGFza19pZBgEIAEoCRIcChR0YXNrX3J1bl9leHRlcm5hbF9pZBgFIAEoCRIRCglhY3Rpb25faWQYBiABKAkSMwoPZXZlbnRfdGltZXN0YW1wGAcgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIoCgpldmVudF90eXBlGAggASgOMhQuU3RlcEFjdGlvbkV2ZW50VHlwZRIVCg1ldmVudF9wYXlsb2FkGAkgASgJEhgKC3JldHJ5X2NvdW50GAogASgFSACIAQESHQoQc2hvdWxkX25vdF9yZXRyeRgLIAEoCEgBiAEBQg4KDF9yZXRyeV9jb3VudEITChFfc2hvdWxkX25vdF9yZXRyeSKpAQoUQmF0Y2hBY3Rpb25FdmVudEl0ZW0SHAoUdGFza19ydW5fZXh0ZXJuYWxfaWQYASABKAkSFQoNZXZlbnRfcGF5bG9hZBgCIAEoCRIYCgtyZXRyeV9jb3VudBgDIAEoBUgAiAEBEh0KEHNob3VsZF9ub3RfcmV0cnkYBCABKAhIAYgBAUIOCgxfcmV0cnlfY291bnRCEwoRX3Nob3VsZF9ub3RfcmV0cnki8QEKEEJhdGNoQWN0aW9uRXZlbnQSEQoJd29ya2VyX2lkGAEgASgJEg4KBmpvYl9pZBgCIAEoCRIRCglhY3Rpb25faWQYAyABKAkSFQoIYmF0Y2hfaWQYBCABKAlIAIgBARIzCg9ldmVudF90aW1lc3RhbXAYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEigKCmV2ZW50X3R5cGUYBiABKA4yFC5TdGVwQWN0aW9uRXZlbnRUeXBlEiQKBWl0ZW1zGAcgAygLMhUuQmF0Y2hBY3Rpb25FdmVudEl0ZW1CCwoJX2JhdGNoX2lkIjsKE0FjdGlvbkV2ZW50UmVzcG9uc2USEQoJdGVuYW50X2lkGAEgASgJEhEKCXdvcmtlcl9pZBgCIAEoCSLMAQogU3Vic2NyaWJlVG9Xb3JrZmxvd0V2ZW50c1JlcXVlc3QSHAoPd29ya2Zsb3dfcnVuX2lkGAEgASgJSACIAQESIAoTYWRkaXRpb25hbF9tZXRhX2tleRgCIAEoCUgBiAEBEiIKFWFkZGl0aW9uYWxfbWV0YV92YWx1ZRgDIAEoCUgCiAEBQhIKEF93b3JrZmxvd19ydW5faWRCFgoUX2FkZGl0aW9uYWxfbWV0YV9rZXlCGAoWX2FkZGl0aW9uYWxfbWV0YV92YWx1ZSI5Ch5TdWJzY3JpYmVUb1dvcmtmbG93UnVuc1JlcXVlc3QSFwoPd29ya2Zsb3dfcnVuX2lkGAEgASgJIucCCg1Xb3JrZmxvd0V2ZW50EhcKD3dvcmtmbG93X3J1bl9pZBgBIAEoCRIkCg1yZXNvdXJjZV90eXBlGAIgASgOMg0uUmVzb3VyY2VUeXBlEiYKCmV2ZW50X3R5cGUYAyABKA4yEi5SZXNvdXJjZUV2ZW50VHlwZRITCgtyZXNvdXJjZV9pZBgEIAEoCRIzCg9ldmVudF90aW1lc3RhbXAYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhUKDWV2ZW50X3BheWxvYWQYBiABKAkSDgoGaGFuZ3VwGAcgASgIEhkKDHRhc2tfcmV0cmllcxgIIAEoBUgAiAEBEhgKC3JldHJ5X2NvdW50GAkgASgFSAGIAQESGAoLZXZlbnRfaW5kZXgYCiABKANIAogBAUIPCg1fdGFza19yZXRyaWVzQg4KDF9yZXRyeV9jb3VudEIOCgxfZXZlbnRfaW5kZXgirAEKEFdvcmtmbG93UnVuRXZlbnQSFwoPd29ya2Zsb3dfcnVuX2lkGAEgASgJEikKCmV2ZW50X3R5cGUYAiABKA4yFS5Xb3JrZmxvd1J1bkV2ZW50VHlwZRIzCg9ldmVudF90aW1lc3RhbXAYAyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEh8KB3Jlc3VsdHMYBCADKAsyDi5TdGVwUnVuUmVzdWx0IpIBCg1TdGVwUnVuUmVzdWx0EhwKFHRhc2tfcnVuX2V4dGVybmFsX2lkGAEgASgJEhEKCXRhc2tfbmFtZRgCIAEoCRISCgpqb2JfcnVuX2lkGAMgASgJEhIKBWVycm9yGAQgASgJSACIAQESEwoGb3V0cHV0GAUgASgJSAGIAQFCCAoGX2Vycm9yQgkKB19vdXRwdXQiYwoNT3ZlcnJpZGVzRGF0YRIcChR0YXNrX3J1bl9leHRlcm5hbF9pZBgBIAEoCRIMCgRwYXRoGAIgASgJEg0KBXZhbHVlGAMgASgJEhcKD2NhbGxlcl9maWxlbmFtZRgEIAEoCSIXChVPdmVycmlkZXNEYXRhUmVzcG9uc2UiVwoQSGVhcnRiZWF0UmVxdWVzdBIRCgl3b3JrZXJfaWQYASABKAkSMAoMaGVhcnRiZWF0X2F0GAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCITChFIZWFydGJlYXRSZXNwb25zZSJTChVSZWZyZXNoVGltZW91dFJlcXVlc3QSHAoUdGFza19ydW5fZXh0ZXJuYWxfaWQYASABKAkSHAoUaW5jcmVtZW50X3RpbWVvdXRfYnkYAiABKAkiSAoWUmVmcmVzaFRpbWVvdXRSZXNwb25zZRIuCgp0aW1lb3V0X2F0GAEgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCIyChJSZWxlYXNlU2xvdFJlcXVlc3QSHAoUdGFza19ydW5fZXh0ZXJuYWxfaWQYASABKAkiFQoTUmVsZWFzZVNsb3RSZXNwb25zZSI5ChlSZXN0b3JlRXZpY3RlZFRhc2tSZXF1ZXN0EhwKFHRhc2tfcnVuX2V4dGVybmFsX2lkGAEgASgJIi4KGlJlc3RvcmVFdmljdGVkVGFza1Jlc3BvbnNlEhAKCHJlcXVldWVkGAEgASgIIhMKEUdldFZlcnNpb25SZXF1ZXN0IiUKEkdldFZlcnNpb25SZXNwb25zZRIPCgd2ZXJzaW9uGAEgASgJKkEKBFNES1MSCwoHVU5LTk9XThAAEgYKAkdPEAESCgoGUFlUSE9OEAISDgoKVFlQRVNDUklQVBADEggKBFJVQlkQBCpfCgpBY3Rpb25UeXBlEhIKDlNUQVJUX1NURVBfUlVOEAASEwoPQ0FOQ0VMX1NURVBfUlVOEAESFwoTU1RBUlRfR0VUX0dST1VQX0tFWRACEg8KC1NUQVJUX0JBVENIEAMqogEKF0dyb3VwS2V5QWN0aW9uRXZlbnRUeXBlEiAKHEdST1VQX0tFWV9FVkVOVF9UWVBFX1VOS05PV04QABIgChxHUk9VUF9LRVlfRVZFTlRfVFlQRV9TVEFSVEVEEAESIgoeR1JPVVBfS0VZX0VWRU5UX1RZUEVfQ09NUExFVEVEEAISHwobR1JPVVBfS0VZX0VWRU5UX1RZUEVfRkFJTEVEEAMqywEKE1N0ZXBBY3Rpb25FdmVudFR5cGUSGwoXU1RFUF9FVkVOVF9UWVBFX1VOS05PV04QABIbChdTVEVQX0VWRU5UX1RZUEVfU1RBUlRFRBABEh0KGVNURVBfRVZFTlRfVFlQRV9DT01QTEVURUQQAhIaChZTVEVQX0VWRU5UX1RZUEVfRkFJTEVEEAMSIAocU1RFUF9FVkVOVF9UWVBFX0FDS05PV0xFREdFRBAEEh0KGVNURVBfRVZFTlRfVFlQRV9DQU5DRUxMRUQQBSplCgxSZXNvdXJjZVR5cGUSGQoVUkVTT1VSQ0VfVFlQRV9VTktOT1dOEAASGgoWUkVTT1VSQ0VfVFlQRV9TVEVQX1JVThABEh4KGlJFU09VUkNFX1RZUEVfV09SS0ZMT1dfUlVOEAIq/gEKEVJlc291cmNlRXZlbnRUeXBlEh8KG1JFU09VUkNFX0VWRU5UX1RZUEVfVU5LTk9XThAAEh8KG1JFU09VUkNFX0VWRU5UX1RZUEVfU1RBUlRFRBABEiEKHVJFU09VUkNFX0VWRU5UX1RZUEVfQ09NUExFVEVEEAISHgoaUkVTT1VSQ0VfRVZFTlRfVFlQRV9GQUlMRUQQAxIhCh1SRVNPVVJDRV9FVkVOVF9UWVBFX0NBTkNFTExFRBAEEiEKHVJFU09VUkNFX0VWRU5UX1RZUEVfVElNRURfT1VUEAUSHgoaUkVTT1VSQ0VfRVZFTlRfVFlQRV9TVFJFQU0QBio8ChRXb3JrZmxvd1J1bkV2ZW50VHlwZRIkCiBXT1JLRkxPV19SVU5fRVZFTlRfVFlQRV9GSU5JU0hFRBAAMsUICgpEaXNwYXRjaGVyEj0KCFJlZ2lzdGVyEhYuV29ya2VyUmVnaXN0ZXJSZXF1ZXN0GhcuV29ya2VyUmVnaXN0ZXJSZXNwb25zZSIAEjMKBkxpc3RlbhIULldvcmtlckxpc3RlblJlcXVlc3QaDy5Bc3NpZ25lZEFjdGlvbiIAMAESNQoITGlzdGVuVjISFC5Xb3JrZXJMaXN0ZW5SZXF1ZXN0Gg8uQXNzaWduZWRBY3Rpb24iADABEjQKCUhlYXJ0YmVhdBIRLkhlYXJ0YmVhdFJlcXVlc3QaEi5IZWFydGJlYXRSZXNwb25zZSIAElIKGVN1YnNjcmliZVRvV29ya2Zsb3dFdmVudHMSIS5TdWJzY3JpYmVUb1dvcmtmbG93RXZlbnRzUmVxdWVzdBoOLldvcmtmbG93RXZlbnQiADABElMKF1N1YnNjcmliZVRvV29ya2Zsb3dSdW5zEh8uU3Vic2NyaWJlVG9Xb3JrZmxvd1J1bnNSZXF1ZXN0GhEuV29ya2Zsb3dSdW5FdmVudCIAKAEwARI/ChNTZW5kU3RlcEFjdGlvbkV2ZW50EhAuU3RlcEFjdGlvbkV2ZW50GhQuQWN0aW9uRXZlbnRSZXNwb25zZSIAEkEKFFNlbmRCYXRjaEFjdGlvbkV2ZW50EhEuQmF0Y2hBY3Rpb25FdmVudBoULkFjdGlvbkV2ZW50UmVzcG9uc2UiABJHChdTZW5kR3JvdXBLZXlBY3Rpb25FdmVudBIULkdyb3VwS2V5QWN0aW9uRXZlbnQaFC5BY3Rpb25FdmVudFJlc3BvbnNlIgASPAoQUHV0T3ZlcnJpZGVzRGF0YRIOLk92ZXJyaWRlc0RhdGEaFi5PdmVycmlkZXNEYXRhUmVzcG9uc2UiABJGCgtVbnN1YnNjcmliZRIZLldvcmtlclVuc3Vic2NyaWJlUmVxdWVzdBoaLldvcmtlclVuc3Vic2NyaWJlUmVzcG9uc2UiABJDCg5SZWZyZXNoVGltZW91dBIWLlJlZnJlc2hUaW1lb3V0UmVxdWVzdBoXLlJlZnJlc2hUaW1lb3V0UmVzcG9uc2UiABI6CgtSZWxlYXNlU2xvdBITLlJlbGVhc2VTbG90UmVxdWVzdBoULlJlbGVhc2VTbG90UmVzcG9uc2UiABJPChJSZXN0b3JlRXZpY3RlZFRhc2sSGi5SZXN0b3JlRXZpY3RlZFRhc2tSZXF1ZXN0GhsuUmVzdG9yZUV2aWN0ZWRUYXNrUmVzcG9uc2UiABJPChJVcHNlcnRXb3JrZXJMYWJlbHMSGi5VcHNlcnRXb3JrZXJMYWJlbHNSZXF1ZXN0GhsuVXBzZXJ0V29ya2VyTGFiZWxzUmVzcG9uc2UiABI3CgpHZXRWZXJzaW9uEhIuR2V0VmVyc2lvblJlcXVlc3QaEy5HZXRWZXJzaW9uUmVzcG9uc2UiAEJHWkVnaXRodWIuY29tL2hhdGNoZXQtZGV2L2hhdGNoZXQvaW50ZXJuYWwvc2VydmljZXMvZGlzcGF0Y2hlci9jb250cmFjdHNiBnByb3RvMw", [wkt_1.file_google_protobuf_timestamp]);
12
+ exports.file_dispatcher_dispatcher = (0, codegenv2_1.fileDesc)("ChtkaXNwYXRjaGVyL2Rpc3BhdGNoZXIucHJvdG8iWgoMV29ya2VyTGFiZWxzEhYKCXN0cl92YWx1ZRgBIAEoCUgAiAEBEhYKCWludF92YWx1ZRgCIAEoBUgBiAEBQgwKCl9zdHJfdmFsdWVCDAoKX2ludF92YWx1ZSLMAQoLUnVudGltZUluZm8SGAoLc2RrX3ZlcnNpb24YASABKAlIAIgBARIcCghsYW5ndWFnZRgCIAEoDjIFLlNES1NIAYgBARIdChBsYW5ndWFnZV92ZXJzaW9uGAMgASgJSAKIAQESDwoCb3MYBCABKAlIA4gBARISCgVleHRyYRgFIAEoCUgEiAEBQg4KDF9zZGtfdmVyc2lvbkILCglfbGFuZ3VhZ2VCEwoRX2xhbmd1YWdlX3ZlcnNpb25CBQoDX29zQggKBl9leHRyYSKxAwoVV29ya2VyUmVnaXN0ZXJSZXF1ZXN0EhMKC3dvcmtlcl9uYW1lGAEgASgJEg8KB2FjdGlvbnMYAiADKAkSEAoIc2VydmljZXMYAyADKAkSEgoFc2xvdHMYBCABKAVIAIgBARIyCgZsYWJlbHMYBSADKAsyIi5Xb3JrZXJSZWdpc3RlclJlcXVlc3QuTGFiZWxzRW50cnkSFwoKd2ViaG9va19pZBgGIAEoCUgBiAEBEicKDHJ1bnRpbWVfaW5mbxgHIAEoCzIMLlJ1bnRpbWVJbmZvSAKIAQESOwoLc2xvdF9jb25maWcYCSADKAsyJi5Xb3JrZXJSZWdpc3RlclJlcXVlc3QuU2xvdENvbmZpZ0VudHJ5GjwKC0xhYmVsc0VudHJ5EgsKA2tleRgBIAEoCRIcCgV2YWx1ZRgCIAEoCzINLldvcmtlckxhYmVsczoCOAEaMQoPU2xvdENvbmZpZ0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoBToCOAFCCAoGX3Nsb3RzQg0KC193ZWJob29rX2lkQg8KDV9ydW50aW1lX2luZm8iUwoWV29ya2VyUmVnaXN0ZXJSZXNwb25zZRIRCgl0ZW5hbnRfaWQYASABKAkSEQoJd29ya2VyX2lkGAIgASgJEhMKC3dvcmtlcl9uYW1lGAMgASgJIqQBChlVcHNlcnRXb3JrZXJMYWJlbHNSZXF1ZXN0EhEKCXdvcmtlcl9pZBgBIAEoCRI2CgZsYWJlbHMYAiADKAsyJi5VcHNlcnRXb3JrZXJMYWJlbHNSZXF1ZXN0LkxhYmVsc0VudHJ5GjwKC0xhYmVsc0VudHJ5EgsKA2tleRgBIAEoCRIcCgV2YWx1ZRgCIAEoCzINLldvcmtlckxhYmVsczoCOAEiQgoaVXBzZXJ0V29ya2VyTGFiZWxzUmVzcG9uc2USEQoJdGVuYW50X2lkGAEgASgJEhEKCXdvcmtlcl9pZBgCIAEoCSKcCQoOQXNzaWduZWRBY3Rpb24SEQoJdGVuYW50X2lkGAEgASgJEhcKD3dvcmtmbG93X3J1bl9pZBgCIAEoCRIcChRnZXRfZ3JvdXBfa2V5X3J1bl9pZBgDIAEoCRIOCgZqb2JfaWQYBCABKAkSEAoIam9iX25hbWUYBSABKAkSEgoKam9iX3J1bl9pZBgGIAEoCRIPCgd0YXNrX2lkGAcgASgJEhwKFHRhc2tfcnVuX2V4dGVybmFsX2lkGAggASgJEhEKCWFjdGlvbl9pZBgJIAEoCRIgCgthY3Rpb25fdHlwZRgKIAEoDjILLkFjdGlvblR5cGUSFgoOYWN0aW9uX3BheWxvYWQYCyABKAkSEQoJdGFza19uYW1lGAwgASgJEhMKC3JldHJ5X2NvdW50GA0gASgFEiAKE2FkZGl0aW9uYWxfbWV0YWRhdGEYDiABKAlIAIgBARIhChRjaGlsZF93b3JrZmxvd19pbmRleBgPIAEoBUgBiAEBEh8KEmNoaWxkX3dvcmtmbG93X2tleRgQIAEoCUgCiAEBEiMKFnBhcmVudF93b3JrZmxvd19ydW5faWQYESABKAlIA4gBARIQCghwcmlvcml0eRgSIAEoBRIYCgt3b3JrZmxvd19pZBgTIAEoCUgEiAEBEiAKE3dvcmtmbG93X3ZlcnNpb25faWQYFCABKAlIBYgBARIqCh1kdXJhYmxlX3Rhc2tfaW52b2NhdGlvbl9jb3VudBgVIAEoBUgGiAEBEikKHHRyaWdnZXJpbmdfZXZlbnRfZXh0ZXJuYWxfaWQYFiABKAlIB4gBARIhChR0cmlnZ2VyaW5nX2V2ZW50X2tleRgXIAEoCUgIiAEBEhQKB2JhdGNoSWQYGCABKAlICYgBARIWCgliYXRjaFNpemUYGSABKAVICogBARIXCgpiYXRjaEluZGV4GBogASgFSAuIAQESMgoRYmF0Y2hTdGFydFBheWxvYWQYGyABKAsyEi5CYXRjaFN0YXJ0UGF5bG9hZEgMiAEBEhUKCGJhdGNoS2V5GBwgASgJSA2IAQESOQoQdGFza19pbnNlcnRlZF9hdBgdIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBIDogBAUIWChRfYWRkaXRpb25hbF9tZXRhZGF0YUIXChVfY2hpbGRfd29ya2Zsb3dfaW5kZXhCFQoTX2NoaWxkX3dvcmtmbG93X2tleUIZChdfcGFyZW50X3dvcmtmbG93X3J1bl9pZEIOCgxfd29ya2Zsb3dfaWRCFgoUX3dvcmtmbG93X3ZlcnNpb25faWRCIAoeX2R1cmFibGVfdGFza19pbnZvY2F0aW9uX2NvdW50Qh8KHV90cmlnZ2VyaW5nX2V2ZW50X2V4dGVybmFsX2lkQhcKFV90cmlnZ2VyaW5nX2V2ZW50X2tleUIKCghfYmF0Y2hJZEIMCgpfYmF0Y2hTaXplQg0KC19iYXRjaEluZGV4QhQKEl9iYXRjaFN0YXJ0UGF5bG9hZEILCglfYmF0Y2hLZXlCEwoRX3Rhc2tfaW5zZXJ0ZWRfYXQicQoRQmF0Y2hTdGFydFBheWxvYWQSFQoNdHJpZ2dlclJlYXNvbhgBIAEoCRIvCgt0cmlnZ2VyVGltZRgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASFAoMZXhwZWN0ZWRTaXplGAMgASgFIigKE1dvcmtlckxpc3RlblJlcXVlc3QSEQoJd29ya2VyX2lkGAEgASgJIi0KGFdvcmtlclVuc3Vic2NyaWJlUmVxdWVzdBIRCgl3b3JrZXJfaWQYASABKAkiQQoZV29ya2VyVW5zdWJzY3JpYmVSZXNwb25zZRIRCgl0ZW5hbnRfaWQYASABKAkSEQoJd29ya2VyX2lkGAIgASgJIuwBChNHcm91cEtleUFjdGlvbkV2ZW50EhEKCXdvcmtlcl9pZBgBIAEoCRIXCg93b3JrZmxvd19ydW5faWQYAiABKAkSHAoUZ2V0X2dyb3VwX2tleV9ydW5faWQYAyABKAkSEQoJYWN0aW9uX2lkGAQgASgJEjMKD2V2ZW50X3RpbWVzdGFtcBgFIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLAoKZXZlbnRfdHlwZRgGIAEoDjIYLkdyb3VwS2V5QWN0aW9uRXZlbnRUeXBlEhUKDWV2ZW50X3BheWxvYWQYByABKAkijgMKD1N0ZXBBY3Rpb25FdmVudBIRCgl3b3JrZXJfaWQYASABKAkSDgoGam9iX2lkGAIgASgJEhIKCmpvYl9ydW5faWQYAyABKAkSDwoHdGFza19pZBgEIAEoCRIcChR0YXNrX3J1bl9leHRlcm5hbF9pZBgFIAEoCRIRCglhY3Rpb25faWQYBiABKAkSMwoPZXZlbnRfdGltZXN0YW1wGAcgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIoCgpldmVudF90eXBlGAggASgOMhQuU3RlcEFjdGlvbkV2ZW50VHlwZRIVCg1ldmVudF9wYXlsb2FkGAkgASgJEhgKC3JldHJ5X2NvdW50GAogASgFSACIAQESHQoQc2hvdWxkX25vdF9yZXRyeRgLIAEoCEgBiAEBEhsKDnJldHJ5X2FmdGVyX21zGAwgASgDSAKIAQFCDgoMX3JldHJ5X2NvdW50QhMKEV9zaG91bGRfbm90X3JldHJ5QhEKD19yZXRyeV9hZnRlcl9tcyLZAQoUQmF0Y2hBY3Rpb25FdmVudEl0ZW0SHAoUdGFza19ydW5fZXh0ZXJuYWxfaWQYASABKAkSFQoNZXZlbnRfcGF5bG9hZBgCIAEoCRIYCgtyZXRyeV9jb3VudBgDIAEoBUgAiAEBEh0KEHNob3VsZF9ub3RfcmV0cnkYBCABKAhIAYgBARIbCg5yZXRyeV9hZnRlcl9tcxgFIAEoA0gCiAEBQg4KDF9yZXRyeV9jb3VudEITChFfc2hvdWxkX25vdF9yZXRyeUIRCg9fcmV0cnlfYWZ0ZXJfbXMi8QEKEEJhdGNoQWN0aW9uRXZlbnQSEQoJd29ya2VyX2lkGAEgASgJEg4KBmpvYl9pZBgCIAEoCRIRCglhY3Rpb25faWQYAyABKAkSFQoIYmF0Y2hfaWQYBCABKAlIAIgBARIzCg9ldmVudF90aW1lc3RhbXAYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEigKCmV2ZW50X3R5cGUYBiABKA4yFC5TdGVwQWN0aW9uRXZlbnRUeXBlEiQKBWl0ZW1zGAcgAygLMhUuQmF0Y2hBY3Rpb25FdmVudEl0ZW1CCwoJX2JhdGNoX2lkIjsKE0FjdGlvbkV2ZW50UmVzcG9uc2USEQoJdGVuYW50X2lkGAEgASgJEhEKCXdvcmtlcl9pZBgCIAEoCSLMAQogU3Vic2NyaWJlVG9Xb3JrZmxvd0V2ZW50c1JlcXVlc3QSHAoPd29ya2Zsb3dfcnVuX2lkGAEgASgJSACIAQESIAoTYWRkaXRpb25hbF9tZXRhX2tleRgCIAEoCUgBiAEBEiIKFWFkZGl0aW9uYWxfbWV0YV92YWx1ZRgDIAEoCUgCiAEBQhIKEF93b3JrZmxvd19ydW5faWRCFgoUX2FkZGl0aW9uYWxfbWV0YV9rZXlCGAoWX2FkZGl0aW9uYWxfbWV0YV92YWx1ZSI5Ch5TdWJzY3JpYmVUb1dvcmtmbG93UnVuc1JlcXVlc3QSFwoPd29ya2Zsb3dfcnVuX2lkGAEgASgJIucCCg1Xb3JrZmxvd0V2ZW50EhcKD3dvcmtmbG93X3J1bl9pZBgBIAEoCRIkCg1yZXNvdXJjZV90eXBlGAIgASgOMg0uUmVzb3VyY2VUeXBlEiYKCmV2ZW50X3R5cGUYAyABKA4yEi5SZXNvdXJjZUV2ZW50VHlwZRITCgtyZXNvdXJjZV9pZBgEIAEoCRIzCg9ldmVudF90aW1lc3RhbXAYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhUKDWV2ZW50X3BheWxvYWQYBiABKAkSDgoGaGFuZ3VwGAcgASgIEhkKDHRhc2tfcmV0cmllcxgIIAEoBUgAiAEBEhgKC3JldHJ5X2NvdW50GAkgASgFSAGIAQESGAoLZXZlbnRfaW5kZXgYCiABKANIAogBAUIPCg1fdGFza19yZXRyaWVzQg4KDF9yZXRyeV9jb3VudEIOCgxfZXZlbnRfaW5kZXgirAEKEFdvcmtmbG93UnVuRXZlbnQSFwoPd29ya2Zsb3dfcnVuX2lkGAEgASgJEikKCmV2ZW50X3R5cGUYAiABKA4yFS5Xb3JrZmxvd1J1bkV2ZW50VHlwZRIzCg9ldmVudF90aW1lc3RhbXAYAyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEh8KB3Jlc3VsdHMYBCADKAsyDi5TdGVwUnVuUmVzdWx0IpIBCg1TdGVwUnVuUmVzdWx0EhwKFHRhc2tfcnVuX2V4dGVybmFsX2lkGAEgASgJEhEKCXRhc2tfbmFtZRgCIAEoCRISCgpqb2JfcnVuX2lkGAMgASgJEhIKBWVycm9yGAQgASgJSACIAQESEwoGb3V0cHV0GAUgASgJSAGIAQFCCAoGX2Vycm9yQgkKB19vdXRwdXQiYwoNT3ZlcnJpZGVzRGF0YRIcChR0YXNrX3J1bl9leHRlcm5hbF9pZBgBIAEoCRIMCgRwYXRoGAIgASgJEg0KBXZhbHVlGAMgASgJEhcKD2NhbGxlcl9maWxlbmFtZRgEIAEoCSIXChVPdmVycmlkZXNEYXRhUmVzcG9uc2UiVwoQSGVhcnRiZWF0UmVxdWVzdBIRCgl3b3JrZXJfaWQYASABKAkSMAoMaGVhcnRiZWF0X2F0GAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCITChFIZWFydGJlYXRSZXNwb25zZSJTChVSZWZyZXNoVGltZW91dFJlcXVlc3QSHAoUdGFza19ydW5fZXh0ZXJuYWxfaWQYASABKAkSHAoUaW5jcmVtZW50X3RpbWVvdXRfYnkYAiABKAkiSAoWUmVmcmVzaFRpbWVvdXRSZXNwb25zZRIuCgp0aW1lb3V0X2F0GAEgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCIyChJSZWxlYXNlU2xvdFJlcXVlc3QSHAoUdGFza19ydW5fZXh0ZXJuYWxfaWQYASABKAkiFQoTUmVsZWFzZVNsb3RSZXNwb25zZSI5ChlSZXN0b3JlRXZpY3RlZFRhc2tSZXF1ZXN0EhwKFHRhc2tfcnVuX2V4dGVybmFsX2lkGAEgASgJIi4KGlJlc3RvcmVFdmljdGVkVGFza1Jlc3BvbnNlEhAKCHJlcXVldWVkGAEgASgIIhMKEUdldFZlcnNpb25SZXF1ZXN0IiUKEkdldFZlcnNpb25SZXNwb25zZRIPCgd2ZXJzaW9uGAEgASgJKkEKBFNES1MSCwoHVU5LTk9XThAAEgYKAkdPEAESCgoGUFlUSE9OEAISDgoKVFlQRVNDUklQVBADEggKBFJVQlkQBCpfCgpBY3Rpb25UeXBlEhIKDlNUQVJUX1NURVBfUlVOEAASEwoPQ0FOQ0VMX1NURVBfUlVOEAESFwoTU1RBUlRfR0VUX0dST1VQX0tFWRACEg8KC1NUQVJUX0JBVENIEAMqogEKF0dyb3VwS2V5QWN0aW9uRXZlbnRUeXBlEiAKHEdST1VQX0tFWV9FVkVOVF9UWVBFX1VOS05PV04QABIgChxHUk9VUF9LRVlfRVZFTlRfVFlQRV9TVEFSVEVEEAESIgoeR1JPVVBfS0VZX0VWRU5UX1RZUEVfQ09NUExFVEVEEAISHwobR1JPVVBfS0VZX0VWRU5UX1RZUEVfRkFJTEVEEAMqywEKE1N0ZXBBY3Rpb25FdmVudFR5cGUSGwoXU1RFUF9FVkVOVF9UWVBFX1VOS05PV04QABIbChdTVEVQX0VWRU5UX1RZUEVfU1RBUlRFRBABEh0KGVNURVBfRVZFTlRfVFlQRV9DT01QTEVURUQQAhIaChZTVEVQX0VWRU5UX1RZUEVfRkFJTEVEEAMSIAocU1RFUF9FVkVOVF9UWVBFX0FDS05PV0xFREdFRBAEEh0KGVNURVBfRVZFTlRfVFlQRV9DQU5DRUxMRUQQBSplCgxSZXNvdXJjZVR5cGUSGQoVUkVTT1VSQ0VfVFlQRV9VTktOT1dOEAASGgoWUkVTT1VSQ0VfVFlQRV9TVEVQX1JVThABEh4KGlJFU09VUkNFX1RZUEVfV09SS0ZMT1dfUlVOEAIq/gEKEVJlc291cmNlRXZlbnRUeXBlEh8KG1JFU09VUkNFX0VWRU5UX1RZUEVfVU5LTk9XThAAEh8KG1JFU09VUkNFX0VWRU5UX1RZUEVfU1RBUlRFRBABEiEKHVJFU09VUkNFX0VWRU5UX1RZUEVfQ09NUExFVEVEEAISHgoaUkVTT1VSQ0VfRVZFTlRfVFlQRV9GQUlMRUQQAxIhCh1SRVNPVVJDRV9FVkVOVF9UWVBFX0NBTkNFTExFRBAEEiEKHVJFU09VUkNFX0VWRU5UX1RZUEVfVElNRURfT1VUEAUSHgoaUkVTT1VSQ0VfRVZFTlRfVFlQRV9TVFJFQU0QBio8ChRXb3JrZmxvd1J1bkV2ZW50VHlwZRIkCiBXT1JLRkxPV19SVU5fRVZFTlRfVFlQRV9GSU5JU0hFRBAAMsUICgpEaXNwYXRjaGVyEj0KCFJlZ2lzdGVyEhYuV29ya2VyUmVnaXN0ZXJSZXF1ZXN0GhcuV29ya2VyUmVnaXN0ZXJSZXNwb25zZSIAEjMKBkxpc3RlbhIULldvcmtlckxpc3RlblJlcXVlc3QaDy5Bc3NpZ25lZEFjdGlvbiIAMAESNQoITGlzdGVuVjISFC5Xb3JrZXJMaXN0ZW5SZXF1ZXN0Gg8uQXNzaWduZWRBY3Rpb24iADABEjQKCUhlYXJ0YmVhdBIRLkhlYXJ0YmVhdFJlcXVlc3QaEi5IZWFydGJlYXRSZXNwb25zZSIAElIKGVN1YnNjcmliZVRvV29ya2Zsb3dFdmVudHMSIS5TdWJzY3JpYmVUb1dvcmtmbG93RXZlbnRzUmVxdWVzdBoOLldvcmtmbG93RXZlbnQiADABElMKF1N1YnNjcmliZVRvV29ya2Zsb3dSdW5zEh8uU3Vic2NyaWJlVG9Xb3JrZmxvd1J1bnNSZXF1ZXN0GhEuV29ya2Zsb3dSdW5FdmVudCIAKAEwARI/ChNTZW5kU3RlcEFjdGlvbkV2ZW50EhAuU3RlcEFjdGlvbkV2ZW50GhQuQWN0aW9uRXZlbnRSZXNwb25zZSIAEkEKFFNlbmRCYXRjaEFjdGlvbkV2ZW50EhEuQmF0Y2hBY3Rpb25FdmVudBoULkFjdGlvbkV2ZW50UmVzcG9uc2UiABJHChdTZW5kR3JvdXBLZXlBY3Rpb25FdmVudBIULkdyb3VwS2V5QWN0aW9uRXZlbnQaFC5BY3Rpb25FdmVudFJlc3BvbnNlIgASPAoQUHV0T3ZlcnJpZGVzRGF0YRIOLk92ZXJyaWRlc0RhdGEaFi5PdmVycmlkZXNEYXRhUmVzcG9uc2UiABJGCgtVbnN1YnNjcmliZRIZLldvcmtlclVuc3Vic2NyaWJlUmVxdWVzdBoaLldvcmtlclVuc3Vic2NyaWJlUmVzcG9uc2UiABJDCg5SZWZyZXNoVGltZW91dBIWLlJlZnJlc2hUaW1lb3V0UmVxdWVzdBoXLlJlZnJlc2hUaW1lb3V0UmVzcG9uc2UiABI6CgtSZWxlYXNlU2xvdBITLlJlbGVhc2VTbG90UmVxdWVzdBoULlJlbGVhc2VTbG90UmVzcG9uc2UiABJPChJSZXN0b3JlRXZpY3RlZFRhc2sSGi5SZXN0b3JlRXZpY3RlZFRhc2tSZXF1ZXN0GhsuUmVzdG9yZUV2aWN0ZWRUYXNrUmVzcG9uc2UiABJPChJVcHNlcnRXb3JrZXJMYWJlbHMSGi5VcHNlcnRXb3JrZXJMYWJlbHNSZXF1ZXN0GhsuVXBzZXJ0V29ya2VyTGFiZWxzUmVzcG9uc2UiABI3CgpHZXRWZXJzaW9uEhIuR2V0VmVyc2lvblJlcXVlc3QaEy5HZXRWZXJzaW9uUmVzcG9uc2UiAEJHWkVnaXRodWIuY29tL2hhdGNoZXQtZGV2L2hhdGNoZXQvaW50ZXJuYWwvc2VydmljZXMvZGlzcGF0Y2hlci9jb250cmFjdHNiBnByb3RvMw", [wkt_1.file_google_protobuf_timestamp]);
13
13
  /**
14
14
  * Describes the message WorkerLabels.
15
15
  * Use `create(WorkerLabelsSchema)` to create a new message.
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.durationToString = durationToString;
4
4
  exports.durationToMs = durationToMs;
5
- const DURATION_RE = /^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$/;
5
+ const DURATION_RE = /^(?:(\d*\.?\d+)h)?(?:(\d*\.?\d+)m)?(?:(\d*\.?\d+)s)?$/;
6
6
  /** Normalizes a Duration to Go-style string format (e.g. "1h30m5s"). */
7
7
  function durationToString(d) {
8
8
  if (typeof d === 'string')
@@ -39,8 +39,8 @@ function durationToMs(d) {
39
39
  }
40
40
  const match = d.match(DURATION_RE);
41
41
  if (!match) {
42
- throw new Error(`Invalid duration string: "${d}". Expected format like "1h30m5s", "10m", "30s".`);
42
+ throw new Error(`Invalid duration string: "${d}". Expected format like "1h30m5s", "10m", "30s", "0.5s".`);
43
43
  }
44
44
  const [, h, m, s] = match;
45
- return ((parseInt(h !== null && h !== void 0 ? h : '0', 10) * 3600 + parseInt(m !== null && m !== void 0 ? m : '0', 10) * 60 + parseInt(s !== null && s !== void 0 ? s : '0', 10)) * 1000);
45
+ return Math.round(parseFloat(h !== null && h !== void 0 ? h : '0') * 3600000 + parseFloat(m !== null && m !== void 0 ? m : '0') * 60000 + parseFloat(s !== null && s !== void 0 ? s : '0') * 1000);
46
46
  }
@@ -1,5 +1,7 @@
1
1
  export declare const MinEngineVersion: {
2
2
  readonly SLOT_CONFIG: "v0.78.23";
3
3
  readonly DURABLE_EVICTION: "v0.80.0";
4
+ readonly RETRY_AFTER: "v0.111.0";
4
5
  };
6
+ export declare function supportsRetryAfter(engineVersion: string | undefined): boolean;
5
7
  export declare function supportsEviction(engineVersion: string | undefined): boolean;
@@ -1,12 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MinEngineVersion = void 0;
4
+ exports.supportsRetryAfter = supportsRetryAfter;
4
5
  exports.supportsEviction = supportsEviction;
5
6
  const deprecation_1 = require("./deprecated/deprecation");
6
7
  exports.MinEngineVersion = {
7
8
  SLOT_CONFIG: 'v0.78.23',
8
9
  DURABLE_EVICTION: 'v0.80.0',
10
+ RETRY_AFTER: 'v0.111.0',
9
11
  };
12
+ function supportsRetryAfter(engineVersion) {
13
+ if (!engineVersion)
14
+ return false;
15
+ return !(0, deprecation_1.semverLessThan)(engineVersion, exports.MinEngineVersion.RETRY_AFTER);
16
+ }
10
17
  function supportsEviction(engineVersion) {
11
18
  if (!engineVersion)
12
19
  return false;
@@ -69,6 +69,7 @@ export declare class InternalWorker {
69
69
  * Keep the signature in sync with the instrumentor wrapper.
70
70
  */
71
71
  handleStartStepRun(action: Action): Promise<Error | undefined>;
72
+ private retryAfterMs;
72
73
  getStepActionEvent(action: Action, eventType: StepActionEventType, shouldNotRetry: boolean, payload?: any, retryCount?: number): StepActionEvent;
73
74
  /**
74
75
  * Handles a START_BATCH action: invokes the registered batch task handler once with
@@ -88,6 +89,7 @@ export declare class InternalWorker {
88
89
  getBatchActionEvent(action: Action, eventType: StepActionEventType, items: {
89
90
  taskRunExternalId: string;
90
91
  eventPayload: string;
92
+ retryAfterMs?: number;
91
93
  }[]): BatchActionEvent;
92
94
  getGroupKeyActionEvent(action: Action, eventType: GroupKeyActionEventType, payload?: any): GroupKeyActionEvent;
93
95
  /**
@@ -349,6 +349,7 @@ class InternalWorker {
349
349
  });
350
350
  const failure = (error) => __awaiter(this, void 0, void 0, function* () {
351
351
  const shouldNotRetry = error instanceof task_1.NonRetryableError;
352
+ const retryAfterMs = this.retryAfterMs(error, actionId);
352
353
  try {
353
354
  if (context.cancelled) {
354
355
  return;
@@ -366,6 +367,7 @@ class InternalWorker {
366
367
  message: error === null || error === void 0 ? void 0 : error.message,
367
368
  stack: error === null || error === void 0 ? void 0 : error.stack,
368
369
  }, action.retryCount);
370
+ event.retryAfterMs = retryAfterMs;
369
371
  yield this.client.dispatcher.sendStepActionEvent(event);
370
372
  }
371
373
  catch (e) {
@@ -423,6 +425,18 @@ class InternalWorker {
423
425
  }
424
426
  });
425
427
  }
428
+ retryAfterMs(error, actionId) {
429
+ var _a;
430
+ if (!(error instanceof task_1.RetryAfterError)) {
431
+ return undefined;
432
+ }
433
+ if (!(0, engine_version_1.supportsRetryAfter)(this.engineVersion)) {
434
+ this.logger.warn(`RetryAfterError requires engine >= ${engine_version_1.MinEngineVersion.RETRY_AFTER} ` +
435
+ `(connected: ${(_a = this.engineVersion) !== null && _a !== void 0 ? _a : 'unknown'}). Task ${actionId} threw it, so the engine ` +
436
+ `will handle the failure with the task's retry policy instead of the requested delay.`);
437
+ }
438
+ return error.afterMs;
439
+ }
426
440
  getStepActionEvent(action, eventType, shouldNotRetry, payload = '', retryCount = 0) {
427
441
  return {
428
442
  workerId: this.name,
@@ -518,7 +532,12 @@ class InternalWorker {
518
532
  sendBatchFailureForAll(action, memberIds, error) {
519
533
  return __awaiter(this, void 0, void 0, function* () {
520
534
  const payload = JSON.stringify({ message: error === null || error === void 0 ? void 0 : error.message, stack: error === null || error === void 0 ? void 0 : error.stack });
521
- const items = memberIds.map((id) => ({ taskRunExternalId: id, eventPayload: payload }));
535
+ const retryAfterMs = this.retryAfterMs(error, action.actionId);
536
+ const items = memberIds.map((id) => ({
537
+ taskRunExternalId: id,
538
+ eventPayload: payload,
539
+ retryAfterMs,
540
+ }));
522
541
  try {
523
542
  yield this.client.dispatcher.sendBatchActionEvent(this.getBatchActionEvent(action, dispatcher_1.StepActionEventType.STEP_EVENT_TYPE_FAILED, items));
524
543
  }
@@ -35,21 +35,22 @@ const workflow_14 = require("./durable_callback_ordering/workflow");
35
35
  const workflow_15 = require("./durable_sleep/workflow");
36
36
  const workflow_16 = require("./logger/workflow");
37
37
  const workflow_17 = require("./non_retryable/workflow");
38
- const workflow_18 = require("./on_failure/workflow");
39
- const workflow_19 = require("./idempotency/workflow");
40
- const workflow_20 = require("./on_event/workflow");
41
- const workflow_21 = require("./return_exceptions/workflow");
42
- const workflow_22 = require("./run_details/workflow");
38
+ const workflow_18 = require("./retry_after/workflow");
39
+ const workflow_19 = require("./on_failure/workflow");
40
+ const workflow_20 = require("./idempotency/workflow");
41
+ const workflow_21 = require("./on_event/workflow");
42
+ const workflow_22 = require("./return_exceptions/workflow");
43
+ const workflow_23 = require("./run_details/workflow");
43
44
  const e2e_workflows_1 = require("./simple/e2e-workflows");
44
- const workflow_23 = require("./batch_assign/workflow");
45
- const workflow_24 = require("./streaming/workflow");
46
- const workflow_25 = require("./subscribe_to_stream/workflow");
47
- const workflow_26 = require("./timeout/workflow");
48
- const workflow_27 = require("./webhooks/workflow");
49
- const workflow_28 = require("./child_index/workflow");
50
- const workflow_29 = require("./support_agent/workflow");
51
- const workflow_30 = require("./welcome_email/workflow");
52
- const workflow_31 = require("./pdf_pipeline/workflow");
45
+ const workflow_24 = require("./batch_assign/workflow");
46
+ const workflow_25 = require("./streaming/workflow");
47
+ const workflow_26 = require("./subscribe_to_stream/workflow");
48
+ const workflow_27 = require("./timeout/workflow");
49
+ const workflow_28 = require("./webhooks/workflow");
50
+ const workflow_29 = require("./child_index/workflow");
51
+ const workflow_30 = require("./support_agent/workflow");
52
+ const workflow_31 = require("./welcome_email/workflow");
53
+ const workflow_32 = require("./pdf_pipeline/workflow");
53
54
  const workflows = [
54
55
  workflow_1.bulkChild,
55
56
  workflow_1.bulkParentWorkflow,
@@ -101,43 +102,45 @@ const workflows = [
101
102
  workflow_13.evictableChildBulkSpawn,
102
103
  (0, workflow_16.createLoggingWorkflow)(hatchet_client_1.hatchet),
103
104
  workflow_17.nonRetryableWorkflow,
104
- workflow_18.failureWorkflow,
105
- workflow_19.idempotentTask,
106
- workflow_19.idempotentTaskShortWindow,
107
- workflow_20.lower,
108
- workflow_21.returnExceptionsTask,
109
- workflow_22.runDetailTestWorkflow,
105
+ workflow_18.retryAfterUpstreamDelay,
106
+ workflow_18.retryAfterExponentialBackoff,
107
+ workflow_19.failureWorkflow,
108
+ workflow_20.idempotentTask,
109
+ workflow_20.idempotentTaskShortWindow,
110
+ workflow_21.lower,
111
+ workflow_22.returnExceptionsTask,
112
+ workflow_23.runDetailTestWorkflow,
110
113
  e2e_workflows_1.helloWorld,
111
114
  e2e_workflows_1.helloWorldDurable,
112
- workflow_24.streamingTask,
113
- workflow_25.dagStream,
114
- workflow_25.longStream,
115
- workflow_26.timeoutTask,
116
- workflow_26.refreshTimeoutTask,
117
- workflow_27.webhookWorkflow,
118
- workflow_28.childIndexChild,
119
- workflow_28.childIndexParent,
120
- workflow_28.scenarioTask,
121
- workflow_28.orchestratorTask,
122
- workflow_29.supportAgent,
123
- workflow_29.triageTicket,
124
- workflow_29.generateReply,
125
- workflow_29.escalateTicket,
126
- workflow_30.welcomeEmail,
127
- workflow_31.pdfPipeline,
128
- workflow_23.batchSimple,
129
- workflow_23.batchKeyed,
130
- workflow_23.batchKeyedFailable,
131
- workflow_23.batchKeyedInterval,
132
- workflow_23.batchLarge,
133
- workflow_23.batchSingle,
134
- workflow_23.batchOrdered,
135
- workflow_23.batchBroadcast,
136
- workflow_23.batchCancel,
137
- workflow_23.child,
138
- workflow_23.childBatch,
139
- workflow_23.batchChildSpawn,
140
- workflow_23.batchChildBatchSpawn,
115
+ workflow_25.streamingTask,
116
+ workflow_26.dagStream,
117
+ workflow_26.longStream,
118
+ workflow_27.timeoutTask,
119
+ workflow_27.refreshTimeoutTask,
120
+ workflow_28.webhookWorkflow,
121
+ workflow_29.childIndexChild,
122
+ workflow_29.childIndexParent,
123
+ workflow_29.scenarioTask,
124
+ workflow_29.orchestratorTask,
125
+ workflow_30.supportAgent,
126
+ workflow_30.triageTicket,
127
+ workflow_30.generateReply,
128
+ workflow_30.escalateTicket,
129
+ workflow_31.welcomeEmail,
130
+ workflow_32.pdfPipeline,
131
+ workflow_24.batchSimple,
132
+ workflow_24.batchKeyed,
133
+ workflow_24.batchKeyedFailable,
134
+ workflow_24.batchKeyedInterval,
135
+ workflow_24.batchLarge,
136
+ workflow_24.batchSingle,
137
+ workflow_24.batchOrdered,
138
+ workflow_24.batchBroadcast,
139
+ workflow_24.batchCancel,
140
+ workflow_24.child,
141
+ workflow_24.childBatch,
142
+ workflow_24.batchChildSpawn,
143
+ workflow_24.batchChildBatchSpawn,
141
144
  ];
142
145
  function main() {
143
146
  return __awaiter(this, void 0, void 0, function* () {
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const workflow_1 = require("./workflow");
13
+ function main() {
14
+ return __awaiter(this, void 0, void 0, function* () {
15
+ const res = yield workflow_1.retryAfterUpstreamDelay.run({ failingAttempts: 2 });
16
+ console.log(res);
17
+ });
18
+ }
19
+ if (require.main === module) {
20
+ main();
21
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const hatchet_client_1 = require("../hatchet-client");
13
+ const workflow_1 = require("./workflow");
14
+ function main() {
15
+ return __awaiter(this, void 0, void 0, function* () {
16
+ const worker = yield hatchet_client_1.hatchet.worker('retry-after-worker', {
17
+ workflows: [workflow_1.retryAfterUpstreamDelay, workflow_1.retryAfterExponentialBackoff],
18
+ });
19
+ yield worker.start();
20
+ });
21
+ }
22
+ if (require.main === module) {
23
+ main();
24
+ }
@@ -0,0 +1,9 @@
1
+ export type UpstreamInput = {
2
+ failingAttempts: number;
3
+ };
4
+ export declare const retryAfterUpstreamDelay: import("../..").TaskWorkflowDeclaration<UpstreamInput, {
5
+ attempt: number;
6
+ }, {}, {}, {}, {}>;
7
+ export declare const retryAfterExponentialBackoff: import("../..").TaskWorkflowDeclaration<UpstreamInput, {
8
+ attempt: number;
9
+ }, {}, {}, {}, {}>;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.retryAfterExponentialBackoff = exports.retryAfterUpstreamDelay = void 0;
13
+ const task_1 = require("../../task");
14
+ const hatchet_client_1 = require("../hatchet-client");
15
+ // > Retry after an upstream-provided delay
16
+ exports.retryAfterUpstreamDelay = hatchet_client_1.hatchet.task({
17
+ name: 'retry-after-upstream-delay',
18
+ retries: 5,
19
+ fn: (input, ctx) => __awaiter(void 0, void 0, void 0, function* () {
20
+ if (ctx.retryCount() < input.failingAttempts) {
21
+ throw new task_1.RetryAfterError('upstream rate limited', { after: '2s' });
22
+ }
23
+ return { attempt: ctx.retryCount() };
24
+ }),
25
+ });
26
+ // !!
27
+ // > Exponential backoff with full jitter
28
+ exports.retryAfterExponentialBackoff = hatchet_client_1.hatchet.task({
29
+ name: 'retry-after-exponential-backoff',
30
+ retries: 3,
31
+ fn: (input, ctx) => __awaiter(void 0, void 0, void 0, function* () {
32
+ if (ctx.retryCount() < input.failingAttempts) {
33
+ throw new task_1.RetryAfterError('upstream unavailable', {
34
+ after: Math.random() * Math.min(2 ** ctx.retryCount(), 60) * 1000,
35
+ });
36
+ }
37
+ return { attempt: ctx.retryCount() };
38
+ }),
39
+ });
40
+ // !!
package/v1/task.d.ts CHANGED
@@ -96,6 +96,19 @@ export type IdempotencyConfig = TTLBasedIdempotencyConfig | StatusBasedIdempoten
96
96
  export declare class NonRetryableError extends Error {
97
97
  constructor(message?: string);
98
98
  }
99
+ export type RetryAfterOpts = {
100
+ /**
101
+ * The delay before the next attempt, e.g. `'90s'`, `{ minutes: 5 }`, or a number of milliseconds.
102
+ */
103
+ after: Duration;
104
+ };
105
+ /**
106
+ * Throw from a task to retry it after a delay of its choosing. The retry counts against the task's `retries`.
107
+ */
108
+ export declare class RetryAfterError extends Error {
109
+ readonly afterMs: number;
110
+ constructor(message: string | undefined, opts: RetryAfterOpts);
111
+ }
99
112
  export type TaskFn<I extends InputType = UnknownInputType, O extends OutputType = void, C = Context<I>> = (input: I, ctx: C) => O | Promise<O>;
100
113
  export type DurableTaskFn<I extends InputType = UnknownInputType, O extends OutputType = void> = TaskFn<I, O, DurableContext<I>>;
101
114
  /**
package/v1/task.js CHANGED
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NonRetryableError = exports.WorkerLabelComparator = exports.ConcurrencyLimitStrategy = void 0;
3
+ exports.RetryAfterError = exports.NonRetryableError = exports.WorkerLabelComparator = exports.ConcurrencyLimitStrategy = void 0;
4
4
  const workflows_1 = require("../protoc/v1/workflows");
5
5
  Object.defineProperty(exports, "ConcurrencyLimitStrategy", { enumerable: true, get: function () { return workflows_1.ConcurrencyLimitStrategy; } });
6
+ const duration_1 = require("./client/duration");
6
7
  const trigger_1 = require("../protoc/v1/shared/trigger");
7
8
  Object.defineProperty(exports, "WorkerLabelComparator", { enumerable: true, get: function () { return trigger_1.WorkerLabelComparator; } });
8
9
  class NonRetryableError extends Error {
@@ -13,3 +14,15 @@ class NonRetryableError extends Error {
13
14
  }
14
15
  }
15
16
  exports.NonRetryableError = NonRetryableError;
17
+ /**
18
+ * Throw from a task to retry it after a delay of its choosing. The retry counts against the task's `retries`.
19
+ */
20
+ class RetryAfterError extends Error {
21
+ constructor(message, opts) {
22
+ super(message);
23
+ this.name = 'RetryAfterError';
24
+ this.afterMs = Math.max(Math.round((0, duration_1.durationToMs)(opts.after)), 0);
25
+ Object.setPrototypeOf(this, new.target.prototype);
26
+ }
27
+ }
28
+ exports.RetryAfterError = RetryAfterError;
package/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const HATCHET_VERSION = "1.36.0";
1
+ export declare const HATCHET_VERSION = "1.37.0";
package/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.HATCHET_VERSION = void 0;
4
- exports.HATCHET_VERSION = '1.36.0';
4
+ exports.HATCHET_VERSION = '1.37.0';