temporalio 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (232) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +175 -4
  3. data/bridge/Cargo.lock +44 -21
  4. data/bridge/Cargo.toml +1 -0
  5. data/bridge/sdk-core/Cargo.toml +1 -1
  6. data/bridge/sdk-core/README.md +1 -4
  7. data/bridge/sdk-core/client/Cargo.toml +1 -1
  8. data/bridge/sdk-core/client/src/lib.rs +12 -20
  9. data/bridge/sdk-core/client/src/raw.rs +9 -8
  10. data/bridge/sdk-core/client/src/retry.rs +100 -23
  11. data/bridge/sdk-core/core/Cargo.toml +7 -7
  12. data/bridge/sdk-core/core/benches/workflow_replay.rs +13 -10
  13. data/bridge/sdk-core/core/src/abstractions.rs +22 -22
  14. data/bridge/sdk-core/core/src/core_tests/activity_tasks.rs +146 -43
  15. data/bridge/sdk-core/core/src/core_tests/local_activities.rs +419 -9
  16. data/bridge/sdk-core/core/src/core_tests/queries.rs +247 -89
  17. data/bridge/sdk-core/core/src/core_tests/workers.rs +2 -2
  18. data/bridge/sdk-core/core/src/core_tests/workflow_cancels.rs +1 -1
  19. data/bridge/sdk-core/core/src/core_tests/workflow_tasks.rs +47 -27
  20. data/bridge/sdk-core/core/src/lib.rs +139 -32
  21. data/bridge/sdk-core/core/src/protosext/mod.rs +1 -1
  22. data/bridge/sdk-core/core/src/replay/mod.rs +185 -41
  23. data/bridge/sdk-core/core/src/telemetry/log_export.rs +190 -0
  24. data/bridge/sdk-core/core/src/telemetry/metrics.rs +184 -139
  25. data/bridge/sdk-core/core/src/telemetry/mod.rs +310 -315
  26. data/bridge/sdk-core/core/src/telemetry/prometheus_server.rs +4 -3
  27. data/bridge/sdk-core/core/src/test_help/mod.rs +23 -9
  28. data/bridge/sdk-core/core/src/worker/activities/local_activities.rs +12 -6
  29. data/bridge/sdk-core/core/src/worker/activities.rs +40 -23
  30. data/bridge/sdk-core/core/src/worker/client/mocks.rs +1 -1
  31. data/bridge/sdk-core/core/src/worker/client.rs +30 -4
  32. data/bridge/sdk-core/core/src/worker/mod.rs +23 -19
  33. data/bridge/sdk-core/core/src/worker/workflow/driven_workflow.rs +10 -19
  34. data/bridge/sdk-core/core/src/worker/workflow/history_update.rs +99 -25
  35. data/bridge/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +1 -5
  36. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -5
  37. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +1 -5
  38. data/bridge/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +3 -5
  39. data/bridge/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +1 -5
  40. data/bridge/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +2 -6
  41. data/bridge/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +1 -5
  42. data/bridge/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +24 -22
  43. data/bridge/sdk-core/core/src/worker/workflow/machines/mod.rs +12 -38
  44. data/bridge/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +178 -0
  45. data/bridge/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +1 -5
  46. data/bridge/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -5
  47. data/bridge/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +1 -5
  48. data/bridge/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +8 -2
  49. data/bridge/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +1 -5
  50. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +1 -1
  51. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +233 -217
  52. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +1 -6
  53. data/bridge/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +4 -4
  54. data/bridge/sdk-core/core/src/worker/workflow/managed_run.rs +13 -5
  55. data/bridge/sdk-core/core/src/worker/workflow/mod.rs +86 -29
  56. data/bridge/sdk-core/core/src/worker/workflow/wft_poller.rs +2 -2
  57. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream.rs +56 -11
  58. data/bridge/sdk-core/core-api/Cargo.toml +4 -3
  59. data/bridge/sdk-core/core-api/src/lib.rs +1 -43
  60. data/bridge/sdk-core/core-api/src/telemetry.rs +147 -0
  61. data/bridge/sdk-core/core-api/src/worker.rs +13 -0
  62. data/bridge/sdk-core/etc/deps.svg +115 -140
  63. data/bridge/sdk-core/etc/regen-depgraph.sh +5 -0
  64. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +1 -1
  65. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-23_history.bin +0 -0
  66. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-85_history.bin +0 -0
  67. data/bridge/sdk-core/protos/api_upstream/buf.yaml +0 -3
  68. data/bridge/sdk-core/protos/api_upstream/build/go.mod +7 -0
  69. data/bridge/sdk-core/protos/api_upstream/build/go.sum +5 -0
  70. data/bridge/sdk-core/protos/api_upstream/{temporal/api/update/v1/message.proto → build/tools.go} +6 -23
  71. data/bridge/sdk-core/protos/api_upstream/go.mod +6 -0
  72. data/bridge/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +12 -9
  73. data/bridge/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +20 -19
  74. data/bridge/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +2 -2
  75. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +3 -2
  76. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +4 -4
  77. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +3 -2
  78. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +5 -3
  79. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +23 -2
  80. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/{cluster.proto → interaction_type.proto} +10 -11
  81. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +2 -2
  82. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/query.proto +2 -2
  83. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +2 -2
  84. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +2 -2
  85. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +2 -2
  86. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +2 -13
  87. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +2 -2
  88. data/bridge/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +2 -2
  89. data/bridge/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +2 -2
  90. data/bridge/sdk-core/protos/api_upstream/temporal/api/filter/v1/message.proto +2 -2
  91. data/bridge/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +26 -19
  92. data/bridge/sdk-core/protos/api_upstream/temporal/api/interaction/v1/message.proto +87 -0
  93. data/bridge/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +2 -2
  94. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +21 -61
  95. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +2 -21
  96. data/bridge/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +2 -2
  97. data/bridge/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +2 -2
  98. data/bridge/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +110 -31
  99. data/bridge/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +4 -4
  100. data/bridge/sdk-core/protos/api_upstream/temporal/api/version/v1/message.proto +2 -2
  101. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +3 -2
  102. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +60 -16
  103. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +17 -3
  104. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +2 -0
  105. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +8 -1
  106. data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +2 -2
  107. data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +2 -2
  108. data/bridge/sdk-core/sdk/Cargo.toml +2 -2
  109. data/bridge/sdk-core/sdk/src/interceptors.rs +36 -3
  110. data/bridge/sdk-core/sdk/src/lib.rs +7 -5
  111. data/bridge/sdk-core/sdk/src/workflow_context.rs +13 -2
  112. data/bridge/sdk-core/sdk/src/workflow_future.rs +3 -7
  113. data/bridge/sdk-core/sdk-core-protos/Cargo.toml +1 -1
  114. data/bridge/sdk-core/sdk-core-protos/build.rs +0 -1
  115. data/bridge/sdk-core/sdk-core-protos/src/history_builder.rs +65 -18
  116. data/bridge/sdk-core/sdk-core-protos/src/history_info.rs +22 -22
  117. data/bridge/sdk-core/sdk-core-protos/src/lib.rs +104 -44
  118. data/bridge/sdk-core/test-utils/Cargo.toml +2 -1
  119. data/bridge/sdk-core/test-utils/src/lib.rs +81 -29
  120. data/bridge/sdk-core/tests/integ_tests/heartbeat_tests.rs +5 -2
  121. data/bridge/sdk-core/tests/integ_tests/metrics_tests.rs +37 -0
  122. data/bridge/sdk-core/tests/integ_tests/polling_tests.rs +0 -13
  123. data/bridge/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +167 -13
  124. data/bridge/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +53 -0
  125. data/bridge/sdk-core/tests/integ_tests/workflow_tests/replay.rs +106 -20
  126. data/bridge/sdk-core/tests/integ_tests/workflow_tests.rs +18 -8
  127. data/bridge/sdk-core/tests/main.rs +6 -4
  128. data/bridge/src/connection.rs +81 -62
  129. data/bridge/src/lib.rs +92 -33
  130. data/bridge/src/runtime.rs +9 -2
  131. data/bridge/src/worker.rs +53 -2
  132. data/lib/bridge.so +0 -0
  133. data/lib/gen/temporal/api/batch/v1/message_pb.rb +8 -6
  134. data/lib/gen/temporal/api/command/v1/message_pb.rb +17 -9
  135. data/lib/gen/temporal/api/common/v1/message_pb.rb +1 -1
  136. data/lib/gen/temporal/api/enums/v1/batch_operation_pb.rb +2 -1
  137. data/lib/gen/temporal/api/enums/v1/command_type_pb.rb +3 -1
  138. data/lib/gen/temporal/api/enums/v1/common_pb.rb +2 -1
  139. data/lib/gen/temporal/api/enums/v1/event_type_pb.rb +3 -2
  140. data/lib/gen/temporal/api/enums/v1/failed_cause_pb.rb +7 -1
  141. data/lib/gen/temporal/api/enums/v1/interaction_type_pb.rb +25 -0
  142. data/lib/gen/temporal/api/enums/v1/namespace_pb.rb +1 -1
  143. data/lib/gen/temporal/api/enums/v1/query_pb.rb +1 -1
  144. data/lib/gen/temporal/api/enums/v1/reset_pb.rb +1 -1
  145. data/lib/gen/temporal/api/enums/v1/schedule_pb.rb +1 -1
  146. data/lib/gen/temporal/api/enums/v1/task_queue_pb.rb +1 -1
  147. data/lib/gen/temporal/api/enums/v1/update_pb.rb +1 -6
  148. data/lib/gen/temporal/api/enums/v1/workflow_pb.rb +1 -1
  149. data/lib/gen/temporal/api/errordetails/v1/message_pb.rb +1 -1
  150. data/lib/gen/temporal/api/failure/v1/message_pb.rb +1 -1
  151. data/lib/gen/temporal/api/filter/v1/message_pb.rb +1 -1
  152. data/lib/gen/temporal/api/history/v1/message_pb.rb +19 -18
  153. data/lib/gen/temporal/api/interaction/v1/message_pb.rb +49 -0
  154. data/lib/gen/temporal/api/namespace/v1/message_pb.rb +1 -1
  155. data/lib/gen/temporal/api/operatorservice/v1/request_response_pb.rb +11 -51
  156. data/lib/gen/temporal/api/operatorservice/v1/service_pb.rb +1 -1
  157. data/lib/gen/temporal/api/query/v1/message_pb.rb +1 -1
  158. data/lib/gen/temporal/api/replication/v1/message_pb.rb +1 -1
  159. data/lib/gen/temporal/api/schedule/v1/message_pb.rb +22 -1
  160. data/lib/gen/temporal/api/taskqueue/v1/message_pb.rb +2 -2
  161. data/lib/gen/temporal/api/version/v1/message_pb.rb +1 -1
  162. data/lib/gen/temporal/api/workflow/v1/message_pb.rb +2 -1
  163. data/lib/gen/temporal/api/workflowservice/v1/request_response_pb.rb +27 -10
  164. data/lib/gen/temporal/api/workflowservice/v1/service_pb.rb +1 -1
  165. data/lib/gen/temporal/sdk/core/workflow_activation/workflow_activation_pb.rb +1 -0
  166. data/lib/gen/temporal/sdk/core/workflow_commands/workflow_commands_pb.rb +5 -1
  167. data/lib/temporalio/activity/context.rb +97 -0
  168. data/lib/temporalio/activity/info.rb +67 -0
  169. data/lib/temporalio/activity.rb +85 -0
  170. data/lib/temporalio/bridge/error.rb +8 -0
  171. data/lib/temporalio/bridge.rb +14 -0
  172. data/lib/{temporal → temporalio}/client/implementation.rb +49 -48
  173. data/lib/{temporal → temporalio}/client/workflow_handle.rb +35 -35
  174. data/lib/{temporal → temporalio}/client.rb +19 -32
  175. data/lib/{temporal → temporalio}/connection.rb +238 -223
  176. data/lib/{temporal → temporalio}/data_converter.rb +76 -35
  177. data/lib/{temporal → temporalio}/error/failure.rb +6 -6
  178. data/lib/{temporal → temporalio}/error/workflow_failure.rb +4 -2
  179. data/lib/{temporal → temporalio}/errors.rb +19 -1
  180. data/lib/{temporal → temporalio}/failure_converter/base.rb +5 -5
  181. data/lib/{temporal → temporalio}/failure_converter/basic.rb +58 -52
  182. data/lib/temporalio/failure_converter.rb +7 -0
  183. data/lib/{temporal → temporalio}/interceptor/chain.rb +2 -1
  184. data/lib/{temporal → temporalio}/interceptor/client.rb +22 -1
  185. data/lib/{temporal → temporalio}/payload_codec/base.rb +5 -5
  186. data/lib/{temporal → temporalio}/payload_converter/base.rb +3 -3
  187. data/lib/{temporal → temporalio}/payload_converter/bytes.rb +4 -3
  188. data/lib/{temporal → temporalio}/payload_converter/composite.rb +7 -5
  189. data/lib/{temporal → temporalio}/payload_converter/encoding_base.rb +4 -4
  190. data/lib/{temporal → temporalio}/payload_converter/json.rb +4 -3
  191. data/lib/{temporal → temporalio}/payload_converter/nil.rb +4 -3
  192. data/lib/temporalio/payload_converter.rb +14 -0
  193. data/lib/{temporal → temporalio}/retry_policy.rb +4 -4
  194. data/lib/{temporal → temporalio}/retry_state.rb +1 -1
  195. data/lib/temporalio/runtime.rb +25 -0
  196. data/lib/{temporal → temporalio}/timeout_type.rb +2 -2
  197. data/lib/temporalio/version.rb +3 -0
  198. data/lib/temporalio/worker/activity_runner.rb +92 -0
  199. data/lib/temporalio/worker/activity_worker.rb +138 -0
  200. data/lib/temporalio/worker/reactor.rb +46 -0
  201. data/lib/temporalio/worker/runner.rb +63 -0
  202. data/lib/temporalio/worker/sync_worker.rb +88 -0
  203. data/lib/temporalio/worker/thread_pool_executor.rb +51 -0
  204. data/lib/temporalio/worker.rb +198 -0
  205. data/lib/{temporal → temporalio}/workflow/execution_info.rb +4 -4
  206. data/lib/{temporal → temporalio}/workflow/execution_status.rb +1 -1
  207. data/lib/{temporal → temporalio}/workflow/id_reuse_policy.rb +6 -6
  208. data/lib/{temporal → temporalio}/workflow/query_reject_condition.rb +5 -5
  209. data/lib/temporalio.rb +12 -3
  210. data/temporalio.gemspec +7 -3
  211. metadata +79 -56
  212. data/bridge/sdk-core/bridge-ffi/Cargo.toml +0 -24
  213. data/bridge/sdk-core/bridge-ffi/LICENSE.txt +0 -23
  214. data/bridge/sdk-core/bridge-ffi/build.rs +0 -25
  215. data/bridge/sdk-core/bridge-ffi/include/sdk-core-bridge.h +0 -249
  216. data/bridge/sdk-core/bridge-ffi/src/lib.rs +0 -825
  217. data/bridge/sdk-core/bridge-ffi/src/wrappers.rs +0 -211
  218. data/bridge/sdk-core/core/src/log_export.rs +0 -62
  219. data/bridge/sdk-core/core/src/worker/workflow/machines/mutable_side_effect_state_machine.rs +0 -127
  220. data/bridge/sdk-core/core/src/worker/workflow/machines/side_effect_state_machine.rs +0 -71
  221. data/bridge/sdk-core/protos/api_upstream/temporal/api/cluster/v1/message.proto +0 -83
  222. data/bridge/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +0 -210
  223. data/bridge/sdk-core/sdk/src/conversions.rs +0 -8
  224. data/lib/gen/temporal/api/cluster/v1/message_pb.rb +0 -67
  225. data/lib/gen/temporal/api/enums/v1/cluster_pb.rb +0 -26
  226. data/lib/gen/temporal/api/update/v1/message_pb.rb +0 -26
  227. data/lib/temporal/bridge.rb +0 -14
  228. data/lib/temporal/failure_converter.rb +0 -8
  229. data/lib/temporal/payload_converter.rb +0 -14
  230. data/lib/temporal/runtime.rb +0 -22
  231. data/lib/temporal/version.rb +0 -3
  232. data/lib/temporal.rb +0 -8
