hatchet-sdk 0.11.0 → 0.11.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 16eca35119ecc07394654147b2c3f4aada19f82dd4829e4cbb18d812f15623ec
4
- data.tar.gz: aeffb9c04dede6fbabee1bf21dfecd30307387ba46e70b7cab694cbca07874ad
3
+ metadata.gz: 8061a1ca79c9741890e7228b266aba4551c91408c3edede118e8be8e108d73fd
4
+ data.tar.gz: 3878c4f5d3e5c4c270cecd0b54ea08ef47cfbd540fe5e37c58f34211dd5905e0
5
5
  SHA512:
6
- metadata.gz: 24fc846b28bce11b91f3a0851d200dc23859830b4ec13fcb792897e1191b8a5b86da33189c1c5c7481e980ecfe3699a7988f90b413cccfaceca03bb0e52e31fb
7
- data.tar.gz: 37ed7f42b45a382d89a6289a1b9726c25d88f7c63d3fae0ede9a3cd77995f5a2f87b31af31a738df1553782274d05120167a704ce340b557fe8f3f28b0ba8aa9
6
+ metadata.gz: 5cb383edd73867ef24a2bb282963d32e83b1bd92840ca28e946c9b334f2656ca960e59804076cd13c5af3fd2c0d0fe1c7440bd440f5ee88a10a5af55a5f0512a
7
+ data.tar.gz: a03d970376c65133dc0438b4f8315460924676b2bcb4dc5728343d8ec13af00f8417c48a1634f3bde9d1ec31b67100a2d49bcb692ab4a6c91fd1b1a041333ee6
data/CHANGELOG.md CHANGED
@@ -5,6 +5,12 @@ All notable changes to Hatchet's Ruby SDK will be documented in this changelog.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.11.1] - 2026-10-23
9
+
10
+ ### Fixed
11
+
12
+ - [Durable tasks](https://docs.hatchet.run/v1/durable-tasks) no longer stall after the worker's durable stream reconnects in the middle of a wait. The worker now reports the last completion it received in its status requests, so the engine resumes delivery from there instead of holding later completions until the task is evicted and replayed.
13
+
8
14
  ## [0.11.0] - 2026-10-14
9
15
 
10
16
  ### Added
@@ -8,7 +8,7 @@ require 'v1/shared/condition_pb'
8
8
  require 'v1/shared/trigger_pb'
9
9
 
10
10
 
11
- descriptor_data = "\n\x13v1/dispatcher.proto\x12\x02v1\x1a\x19v1/shared/condition.proto\x1a\x17v1/shared/trigger.proto\"5\n DurableTaskRequestRegisterWorker\x12\x11\n\tworker_id\x18\x01 \x01(\t\"6\n!DurableTaskResponseRegisterWorker\x12\x11\n\tworker_id\x18\x01 \x01(\t\"y\n\x17\x44urableEventLogEntryRef\x12 \n\x18\x64urable_task_external_id\x18\x01 \x01(\t\x12\x18\n\x10invocation_count\x18\x02 \x01(\x05\x12\x11\n\tbranch_id\x18\x03 \x01(\x03\x12\x0f\n\x07node_id\x18\x04 \x01(\x03\"^\n\x16\x44urableTaskRunAckEntry\x12\x0f\n\x07node_id\x18\x01 \x01(\x03\x12\x11\n\tbranch_id\x18\x02 \x01(\x03\x12 \n\x18workflow_run_external_id\x18\x03 \x01(\t\"\xa3\x01\n\x1f\x44urableTaskEventMemoAckResponse\x12(\n\x03ref\x18\x01 \x01(\x0b\x32\x1b.v1.DurableEventLogEntryRef\x12\x1c\n\x14memo_already_existed\x18\x02 \x01(\x08\x12 \n\x13memo_result_payload\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x42\x16\n\x14_memo_result_payload\"\x95\x01\n&DurableTaskEventTriggerRunsAckResponse\x12 \n\x18\x64urable_task_external_id\x18\x01 \x01(\t\x12\x18\n\x10invocation_count\x18\x02 \x01(\x05\x12/\n\x0brun_entries\x18\x03 \x03(\x0b\x32\x1a.v1.DurableTaskRunAckEntry\"N\n\"DurableTaskEventWaitForAckResponse\x12(\n\x03ref\x18\x01 \x01(\x0b\x32\x1b.v1.DurableEventLogEntryRef\"\xa8\x01\n)DurableTaskEventLogEntryCompletedResponse\x12(\n\x03ref\x18\x01 \x01(\x0b\x32\x1b.v1.DurableEventLogEntryRef\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x12\n\nis_failure\x18\x03 \x01(\x08\x12\x1a\n\rerror_message\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x10\n\x0e_error_message\"\x7f\n!DurableTaskEvictInvocationRequest\x12\x18\n\x10invocation_count\x18\x01 \x01(\x05\x12 \n\x18\x64urable_task_external_id\x18\x02 \x01(\t\x12\x13\n\x06reason\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_reason\"\\\n\x1e\x44urableTaskEvictionAckResponse\x12\x18\n\x10invocation_count\x18\x01 \x01(\x05\x12 \n\x18\x64urable_task_external_id\x18\x02 \x01(\t\"\x82\x01\n DurableTaskAwaitedCompletedEntry\x12 \n\x18\x64urable_task_external_id\x18\x01 \x01(\t\x12\x11\n\tbranch_id\x18\x02 \x01(\x03\x12\x0f\n\x07node_id\x18\x03 \x01(\x03\x12\x18\n\x10invocation_count\x18\x04 \x01(\x05\"j\n\x1c\x44urableTaskServerEvictNotice\x12 \n\x18\x64urable_task_external_id\x18\x01 \x01(\t\x12\x18\n\x10invocation_count\x18\x02 \x01(\x05\x12\x0e\n\x06reason\x18\x03 \x01(\t\"r\n\x1e\x44urableTaskWorkerStatusRequest\x12\x11\n\tworker_id\x18\x01 \x01(\t\x12=\n\x0fwaiting_entries\x18\x02 \x03(\x0b\x32$.v1.DurableTaskAwaitedCompletedEntry\"m\n\x1e\x44urableTaskCompleteMemoRequest\x12(\n\x03ref\x18\x01 \x01(\x0b\x32\x1b.v1.DurableEventLogEntryRef\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x10\n\x08memo_key\x18\x03 \x01(\x0c\"\x83\x01\n\x16\x44urableTaskMemoRequest\x12\x18\n\x10invocation_count\x18\x01 \x01(\x05\x12 \n\x18\x64urable_task_external_id\x18\x02 \x01(\t\x12\x0b\n\x03key\x18\x03 \x01(\x0c\x12\x14\n\x07payload\x18\x04 \x01(\x0cH\x00\x88\x01\x01\x42\n\n\x08_payload\"\x8d\x01\n\x1d\x44urableTaskTriggerRunsRequest\x12\x18\n\x10invocation_count\x18\x01 \x01(\x05\x12 \n\x18\x64urable_task_external_id\x18\x02 \x01(\t\x12\x30\n\x0ctrigger_opts\x18\x03 \x03(\x0b\x32\x1a.v1.TriggerWorkflowRequest\"\xd3\x01\n\x19\x44urableTaskWaitForRequest\x12\x18\n\x10invocation_count\x18\x01 \x01(\x05\x12 \n\x18\x64urable_task_external_id\x18\x02 \x01(\t\x12\x44\n\x13wait_for_conditions\x18\x03 \x01(\x0b\x32\".v1.DurableEventListenerConditionsH\x00\x88\x01\x01\x12\x12\n\x05label\x18\x04 \x01(\tH\x01\x88\x01\x01\x42\x16\n\x14_wait_for_conditionsB\x08\n\x06_label\"\xb7\x03\n\x12\x44urableTaskRequest\x12?\n\x0fregister_worker\x18\x01 \x01(\x0b\x32$.v1.DurableTaskRequestRegisterWorkerH\x00\x12*\n\x04memo\x18\x02 \x01(\x0b\x32\x1a.v1.DurableTaskMemoRequestH\x00\x12\x39\n\x0ctrigger_runs\x18\x03 \x01(\x0b\x32!.v1.DurableTaskTriggerRunsRequestH\x00\x12\x31\n\x08wait_for\x18\x04 \x01(\x0b\x32\x1d.v1.DurableTaskWaitForRequestH\x00\x12\x41\n\x10\x65vict_invocation\x18\x05 \x01(\x0b\x32%.v1.DurableTaskEvictInvocationRequestH\x00\x12;\n\rworker_status\x18\x06 \x01(\x0b\x32\".v1.DurableTaskWorkerStatusRequestH\x00\x12;\n\rcomplete_memo\x18\x07 \x01(\x0b\x32\".v1.DurableTaskCompleteMemoRequestH\x00\x42\t\n\x07message\"\x89\x01\n\x18\x44urableTaskErrorResponse\x12(\n\x03ref\x18\x01 \x01(\x0b\x32\x1b.v1.DurableEventLogEntryRef\x12,\n\nerror_type\x18\x02 \x01(\x0e\x32\x18.v1.DurableTaskErrorType\x12\x15\n\rerror_message\x18\x03 \x01(\t\"\x92\x04\n\x13\x44urableTaskResponse\x12@\n\x0fregister_worker\x18\x01 \x01(\x0b\x32%.v1.DurableTaskResponseRegisterWorkerH\x00\x12\x37\n\x08memo_ack\x18\x02 \x01(\x0b\x32#.v1.DurableTaskEventMemoAckResponseH\x00\x12\x46\n\x10trigger_runs_ack\x18\x03 \x01(\x0b\x32*.v1.DurableTaskEventTriggerRunsAckResponseH\x00\x12>\n\x0cwait_for_ack\x18\x04 \x01(\x0b\x32&.v1.DurableTaskEventWaitForAckResponseH\x00\x12H\n\x0f\x65ntry_completed\x18\x05 \x01(\x0b\x32-.v1.DurableTaskEventLogEntryCompletedResponseH\x00\x12-\n\x05\x65rror\x18\x06 \x01(\x0b\x32\x1c.v1.DurableTaskErrorResponseH\x00\x12:\n\x0c\x65viction_ack\x18\x07 \x01(\x0b\x32\".v1.DurableTaskEvictionAckResponseH\x00\x12\x38\n\x0cserver_evict\x18\x08 \x01(\x0b\x32 .v1.DurableTaskServerEvictNoticeH\x00\x42\t\n\x07message\"z\n\x1bRegisterDurableEventRequest\x12\x0f\n\x07task_id\x18\x01 \x01(\t\x12\x12\n\nsignal_key\x18\x02 \x01(\t\x12\x36\n\nconditions\x18\x03 \x01(\x0b\x32\".v1.DurableEventListenerConditions\"\x1e\n\x1cRegisterDurableEventResponse\"C\n\x1cListenForDurableEventRequest\x12\x0f\n\x07task_id\x18\x01 \x01(\t\x12\x12\n\nsignal_key\x18\x02 \x01(\t\"A\n\x0c\x44urableEvent\x12\x0f\n\x07task_id\x18\x01 \x01(\t\x12\x12\n\nsignal_key\x18\x02 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\x0c*k\n\x14\x44urableTaskErrorType\x12\'\n#DURABLE_TASK_ERROR_TYPE_UNSPECIFIED\x10\x00\x12*\n&DURABLE_TASK_ERROR_TYPE_NONDETERMINISM\x10\x01\x32\x84\x02\n\x0cV1Dispatcher\x12\x44\n\x0b\x44urableTask\x12\x16.v1.DurableTaskRequest\x1a\x17.v1.DurableTaskResponse\"\x00(\x01\x30\x01\x12[\n\x14RegisterDurableEvent\x12\x1f.v1.RegisterDurableEventRequest\x1a .v1.RegisterDurableEventResponse\"\x00\x12Q\n\x15ListenForDurableEvent\x12 .v1.ListenForDurableEventRequest\x1a\x10.v1.DurableEvent\"\x00(\x01\x30\x01\x42\x42Z@github.com/hatchet-dev/hatchet/internal/services/shared/proto/v1b\x06proto3"
11
+ descriptor_data = "\n\x13v1/dispatcher.proto\x12\x02v1\x1a\x19v1/shared/condition.proto\x1a\x17v1/shared/trigger.proto\"5\n DurableTaskRequestRegisterWorker\x12\x11\n\tworker_id\x18\x01 \x01(\t\"6\n!DurableTaskResponseRegisterWorker\x12\x11\n\tworker_id\x18\x01 \x01(\t\"y\n\x17\x44urableEventLogEntryRef\x12 \n\x18\x64urable_task_external_id\x18\x01 \x01(\t\x12\x18\n\x10invocation_count\x18\x02 \x01(\x05\x12\x11\n\tbranch_id\x18\x03 \x01(\x03\x12\x0f\n\x07node_id\x18\x04 \x01(\x03\"^\n\x16\x44urableTaskRunAckEntry\x12\x0f\n\x07node_id\x18\x01 \x01(\x03\x12\x11\n\tbranch_id\x18\x02 \x01(\x03\x12 \n\x18workflow_run_external_id\x18\x03 \x01(\t\"\xa3\x01\n\x1f\x44urableTaskEventMemoAckResponse\x12(\n\x03ref\x18\x01 \x01(\x0b\x32\x1b.v1.DurableEventLogEntryRef\x12\x1c\n\x14memo_already_existed\x18\x02 \x01(\x08\x12 \n\x13memo_result_payload\x18\x03 \x01(\x0cH\x00\x88\x01\x01\x42\x16\n\x14_memo_result_payload\"\x95\x01\n&DurableTaskEventTriggerRunsAckResponse\x12 \n\x18\x64urable_task_external_id\x18\x01 \x01(\t\x12\x18\n\x10invocation_count\x18\x02 \x01(\x05\x12/\n\x0brun_entries\x18\x03 \x03(\x0b\x32\x1a.v1.DurableTaskRunAckEntry\"N\n\"DurableTaskEventWaitForAckResponse\x12(\n\x03ref\x18\x01 \x01(\x0b\x32\x1b.v1.DurableEventLogEntryRef\"\xda\x01\n)DurableTaskEventLogEntryCompletedResponse\x12(\n\x03ref\x18\x01 \x01(\x0b\x32\x1b.v1.DurableEventLogEntryRef\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x12\n\nis_failure\x18\x03 \x01(\x08\x12\x1a\n\rerror_message\x18\x04 \x01(\tH\x00\x88\x01\x01\x12\x1c\n\x0fsatisfied_order\x18\x05 \x01(\x03H\x01\x88\x01\x01\x42\x10\n\x0e_error_messageB\x12\n\x10_satisfied_order\"\x7f\n!DurableTaskEvictInvocationRequest\x12\x18\n\x10invocation_count\x18\x01 \x01(\x05\x12 \n\x18\x64urable_task_external_id\x18\x02 \x01(\t\x12\x13\n\x06reason\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\t\n\x07_reason\"\\\n\x1e\x44urableTaskEvictionAckResponse\x12\x18\n\x10invocation_count\x18\x01 \x01(\x05\x12 \n\x18\x64urable_task_external_id\x18\x02 \x01(\t\"\x82\x01\n DurableTaskAwaitedCompletedEntry\x12 \n\x18\x64urable_task_external_id\x18\x01 \x01(\t\x12\x11\n\tbranch_id\x18\x02 \x01(\x03\x12\x0f\n\x07node_id\x18\x03 \x01(\x03\x12\x18\n\x10invocation_count\x18\x04 \x01(\x05\"j\n\x1c\x44urableTaskServerEvictNotice\x12 \n\x18\x64urable_task_external_id\x18\x01 \x01(\t\x12\x18\n\x10invocation_count\x18\x02 \x01(\x05\x12\x0e\n\x06reason\x18\x03 \x01(\t\"\x89\x01\n!DurableTaskReceivedSatisfiedOrder\x12 \n\x18\x64urable_task_external_id\x18\x01 \x01(\t\x12\x18\n\x10invocation_count\x18\x02 \x01(\x05\x12(\n highest_received_satisfied_order\x18\x03 \x01(\x03\"\xbc\x01\n\x1e\x44urableTaskWorkerStatusRequest\x12\x11\n\tworker_id\x18\x01 \x01(\t\x12=\n\x0fwaiting_entries\x18\x02 \x03(\x0b\x32$.v1.DurableTaskAwaitedCompletedEntry\x12H\n\x19received_satisfied_orders\x18\x03 \x03(\x0b\x32%.v1.DurableTaskReceivedSatisfiedOrder\"m\n\x1e\x44urableTaskCompleteMemoRequest\x12(\n\x03ref\x18\x01 \x01(\x0b\x32\x1b.v1.DurableEventLogEntryRef\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x10\n\x08memo_key\x18\x03 \x01(\x0c\"\x83\x01\n\x16\x44urableTaskMemoRequest\x12\x18\n\x10invocation_count\x18\x01 \x01(\x05\x12 \n\x18\x64urable_task_external_id\x18\x02 \x01(\t\x12\x0b\n\x03key\x18\x03 \x01(\x0c\x12\x14\n\x07payload\x18\x04 \x01(\x0cH\x00\x88\x01\x01\x42\n\n\x08_payload\"\x8d\x01\n\x1d\x44urableTaskTriggerRunsRequest\x12\x18\n\x10invocation_count\x18\x01 \x01(\x05\x12 \n\x18\x64urable_task_external_id\x18\x02 \x01(\t\x12\x30\n\x0ctrigger_opts\x18\x03 \x03(\x0b\x32\x1a.v1.TriggerWorkflowRequest\"\xd3\x01\n\x19\x44urableTaskWaitForRequest\x12\x18\n\x10invocation_count\x18\x01 \x01(\x05\x12 \n\x18\x64urable_task_external_id\x18\x02 \x01(\t\x12\x44\n\x13wait_for_conditions\x18\x03 \x01(\x0b\x32\".v1.DurableEventListenerConditionsH\x00\x88\x01\x01\x12\x12\n\x05label\x18\x04 \x01(\tH\x01\x88\x01\x01\x42\x16\n\x14_wait_for_conditionsB\x08\n\x06_label\"\xb7\x03\n\x12\x44urableTaskRequest\x12?\n\x0fregister_worker\x18\x01 \x01(\x0b\x32$.v1.DurableTaskRequestRegisterWorkerH\x00\x12*\n\x04memo\x18\x02 \x01(\x0b\x32\x1a.v1.DurableTaskMemoRequestH\x00\x12\x39\n\x0ctrigger_runs\x18\x03 \x01(\x0b\x32!.v1.DurableTaskTriggerRunsRequestH\x00\x12\x31\n\x08wait_for\x18\x04 \x01(\x0b\x32\x1d.v1.DurableTaskWaitForRequestH\x00\x12\x41\n\x10\x65vict_invocation\x18\x05 \x01(\x0b\x32%.v1.DurableTaskEvictInvocationRequestH\x00\x12;\n\rworker_status\x18\x06 \x01(\x0b\x32\".v1.DurableTaskWorkerStatusRequestH\x00\x12;\n\rcomplete_memo\x18\x07 \x01(\x0b\x32\".v1.DurableTaskCompleteMemoRequestH\x00\x42\t\n\x07message\"\x89\x01\n\x18\x44urableTaskErrorResponse\x12(\n\x03ref\x18\x01 \x01(\x0b\x32\x1b.v1.DurableEventLogEntryRef\x12,\n\nerror_type\x18\x02 \x01(\x0e\x32\x18.v1.DurableTaskErrorType\x12\x15\n\rerror_message\x18\x03 \x01(\t\"\x92\x04\n\x13\x44urableTaskResponse\x12@\n\x0fregister_worker\x18\x01 \x01(\x0b\x32%.v1.DurableTaskResponseRegisterWorkerH\x00\x12\x37\n\x08memo_ack\x18\x02 \x01(\x0b\x32#.v1.DurableTaskEventMemoAckResponseH\x00\x12\x46\n\x10trigger_runs_ack\x18\x03 \x01(\x0b\x32*.v1.DurableTaskEventTriggerRunsAckResponseH\x00\x12>\n\x0cwait_for_ack\x18\x04 \x01(\x0b\x32&.v1.DurableTaskEventWaitForAckResponseH\x00\x12H\n\x0f\x65ntry_completed\x18\x05 \x01(\x0b\x32-.v1.DurableTaskEventLogEntryCompletedResponseH\x00\x12-\n\x05\x65rror\x18\x06 \x01(\x0b\x32\x1c.v1.DurableTaskErrorResponseH\x00\x12:\n\x0c\x65viction_ack\x18\x07 \x01(\x0b\x32\".v1.DurableTaskEvictionAckResponseH\x00\x12\x38\n\x0cserver_evict\x18\x08 \x01(\x0b\x32 .v1.DurableTaskServerEvictNoticeH\x00\x42\t\n\x07message\"z\n\x1bRegisterDurableEventRequest\x12\x0f\n\x07task_id\x18\x01 \x01(\t\x12\x12\n\nsignal_key\x18\x02 \x01(\t\x12\x36\n\nconditions\x18\x03 \x01(\x0b\x32\".v1.DurableEventListenerConditions\"\x1e\n\x1cRegisterDurableEventResponse\"C\n\x1cListenForDurableEventRequest\x12\x0f\n\x07task_id\x18\x01 \x01(\t\x12\x12\n\nsignal_key\x18\x02 \x01(\t\"A\n\x0c\x44urableEvent\x12\x0f\n\x07task_id\x18\x01 \x01(\t\x12\x12\n\nsignal_key\x18\x02 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\x0c*k\n\x14\x44urableTaskErrorType\x12\'\n#DURABLE_TASK_ERROR_TYPE_UNSPECIFIED\x10\x00\x12*\n&DURABLE_TASK_ERROR_TYPE_NONDETERMINISM\x10\x01\x32\x84\x02\n\x0cV1Dispatcher\x12\x44\n\x0b\x44urableTask\x12\x16.v1.DurableTaskRequest\x1a\x17.v1.DurableTaskResponse\"\x00(\x01\x30\x01\x12[\n\x14RegisterDurableEvent\x12\x1f.v1.RegisterDurableEventRequest\x1a .v1.RegisterDurableEventResponse\"\x00\x12Q\n\x15ListenForDurableEvent\x12 .v1.ListenForDurableEventRequest\x1a\x10.v1.DurableEvent\"\x00(\x01\x30\x01\x42\x42Z@github.com/hatchet-dev/hatchet/internal/services/shared/proto/v1b\x06proto3"
12
12
 
13
13
  pool = ::Google::Protobuf::DescriptorPool.generated_pool
14
14
  pool.add_serialized_file(descriptor_data)
@@ -26,6 +26,7 @@ module V1
26
26
  DurableTaskEvictionAckResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("v1.DurableTaskEvictionAckResponse").msgclass
27
27
  DurableTaskAwaitedCompletedEntry = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("v1.DurableTaskAwaitedCompletedEntry").msgclass
28
28
  DurableTaskServerEvictNotice = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("v1.DurableTaskServerEvictNotice").msgclass
29
+ DurableTaskReceivedSatisfiedOrder = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("v1.DurableTaskReceivedSatisfiedOrder").msgclass
29
30
  DurableTaskWorkerStatusRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("v1.DurableTaskWorkerStatusRequest").msgclass
30
31
  DurableTaskCompleteMemoRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("v1.DurableTaskCompleteMemoRequest").msgclass
31
32
  DurableTaskMemoRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("v1.DurableTaskMemoRequest").msgclass
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hatchet
4
- VERSION = "0.11.0"
4
+ VERSION = "0.11.1"
5
5
  end
@@ -71,6 +71,7 @@ module Hatchet
71
71
  @waiting_since = {}
72
72
  # key -> [inserted_at, result] (rudimentary TTL cache)
73
73
  @buffered_completions = {}
74
+ @received_satisfied_orders = ReceivedSatisfiedOrders.new
74
75
 
75
76
  @running = false
76
77
  @start_mu = Mutex.new
@@ -259,11 +260,8 @@ module Hatchet
259
260
  @pending_event_acks.delete(k)&.close
260
261
  end
261
262
 
262
- @buffered_completions.each_key do |k|
263
- next unless k[0] == durable_task_external_id && k[1] <= invocation_count
264
-
265
- @buffered_completions.delete(k)
266
- end
263
+ @buffered_completions.delete_if { |k, _| k[0] == durable_task_external_id && k[1] <= invocation_count }
264
+ @received_satisfied_orders.delete_through(durable_task_external_id, invocation_count)
267
265
  end
268
266
  end
269
267
 
@@ -501,6 +499,7 @@ module Hatchet
501
499
  worker_status: ::V1::DurableTaskWorkerStatusRequest.new(
502
500
  worker_id: @worker_id,
503
501
  waiting_entries: waiting,
502
+ received_satisfied_orders: @mu.synchronize { @received_satisfied_orders.to_proto_for(keys_for_request) },
504
503
  ),
505
504
  )