@@ -204,20 +204,20 @@ impl HistoryUpdate {
204
204
  &mut self,
205
205
  from_wft_started_id: i64,
206
206
  ) -> Result<Vec<HistoryEvent>, tonic::Status> {
207
- let (next_wft_events, maybe_bonus_event) = self
207
+ let (next_wft_events, maybe_bonus_events) = self
208
208
  .take_next_wft_sequence_impl(from_wft_started_id)
209
209
  .await?;
210
- if let Some(be) = maybe_bonus_event {
211
- self.buffered.push_back(be);
210
+ if !maybe_bonus_events.is_empty() {
211
+ self.buffered.extend(maybe_bonus_events);
212
212
  }
213
213
 
214
214
  if let Some(last_event_id) = next_wft_events.last().map(|he| he.event_id) {
215
215
  // Always attempt to fetch the *next* WFT sequence as well, to buffer it for lookahead
216
- let (buffer_these_events, maybe_bonus_event) =
216
+ let (buffer_these_events, maybe_bonus_events) =
217
217
  self.take_next_wft_sequence_impl(last_event_id).await?;
218
218
  self.buffered.extend(buffer_these_events);
219
- if let Some(be) = maybe_bonus_event {
220
- self.buffered.push_back(be);
219
+ if !maybe_bonus_events.is_empty() {
220
+ self.buffered.extend(maybe_bonus_events);
221
221
  }
222
222
  }
223
223
 
@@ -232,44 +232,61 @@ impl HistoryUpdate {
232
232
  self.buffered.iter()
233
233
  }
234
234
 
235
+ /// Retrieve the next WFT sequence, first from buffered events and then from the real stream.
236
+ /// Returns (events up to the next logical wft sequence, extra events that were taken but
237
+ /// should be re-appended to the end of the buffer).
235
238
  async fn take_next_wft_sequence_impl(
236
239
  &mut self,
237
240
  from_event_id: i64,
238
- ) -> Result<(Vec<HistoryEvent>, Option<HistoryEvent>), tonic::Status> {
241
+ ) -> Result<(Vec<HistoryEvent>, Vec<HistoryEvent>), tonic::Status> {
239
242
  let mut events_to_next_wft_started: Vec<HistoryEvent> = vec![];
240
243
 
241
244
  // This flag tracks if, while determining events to be returned, we have seen the next
242
245
  // logically significant WFT started event which follows the one that was passed in as a
243
- // parameter. If a WFT fails or times out, it is not significant. So we will stop returning
244
- // events (exclusive) as soon as we see an event following a WFT started that is *not*
245
- // failed or timed out.
246
- let mut saw_next_wft = false;
246
+ // parameter. If a WFT fails, times out, or is devoid of commands (ie: a heartbeat) it is
247
+ // not significant. So we will stop returning events (exclusive) as soon as we see an event
248
+ // following a WFT started that is *not* failed, timed out, or completed with a command.
249
+ let mut next_wft_state = NextWftState::NotSeen;
247
250
  let mut should_pop = |e: &HistoryEvent| {
248
251
  if e.event_id <= from_event_id {
249
252
  return true;
250
- } else if e.event_type == EventType::WorkflowTaskStarted as i32 {
251
- saw_next_wft = true;
253
+ } else if e.event_type() == EventType::WorkflowTaskStarted {
254
+ next_wft_state = NextWftState::Seen;
252
255
  return true;
253
256
  }
254
257
 
255
- if saw_next_wft {
256
- // Must ignore failures and timeouts
257
- if e.event_type == EventType::WorkflowTaskFailed as i32
258
- || e.event_type == EventType::WorkflowTaskTimedOut as i32
259
- {
260
- saw_next_wft = false;
261
- return true;
258
+ match next_wft_state {
259
+ NextWftState::Seen => {
260
+ // Must ignore failures and timeouts
261
+ if e.event_type() == EventType::WorkflowTaskFailed
262
+ || e.event_type() == EventType::WorkflowTaskTimedOut
263
+ {
264
+ next_wft_state = NextWftState::NotSeen;
265
+ return true;
266
+ } else if e.event_type() == EventType::WorkflowTaskCompleted {
267
+ next_wft_state = NextWftState::SeenCompleted;
268
+ return true;
269
+ }
270
+ false
271
+ }
272
+ NextWftState::SeenCompleted => {
273
+ // If we've seen the WFT be completed, and this event is another scheduled, then
274
+ // this was an empty heartbeat we should ignore.
275
+ if e.event_type() == EventType::WorkflowTaskScheduled {
276
+ next_wft_state = NextWftState::NotSeen;
277
+ return true;
278
+ }
279
+ // Otherwise, we're done here
280
+ false
262
281
  }
263
- return false;
282
+ NextWftState::NotSeen => true,
264
283
  }
265
-
266
- true
267
284
  };
268
285
 
269
286
  // Fetch events from the buffer first, then from the network
270
287
  let mut event_q = stream::iter(self.buffered.drain(..).map(Ok)).chain(&mut self.events);
271
288
 
272
- let mut extra_e = None;
289
+ let mut extra_e = vec![];
273
290
  let mut last_seen_id = None;
274
291
  while let Some(e) = event_q.next().await {
275
292
  let e = e?;
@@ -288,7 +305,17 @@ impl HistoryUpdate {
288
305
  // command on completion), where we may need to skip events we already handled.
289
306
  if e.event_id > from_event_id {
290
307
  if !should_pop(&e) {
291
- extra_e = Some(e);
308
+ if next_wft_state == NextWftState::SeenCompleted {
309
+ // We have seen the wft completed event, but decided to exit. We don't
310
+ // want to return that event as part of this sequence, so include it for
311
+ // re-buffering along with the event we're currently on.
312
+ extra_e.push(
313
+ events_to_next_wft_started
314
+ .pop()
315
+ .expect("There is an element here by definition"),
316
+ );
317
+ }
318
+ extra_e.push(e);
292
319
  break;
293
320
  }
294
321
  events_to_next_wft_started.push(e);
@@ -299,6 +326,13 @@ impl HistoryUpdate {
299
326
  }
300
327
  }
301
328
 
329
+ #[derive(Eq, PartialEq, Debug)]
330
+ enum NextWftState {
331
+ NotSeen,
332
+ Seen,
333
+ SeenCompleted,
334
+ }
335
+
302
336
  impl From<HistoryInfo> for HistoryUpdate {
303
337
  fn from(v: HistoryInfo) -> Self {
304
338
  Self::new_from_events(v.events().to_vec(), v.previous_started_event_id())
@@ -366,6 +400,46 @@ pub mod tests {
366
400
  assert_eq!(seq_2.last().unwrap().event_id, 8);
367
401
  }
368
402
 
403
+ #[tokio::test]
404
+ async fn history_ends_abruptly() {
405
+ let mut timer_hist = canned_histories::single_timer("t");
406
+ timer_hist.add_workflow_execution_terminated();
407
+ let mut update = timer_hist.as_history_update();
408
+ let seq_2 = update.take_next_wft_sequence(3).await.unwrap();
409
+ assert_eq!(seq_2.len(), 5);
410
+ assert_eq!(seq_2.last().unwrap().event_id, 8);
411
+ }
412
+
413
+ #[tokio::test]
414
+ async fn heartbeats_skipped() {
415
+ let mut t = TestHistoryBuilder::default();
416
+ t.add_by_type(EventType::WorkflowExecutionStarted);
417
+ t.add_full_wf_task();
418
+ t.add_full_wf_task();
419
+ t.add_get_event_id(EventType::TimerStarted, None);
420
+ t.add_full_wf_task();
421
+ t.add_full_wf_task();
422
+ t.add_full_wf_task();
423
+ t.add_full_wf_task();
424
+ t.add_get_event_id(EventType::TimerStarted, None);
425
+ t.add_full_wf_task();
426
+ t.add_we_signaled("whee", vec![]);
427
+ t.add_full_wf_task();
428
+ t.add_workflow_execution_completed();
429
+
430
+ let mut update = t.as_history_update();
431
+ let seq = update.take_next_wft_sequence(0).await.unwrap();
432
+ assert_eq!(seq.len(), 6);
433
+ let seq = update.take_next_wft_sequence(6).await.unwrap();
434
+ assert_eq!(seq.len(), 13);
435
+ let seq = update.take_next_wft_sequence(19).await.unwrap();
436
+ assert_eq!(seq.len(), 4);
437
+ let seq = update.take_next_wft_sequence(23).await.unwrap();
438
+ assert_eq!(seq.len(), 4);
439
+ let seq = update.take_next_wft_sequence(27).await.unwrap();
440
+ assert_eq!(seq.len(), 2);
441
+ }
442
+
369
443
  #[tokio::test]
370
444
  async fn paginator_fetches_new_pages() {
371
445
  // Note that this test triggers the "event ids that went backwards" error, acceptably.
@@ -1,7 +1,7 @@
1
1
  #![allow(clippy::large_enum_variant)]
2
2
 
3
3
  use super::{
4
- workflow_machines::MachineResponse, Cancellable, EventInfo, MachineKind, NewMachineWithCommand,
4
+ workflow_machines::MachineResponse, Cancellable, EventInfo, NewMachineWithCommand,
5
5
  OnEventWrapper, WFMachinesAdapter, WFMachinesError,
6
6
  };
7
7
  use rustfsm::{fsm, MachineError, StateMachine, TransitionResult};
@@ -288,10 +288,6 @@ impl WFMachinesAdapter for ActivityMachine {
288
288
  | EventType::ActivityTaskCanceled
289
289
  )
290
290
  }
291
-
292
- fn kind(&self) -> MachineKind {
293
- MachineKind::Activity
294
- }
295
291
  }
296
292
 
297
293
  impl TryFrom<CommandType> for ActivityMachineEvents {
@@ -1,5 +1,5 @@
1
1
  use super::{
2
- workflow_machines::MachineResponse, Cancellable, EventInfo, MachineKind, NewMachineWithCommand,
2
+ workflow_machines::MachineResponse, Cancellable, EventInfo, NewMachineWithCommand,
3
3
  OnEventWrapper, WFMachinesAdapter, WFMachinesError,
4
4
  };
5
5
  use rustfsm::{fsm, TransitionResult};
@@ -222,10 +222,6 @@ impl WFMachinesAdapter for CancelExternalMachine {
222
222
  | EventType::RequestCancelExternalWorkflowExecutionInitiated
223
223
  )
224
224
  }
225
-
226
- fn kind(&self) -> MachineKind {
227
- MachineKind::CancelExternalWorkflow
228
- }
229
225
  }
230
226
 
231
227
  impl Cancellable for CancelExternalMachine {}
@@ -1,5 +1,5 @@
1
1
  use super::{
2
- workflow_machines::MachineResponse, Cancellable, EventInfo, HistoryEvent, MachineKind,
2
+ workflow_machines::MachineResponse, Cancellable, EventInfo, HistoryEvent,
3
3
  NewMachineWithCommand, OnEventWrapper, WFMachinesAdapter, WFMachinesError,
4
4
  };
5
5
  use rustfsm::{fsm, TransitionResult};
@@ -111,10 +111,6 @@ impl WFMachinesAdapter for CancelWorkflowMachine {
111
111
  fn matches_event(&self, event: &HistoryEvent) -> bool {
112
112
  event.event_type() == EventType::WorkflowExecutionCanceled
113
113
  }
114
-
115
- fn kind(&self) -> MachineKind {
116
- MachineKind::CancelWorkflow
117
- }
118
114
  }
119
115
 
120
116
  impl Cancellable for CancelWorkflowMachine {}
@@ -1,5 +1,5 @@
1
1
  use super::{
2
- workflow_machines::MachineResponse, Cancellable, EventInfo, MachineKind, NewMachineWithCommand,
2
+ workflow_machines::MachineResponse, Cancellable, EventInfo, NewMachineWithCommand,
3
3
  OnEventWrapper, WFMachinesAdapter, WFMachinesError,
4
4
  };
5
5
  use rustfsm::{fsm, MachineError, TransitionResult};
@@ -71,6 +71,7 @@ fsm! {
71
71
  // Ignore any spurious cancellations after resolution
72
72
  Cancelled --(Cancel) --> Cancelled;
73
73
  Failed --(Cancel) --> Failed;
74
+ StartFailed --(Cancel) --> StartFailed;
74
75
  TimedOut --(Cancel) --> TimedOut;
75
76
  Completed --(Cancel) --> Completed;
76
77
  }
@@ -584,10 +585,6 @@ impl WFMachinesAdapter for ChildWorkflowMachine {
584
585
  | EventType::ChildWorkflowExecutionCanceled
585
586
  )
586
587
  }
587
-
588
- fn kind(&self) -> MachineKind {
589
- MachineKind::ChildWorkflow
590
- }
591
588
  }
592
589
 
593
590
  impl TryFrom<CommandType> for ChildWorkflowMachineEvents {
@@ -845,6 +842,7 @@ mod test {
845
842
  for state in [
846
843
  ChildWorkflowMachineState::Cancelled(Cancelled {}),
847
844
  Failed {}.into(),
845
+ StartFailed {}.into(),
848
846
  TimedOut {}.into(),
849
847
  Completed {}.into(),
850
848
  ] {
@@ -1,5 +1,5 @@
1
1
  use super::{
2
- workflow_machines::MachineResponse, Cancellable, EventInfo, MachineKind, NewMachineWithCommand,
2
+ workflow_machines::MachineResponse, Cancellable, EventInfo, NewMachineWithCommand,
3
3
  OnEventWrapper, WFMachinesAdapter, WFMachinesError,
4
4
  };
5
5
  use rustfsm::{fsm, TransitionResult};
@@ -131,10 +131,6 @@ impl WFMachinesAdapter for CompleteWorkflowMachine {
131
131
  fn matches_event(&self, event: &HistoryEvent) -> bool {
132
132
  event.event_type() == EventType::WorkflowExecutionCompleted
133
133
  }
134
-
135
- fn kind(&self) -> MachineKind {
136
- MachineKind::CompleteWorkflow
137
- }
138
134
  }
139
135
 
140
136
  impl Cancellable for CompleteWorkflowMachine {}
@@ -1,6 +1,6 @@
1
1
  use super::{
2
- Cancellable, EventInfo, HistoryEvent, MachineKind, MachineResponse, NewMachineWithCommand,
3
- OnEventWrapper, WFMachinesAdapter, WFMachinesError,
2
+ Cancellable, EventInfo, HistoryEvent, MachineResponse, NewMachineWithCommand, OnEventWrapper,
3
+ WFMachinesAdapter, WFMachinesError,
4
4
  };
5
5
  use rustfsm::{fsm, TransitionResult};
6
6
  use std::convert::TryFrom;
@@ -110,10 +110,6 @@ impl WFMachinesAdapter for ContinueAsNewWorkflowMachine {
110
110
  fn matches_event(&self, event: &HistoryEvent) -> bool {
111
111
  event.event_type() == EventType::WorkflowExecutionContinuedAsNew
112
112
  }
113
-
114
- fn kind(&self) -> MachineKind {
115
- MachineKind::ContinueAsNewWorkflow
116
- }
117
113
  }
118
114
 
119
115
  impl Cancellable for ContinueAsNewWorkflowMachine {}
@@ -1,5 +1,5 @@
1
1
  use super::{
2
- workflow_machines::MachineResponse, Cancellable, EventInfo, MachineKind, NewMachineWithCommand,
2
+ workflow_machines::MachineResponse, Cancellable, EventInfo, NewMachineWithCommand,
3
3
  OnEventWrapper, WFMachinesAdapter, WFMachinesError,
4
4
  };
5
5
  use rustfsm::{fsm, TransitionResult};
@@ -124,10 +124,6 @@ impl WFMachinesAdapter for FailWorkflowMachine {
124
124
  fn matches_event(&self, event: &HistoryEvent) -> bool {
125
125
  event.event_type() == EventType::WorkflowExecutionFailed
126
126
  }
127
-
128
- fn kind(&self) -> MachineKind {
129
- MachineKind::FailWorkflow
130
- }
131
127
  }
132
128
 
133
129
  impl Cancellable for FailWorkflowMachine {}
@@ -1,10 +1,10 @@
1
1
  use super::{
2
- workflow_machines::MachineResponse, Cancellable, EventInfo, MachineKind, OnEventWrapper,
3
- WFMachinesAdapter, WFMachinesError,
2
+ workflow_machines::MachineResponse, Cancellable, EventInfo, OnEventWrapper, WFMachinesAdapter,
3
+ WFMachinesError,
4
4
  };
5
5
  use crate::{
6
6
  protosext::{CompleteLocalActivityData, HistoryEventExt, ValidScheduleLA},
7
- worker::LocalActivityExecutionResult,
7
+ worker::{workflow::OutgoingJob, LocalActivityExecutionResult},
8
8
  };
9
9
  use rustfsm::{fsm, MachineError, StateMachine, TransitionResult};
10
10
  use std::{
@@ -79,6 +79,10 @@ fsm! {
79
79
  // even though we already resolved the activity.
80
80
  WaitingMarkerEventPreResolved --(MarkerRecorded(CompleteLocalActivityData),
81
81
  shared on_marker_recorded) --> MarkerCommandRecorded;
82
+ // Ignore cancellations when waiting for the marker after being pre-resolved
83
+ WaitingMarkerEventPreResolved --(Cancel) --> WaitingMarkerEventPreResolved;
84
+ WaitingMarkerEventPreResolved --(NoWaitCancel(ActivityCancellationType))
85
+ --> WaitingMarkerEventPreResolved;
82
86
 
83
87
  // Ignore cancellation in final state
84
88
  MarkerCommandRecorded --(Cancel, on_cancel_requested) --> MarkerCommandRecorded;
@@ -131,7 +135,7 @@ impl From<CompleteLocalActivityData> for ResolveDat {
131
135
  /// must resolve before we send a record marker command. A [MachineResponse] may be produced,
132
136
  /// to queue the LA for execution if it needs to be.
133
137
  pub(super) fn new_local_activity(
134
- attrs: ValidScheduleLA,
138
+ mut attrs: ValidScheduleLA,
135
139
  replaying_when_invoked: bool,
136
140
  maybe_pre_resolved: Option<ResolveDat>,
137
141
  wf_time: Option<SystemTime>,
@@ -151,6 +155,11 @@ pub(super) fn new_local_activity(
151
155
  Executing {}.into()
152
156
  };
153
157
 
158
+ // If the scheduled LA doesn't already have an "original" schedule time, assign one.
159
+ attrs
160
+ .original_schedule_time
161
+ .get_or_insert(SystemTime::now());
162
+
154
163
  let mut machine = LocalActivityMachine {
155
164
  state: initial_state,
156
165
  shared_state: SharedState {
@@ -286,6 +295,7 @@ impl SharedState {
286
295
  }
287
296
  }
288
297
 
298
+ #[allow(clippy::large_enum_variant)]
289
299
  #[derive(Debug, derive_more::Display)]
290
300
  pub(super) enum LocalActivityCommand {
291
301
  RequestActivityExecution(ValidScheduleLA),
@@ -643,13 +653,14 @@ impl WFMachinesAdapter for LocalActivityMachine {
643
653
  result.into()
644
654
  };
645
655
  let mut responses = vec![
646
- MachineResponse::PushWFJob(
647
- ResolveActivity {
656
+ MachineResponse::PushWFJob(OutgoingJob {
657
+ variant: ResolveActivity {
648
658
  seq: self.shared_state.attrs.seq,
649
659
  result: Some(resolution),
650
660
  }
651
661
  .into(),
652
- ),
662
+ is_la_resolution: true,
663
+ }),
653
664
  MachineResponse::UpdateWFTime(complete_time),
654
665
  ];
655
666
 
@@ -708,10 +719,6 @@ impl WFMachinesAdapter for LocalActivityMachine {
708
719
  fn matches_event(&self, event: &HistoryEvent) -> bool {
709
720
  event.is_local_activity_marker()
710
721
  }
711
-
712
- fn kind(&self) -> MachineKind {
713
- MachineKind::LocalActivity
714
- }
715
722
  }
716
723
 
717
724
  impl TryFrom<CommandType> for LocalActivityMachineEvents {
@@ -940,7 +947,7 @@ mod tests {
940
947
  let commands = wfm.get_server_commands().commands;
941
948
  assert_eq!(commands.len(), 0);
942
949
  let ready_to_execute_las = wfm.drain_queued_local_activities();
943
- let num_queued = if !replay { 1 } else { 0 };
950
+ let num_queued = usize::from(!replay);
944
951
  assert_eq!(ready_to_execute_las.len(), num_queued);
945
952
 
946
953
  if !replay {
@@ -1116,7 +1123,7 @@ mod tests {
1116
1123
  let commands = wfm.get_server_commands().commands;
1117
1124
  assert_eq!(commands.len(), 0);
1118
1125
  let ready_to_execute_las = wfm.drain_queued_local_activities();
1119
- let num_queued = if !replay { 1 } else { 0 };
1126
+ let num_queued = usize::from(!replay);
1120
1127
  assert_eq!(ready_to_execute_las.len(), num_queued);
1121
1128
 
1122
1129
  if !replay {
@@ -1158,7 +1165,7 @@ mod tests {
1158
1165
  }]
1159
1166
  );
1160
1167
  let ready_to_execute_las = wfm.drain_queued_local_activities();
1161
- let num_queued = if !replay { 1 } else { 0 };
1168
+ let num_queued = usize::from(!replay);
1162
1169
  assert_eq!(ready_to_execute_las.len(), num_queued);
1163
1170
  if !replay {
1164
1171
  wfm.complete_local_activity(2, ActivityExecutionResult::ok(b"Resolved".into()))
@@ -1210,17 +1217,12 @@ mod tests {
1210
1217
  let histinfo = t.get_full_history_info().unwrap().into();
1211
1218
  let mut wfm = ManagedWFFunc::new_from_update(histinfo, func, vec![]);
1212
1219
 
1213
- // First activation will request to run the LA, but it will *not* be queued for execution
1214
- // yet as we're still replaying.
1220
+ // First activation will request to run the LA since the heartbeat & wft failure are skipped
1221
+ // over
1215
1222
  wfm.get_next_activation().await.unwrap();
1216
1223
  let commands = wfm.get_server_commands().commands;
1217
1224
  assert_eq!(commands.len(), 0);
1218
1225
  let ready_to_execute_las = wfm.drain_queued_local_activities();
1219
- assert_eq!(ready_to_execute_las.len(), 0);
1220
-
1221
- // On the *next* activation, we are no longer replaying and the activity should be queued
1222
- wfm.get_next_activation().await.unwrap();
1223
- let ready_to_execute_las = wfm.drain_queued_local_activities();
1224
1226
  assert_eq!(ready_to_execute_las.len(), 1);
1225
1227
  // We can happily complete it now
1226
1228
  wfm.complete_local_activity(1, ActivityExecutionResult::ok(b"hi".into()))
@@ -1383,7 +1385,7 @@ mod tests {
1383
1385
  assert_eq!(commands.len(), 1);
1384
1386
  assert_eq!(commands[0].command_type, CommandType::StartTimer as i32);
1385
1387
  let ready_to_execute_las = wfm.drain_queued_local_activities();
1386
- let num_queued = if !replay { 1 } else { 0 };
1388
+ let num_queued = usize::from(!replay);
1387
1389
  assert_eq!(ready_to_execute_las.len(), num_queued);
1388
1390
 
1389
1391
  // Next activation timer fires and activity cancel will be requested
@@ -8,11 +8,8 @@ mod complete_workflow_state_machine;
8
8
  mod continue_as_new_workflow_state_machine;
9
9
  mod fail_workflow_state_machine;
10
10
  mod local_activity_state_machine;
11
- #[allow(unused)]
12
- mod mutable_side_effect_state_machine;
11
+ mod modify_workflow_properties_state_machine;
13
12
  mod patch_state_machine;
14
- #[allow(unused)]
15
- mod side_effect_state_machine;
16
13
  mod signal_external_state_machine;
17
14
  mod timer_state_machine;
18
15
  mod upsert_search_attributes_state_machine;
@@ -32,8 +29,8 @@ use complete_workflow_state_machine::CompleteWorkflowMachine;
32
29
  use continue_as_new_workflow_state_machine::ContinueAsNewWorkflowMachine;
33
30
  use fail_workflow_state_machine::FailWorkflowMachine;
34
31
  use local_activity_state_machine::LocalActivityMachine;
32
+ use modify_workflow_properties_state_machine::ModifyWorkflowPropertiesMachine;
35
33
  use patch_state_machine::PatchMachine;
36
- use prost::alloc::fmt::Formatter;
37
34
  use rustfsm::{MachineError, StateMachine};
38
35
  use signal_external_state_machine::SignalExternalMachine;
39
36
  use std::{
@@ -53,23 +50,6 @@ use workflow_task_state_machine::WorkflowTaskMachine;
53
50
  #[cfg(test)]
54
51
  use transition_coverage::add_coverage;
55
52
 
56
- #[derive(Copy, Clone, Debug, derive_more::Display, Eq, PartialEq)]
57
- enum MachineKind {
58
- Activity,
59
- CancelWorkflow,
60
- ChildWorkflow,
61
- CompleteWorkflow,
62
- ContinueAsNewWorkflow,
63
- FailWorkflow,
64
- Timer,
65
- Patch,
66
- WorkflowTask,
67
- SignalExternalWorkflow,
68
- CancelExternalWorkflow,
69
- LocalActivity,
70
- UpsertSearchAttributes,
71
- }
72
-
73
53
  #[enum_dispatch::enum_dispatch]
74
54
  #[allow(clippy::enum_variant_names, clippy::large_enum_variant)]
75
55
  enum Machines {
@@ -86,6 +66,7 @@ enum Machines {
86
66
  TimerMachine,
87
67
  WorkflowTaskMachine,
88
68
  UpsertSearchAttributesMachine,
69
+ ModifyWorkflowPropertiesMachine,
89
70
  }
90
71
 
91
72
  /// Extends [rustfsm::StateMachine] with some functionality specific to the temporal SDK.
@@ -93,7 +74,6 @@ enum Machines {
93
74
  /// Formerly known as `EntityStateMachine` in Java.
94
75
  #[enum_dispatch::enum_dispatch(Machines)]
95
76
  trait TemporalStateMachine: Send {
96
- fn kind(&self) -> MachineKind;
97
77
  fn handle_command(
98
78
  &mut self,
99
79
  command_type: CommandType,
@@ -121,6 +101,9 @@ trait TemporalStateMachine: Send {
121
101
 
122
102
  /// Returns true if the state machine is in a final state
123
103
  fn is_final_state(&self) -> bool;
104
+
105
+ /// Returns a friendly name for the type of this machine
106
+ fn name(&self) -> &str;
124
107
  }
125
108
 
126
109
  impl<SM> TemporalStateMachine for SM
@@ -132,10 +115,6 @@ where
132
115
  <SM as StateMachine>::State: Display,
133
116
  <SM as StateMachine>::Error: Into<WFMachinesError> + 'static + Send + Sync,
134
117
  {
135
- fn kind(&self) -> MachineKind {
136
- self.kind()
137
- }
138
-
139
118
  fn handle_command(
140
119
  &mut self,
141
120
  command_type: CommandType,
@@ -162,7 +141,7 @@ where
162
141
  Err(WFMachinesError::Nondeterminism(format!(
163
142
  "Unexpected command {:?} generated by a {:?} machine",
164
143
  command_type,
165
- self.kind()
144
+ self.name()
166
145
  )))
167
146
  }
168
147
  }
@@ -220,6 +199,10 @@ where
220
199
  fn is_final_state(&self) -> bool {
221
200
  self.has_reached_final_state()
222
201
  }
202
+
203
+ fn name(&self) -> &str {
204
+ self.name()
205
+ }
223
206
  }
224
207
 
225
208
  fn process_machine_commands<SM>(
@@ -235,7 +218,7 @@ where
235
218
  {
236
219
  if !commands.is_empty() {
237
220
  debug!(commands=%commands.display(), state=%machine.state(),
238
- machine_name=%TemporalStateMachine::kind(machine), "Machine produced commands");
221
+ machine_name=%TemporalStateMachine::name(machine), "Machine produced commands");
239
222
  }
240
223
  let mut machine_responses = vec![];
241
224
  for cmd in commands {
@@ -260,9 +243,6 @@ trait WFMachinesAdapter: StateMachine {
260
243
  /// ahead of time if it's worth trying to call [TemporalStateMachine::handle_event] without
261
244
  /// requiring mutable access.
262
245
  fn matches_event(&self, event: &HistoryEvent) -> bool;
263
-
264
- /// Allows robust identification of the type of machine
265
- fn kind(&self) -> MachineKind;
266
246
  }
267
247
 
268
248
  #[derive(Debug, Copy, Clone)]
@@ -334,9 +314,3 @@ struct NewMachineWithCommand {
334
314
  command: ProtoCommand,
335
315
  machine: Machines,
336
316
  }
337
-
338
- impl Debug for dyn TemporalStateMachine {
339
- fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
340
- std::fmt::Display::fmt(&self.kind(), f)
341
- }
342
- }