506
505
  end
@@ -661,6 +660,7 @@ module Hatchet
661
660
  result = parse_entry_completed(completed)
662
661
 
663
662
  @mu.synchronize do
663
+ @received_satisfied_orders.record(completed)
664
664
  queue = @pending_callbacks.delete(key)
665
665
  if queue
666
666
  queue << [:ok, result]
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hatchet
4
+ module WorkerRuntime
5
+ # The highest satisfied_order received per (task_external_id, invocation_count). Reported in
6
+ # worker status requests so that after a reconnect the server resumes ordered delivery where
7
+ # this worker left off instead of waiting for orders it already sent.
8
+ #
9
+ # Not thread-safe; the durable event listener guards it with its own lock.
10
+ class ReceivedSatisfiedOrders
11
+ def initialize
12
+ @highest_by_invocation = {}
13
+ end
14
+
15
+ def record(completed)
16
+ return unless completed.has_satisfied_order?
17
+
18
+ invocation = [completed.ref.durable_task_external_id, completed.ref.invocation_count]
19
+ @highest_by_invocation[invocation] = [@highest_by_invocation.fetch(invocation, 0), completed.satisfied_order].max
20
+ end
21
+
22
+ # callback_keys are [task_external_id, invocation_count, branch_id, node_id]
23
+ def to_proto_for(callback_keys)
24
+ invocations = callback_keys.map { |(task_external_id, invocation_count, _, _)| [task_external_id, invocation_count] }
25
+
26
+ invocations.uniq.filter_map do |(durable_task_external_id, invocation_count)|
27
+ highest_received = @highest_by_invocation[[durable_task_external_id, invocation_count]]
28
+ next if highest_received.nil?
29
+
30
+ ::V1::DurableTaskReceivedSatisfiedOrder.new(
31
+ durable_task_external_id: durable_task_external_id,
32
+ invocation_count: invocation_count,
33
+ highest_received_satisfied_order: highest_received,
34
+ )
35
+ end
36
+ end
37
+
38
+ def delete_through(durable_task_external_id, invocation_count)
39
+ @highest_by_invocation.delete_if do |(task_external_id, recorded_invocation_count), _|
40
+ task_external_id == durable_task_external_id && recorded_invocation_count <= invocation_count
41
+ end
42
+ end
43
+
44
+ def clear
45
+ @highest_by_invocation.clear
46
+ end
47
+ end
48
+ end
49
+ end
@@ -467,9 +467,13 @@ module Hatchet
467
467
  end
468
468
 
469
469
  def cleanup_action(action_key)
470
- @contexts_mu.synchronize do
471
- @contexts.delete(action_key)
470
+ ctx = @contexts_mu.synchronize do
472
471
  @task_threads.delete(action_key)
472
+ @contexts.delete(action_key)
473
+ end
474
+
475
+ if @durable_event_listener && ctx.is_a?(DurableContext)
476
+ @durable_event_listener.cleanup_task_state(ctx.step_run_id, ctx.invocation_count || 1)
473
477
  end
474
478
 
475
479
  @eviction_manager&.unregister_run(action_key)
data/lib/hatchet-sdk.rb CHANGED
@@ -67,6 +67,7 @@ module Hatchet
67
67
  require_relative "hatchet/worker/workflow_run_listener"
68
68
  require_relative "hatchet/worker/durable_eviction/cache"
69
69
  require_relative "hatchet/worker/durable_eviction/manager"
70
+ require_relative "hatchet/worker/received_satisfied_orders"
70
71
  require_relative "hatchet/worker/durable_event_listener"
71
72
  require_relative "hatchet/worker/runner"
72
73
 
@@ -0,0 +1,11 @@
1
+ module Hatchet
2
+ module WorkerRuntime
3
+ class ReceivedSatisfiedOrders
4
+ def initialize: () -> void
5
+ def record: (untyped completed) -> void
6
+ def to_proto_for: (Array[[String, Integer, Integer, Integer]] callback_keys) -> Array[untyped]
7
+ def delete_through: (String durable_task_external_id, Integer invocation_count) -> void
8
+ def clear: () -> void
9
+ end
10
+ end
11
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hatchet-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - gabriel ruttner
@@ -544,6 +544,7 @@ files:
544
544
  - lib/hatchet/worker/durable_eviction/cache.rb
545
545
  - lib/hatchet/worker/durable_eviction/manager.rb
546
546
  - lib/hatchet/worker/health_check.rb
547
+ - lib/hatchet/worker/received_satisfied_orders.rb
547
548
  - lib/hatchet/worker/runner.rb
548
549
  - lib/hatchet/worker/workflow_run_listener.rb
549
550
  - lib/hatchet/worker_obj.rb
@@ -593,6 +594,7 @@ files:
593
594
  - sig/hatchet/worker/durable_eviction/cache.rbs
594
595
  - sig/hatchet/worker/durable_eviction/manager.rbs
595
596
  - sig/hatchet/worker/health_check.rbs
597
+ - sig/hatchet/worker/received_satisfied_orders.rbs
596
598
  - sig/hatchet/worker/runner.rbs
597
599
  - sig/hatchet/worker/workflow_run_listener.rbs
598
600
  - sig/hatchet/worker_obj.rbs