temporalio 0.0.2 → 0.1.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.
Files changed (202) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +25 -23
  3. data/bridge/Cargo.lock +168 -59
  4. data/bridge/Cargo.toml +4 -2
  5. data/bridge/sdk-core/README.md +19 -6
  6. data/bridge/sdk-core/client/src/lib.rs +215 -39
  7. data/bridge/sdk-core/client/src/metrics.rs +17 -8
  8. data/bridge/sdk-core/client/src/raw.rs +4 -4
  9. data/bridge/sdk-core/client/src/retry.rs +32 -20
  10. data/bridge/sdk-core/core/Cargo.toml +22 -9
  11. data/bridge/sdk-core/core/src/abstractions.rs +203 -14
  12. data/bridge/sdk-core/core/src/core_tests/activity_tasks.rs +76 -41
  13. data/bridge/sdk-core/core/src/core_tests/determinism.rs +165 -2
  14. data/bridge/sdk-core/core/src/core_tests/local_activities.rs +204 -83
  15. data/bridge/sdk-core/core/src/core_tests/queries.rs +3 -4
  16. data/bridge/sdk-core/core/src/core_tests/workers.rs +1 -3
  17. data/bridge/sdk-core/core/src/core_tests/workflow_tasks.rs +397 -54
  18. data/bridge/sdk-core/core/src/ephemeral_server/mod.rs +106 -12
  19. data/bridge/sdk-core/core/src/internal_flags.rs +136 -0
  20. data/bridge/sdk-core/core/src/lib.rs +16 -9
  21. data/bridge/sdk-core/core/src/telemetry/log_export.rs +1 -1
  22. data/bridge/sdk-core/core/src/telemetry/metrics.rs +69 -35
  23. data/bridge/sdk-core/core/src/telemetry/mod.rs +29 -13
  24. data/bridge/sdk-core/core/src/telemetry/prometheus_server.rs +17 -12
  25. data/bridge/sdk-core/core/src/test_help/mod.rs +62 -12
  26. data/bridge/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +112 -156
  27. data/bridge/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +89 -0
  28. data/bridge/sdk-core/core/src/worker/activities/local_activities.rs +352 -122
  29. data/bridge/sdk-core/core/src/worker/activities.rs +233 -157
  30. data/bridge/sdk-core/core/src/worker/client/mocks.rs +22 -2
  31. data/bridge/sdk-core/core/src/worker/client.rs +18 -2
  32. data/bridge/sdk-core/core/src/worker/mod.rs +165 -58
  33. data/bridge/sdk-core/core/src/worker/workflow/bridge.rs +1 -3
  34. data/bridge/sdk-core/core/src/worker/workflow/driven_workflow.rs +3 -5
  35. data/bridge/sdk-core/core/src/worker/workflow/history_update.rs +856 -277
  36. data/bridge/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +100 -43
  37. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +7 -7
  38. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +5 -4
  39. data/bridge/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +87 -27
  40. data/bridge/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +5 -4
  41. data/bridge/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +5 -4
  42. data/bridge/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +5 -4
  43. data/bridge/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +137 -62
  44. data/bridge/sdk-core/core/src/worker/workflow/machines/mod.rs +25 -17
  45. data/bridge/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +7 -6
  46. data/bridge/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +103 -152
  47. data/bridge/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +7 -7
  48. data/bridge/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +9 -9
  49. data/bridge/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +2 -2
  50. data/bridge/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +14 -7
  51. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +5 -16
  52. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +201 -121
  53. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +11 -14
  54. data/bridge/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +30 -15
  55. data/bridge/sdk-core/core/src/worker/workflow/managed_run.rs +1026 -376
  56. data/bridge/sdk-core/core/src/worker/workflow/mod.rs +460 -384
  57. data/bridge/sdk-core/core/src/worker/workflow/run_cache.rs +40 -57
  58. data/bridge/sdk-core/core/src/worker/workflow/wft_extraction.rs +125 -0
  59. data/bridge/sdk-core/core/src/worker/workflow/wft_poller.rs +1 -4
  60. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +117 -0
  61. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +24 -0
  62. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream.rs +448 -718
  63. data/bridge/sdk-core/core-api/Cargo.toml +2 -1
  64. data/bridge/sdk-core/core-api/src/errors.rs +1 -34
  65. data/bridge/sdk-core/core-api/src/lib.rs +6 -2
  66. data/bridge/sdk-core/core-api/src/telemetry.rs +0 -6
  67. data/bridge/sdk-core/core-api/src/worker.rs +14 -1
  68. data/bridge/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +18 -15
  69. data/bridge/sdk-core/fsm/rustfsm_trait/src/lib.rs +8 -3
  70. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-16_history.bin +0 -0
  71. data/bridge/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +5 -17
  72. data/bridge/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +11 -0
  73. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +1 -6
  74. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +6 -6
  75. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +5 -0
  76. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +22 -6
  77. data/bridge/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +48 -19
  78. data/bridge/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +2 -0
  79. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +3 -0
  80. data/bridge/sdk-core/protos/api_upstream/temporal/api/{enums/v1/interaction_type.proto → protocol/v1/message.proto} +29 -11
  81. data/bridge/sdk-core/protos/api_upstream/temporal/api/sdk/v1/task_complete_metadata.proto +63 -0
  82. data/bridge/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +111 -0
  83. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +59 -28
  84. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +2 -2
  85. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +1 -0
  86. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +1 -0
  87. data/bridge/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +1 -0
  88. data/bridge/sdk-core/protos/local/temporal/sdk/core/common/common.proto +1 -0
  89. data/bridge/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +1 -0
  90. data/bridge/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +1 -0
  91. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +7 -0
  92. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +1 -0
  93. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +6 -0
  94. data/bridge/sdk-core/sdk/Cargo.toml +3 -2
  95. data/bridge/sdk-core/sdk/src/lib.rs +87 -20
  96. data/bridge/sdk-core/sdk/src/workflow_future.rs +9 -8
  97. data/bridge/sdk-core/sdk-core-protos/Cargo.toml +5 -2
  98. data/bridge/sdk-core/sdk-core-protos/build.rs +36 -1
  99. data/bridge/sdk-core/sdk-core-protos/src/history_builder.rs +100 -87
  100. data/bridge/sdk-core/sdk-core-protos/src/history_info.rs +5 -1
  101. data/bridge/sdk-core/sdk-core-protos/src/lib.rs +175 -57
  102. data/bridge/sdk-core/sdk-core-protos/src/task_token.rs +12 -2
  103. data/bridge/sdk-core/test-utils/Cargo.toml +3 -1
  104. data/bridge/sdk-core/test-utils/src/canned_histories.rs +106 -296
  105. data/bridge/sdk-core/test-utils/src/histfetch.rs +1 -1
  106. data/bridge/sdk-core/test-utils/src/lib.rs +82 -23
  107. data/bridge/sdk-core/test-utils/src/wf_input_saver.rs +50 -0
  108. data/bridge/sdk-core/test-utils/src/workflows.rs +29 -0
  109. data/bridge/sdk-core/tests/fuzzy_workflow.rs +130 -0
  110. data/bridge/sdk-core/tests/{load_tests.rs → heavy_tests.rs} +125 -51
  111. data/bridge/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +25 -3
  112. data/bridge/sdk-core/tests/integ_tests/heartbeat_tests.rs +5 -3
  113. data/bridge/sdk-core/tests/integ_tests/metrics_tests.rs +218 -16
  114. data/bridge/sdk-core/tests/integ_tests/polling_tests.rs +4 -47
  115. data/bridge/sdk-core/tests/integ_tests/queries_tests.rs +5 -128
  116. data/bridge/sdk-core/tests/integ_tests/visibility_tests.rs +83 -25
  117. data/bridge/sdk-core/tests/integ_tests/workflow_tests/activities.rs +93 -69
  118. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -0
  119. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +6 -13
  120. data/bridge/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +1 -0
  121. data/bridge/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +6 -2
  122. data/bridge/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -10
  123. data/bridge/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +72 -191
  124. data/bridge/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +1 -0
  125. data/bridge/sdk-core/tests/integ_tests/workflow_tests/patches.rs +7 -28
  126. data/bridge/sdk-core/tests/integ_tests/workflow_tests/replay.rs +12 -7
  127. data/bridge/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -0
  128. data/bridge/sdk-core/tests/integ_tests/workflow_tests/signals.rs +18 -14
  129. data/bridge/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +6 -20
  130. data/bridge/sdk-core/tests/integ_tests/workflow_tests/timers.rs +10 -21
  131. data/bridge/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +6 -4
  132. data/bridge/sdk-core/tests/integ_tests/workflow_tests.rs +10 -11
  133. data/bridge/sdk-core/tests/main.rs +3 -13
  134. data/bridge/sdk-core/tests/runner.rs +75 -36
  135. data/bridge/sdk-core/tests/wf_input_replay.rs +32 -0
  136. data/bridge/src/connection.rs +41 -25
  137. data/bridge/src/lib.rs +269 -14
  138. data/bridge/src/runtime.rs +1 -1
  139. data/bridge/src/test_server.rs +153 -0
  140. data/bridge/src/worker.rs +89 -16
  141. data/lib/gen/temporal/api/command/v1/message_pb.rb +4 -18
  142. data/lib/gen/temporal/api/common/v1/message_pb.rb +4 -0
  143. data/lib/gen/temporal/api/enums/v1/command_type_pb.rb +1 -3
  144. data/lib/gen/temporal/api/enums/v1/event_type_pb.rb +3 -3
  145. data/lib/gen/temporal/api/enums/v1/failed_cause_pb.rb +2 -0
  146. data/lib/gen/temporal/api/enums/v1/update_pb.rb +6 -4
  147. data/lib/gen/temporal/api/history/v1/message_pb.rb +27 -19
  148. data/lib/gen/temporal/api/namespace/v1/message_pb.rb +1 -0
  149. data/lib/gen/temporal/api/operatorservice/v1/request_response_pb.rb +3 -0
  150. data/lib/gen/temporal/api/protocol/v1/message_pb.rb +30 -0
  151. data/lib/gen/temporal/api/sdk/v1/task_complete_metadata_pb.rb +23 -0
  152. data/lib/gen/temporal/api/testservice/v1/request_response_pb.rb +49 -0
  153. data/lib/gen/temporal/api/testservice/v1/service_pb.rb +21 -0
  154. data/lib/gen/temporal/api/update/v1/message_pb.rb +72 -0
  155. data/lib/gen/temporal/api/workflowservice/v1/request_response_pb.rb +26 -16
  156. data/lib/gen/temporal/sdk/core/activity_result/activity_result_pb.rb +13 -9
  157. data/lib/gen/temporal/sdk/core/activity_task/activity_task_pb.rb +10 -6
  158. data/lib/gen/temporal/sdk/core/child_workflow/child_workflow_pb.rb +13 -9
  159. data/lib/gen/temporal/sdk/core/common/common_pb.rb +7 -3
  160. data/lib/gen/temporal/sdk/core/core_interface_pb.rb +9 -3
  161. data/lib/gen/temporal/sdk/core/external_data/external_data_pb.rb +7 -3
  162. data/lib/gen/temporal/sdk/core/workflow_activation/workflow_activation_pb.rb +27 -21
  163. data/lib/gen/temporal/sdk/core/workflow_commands/workflow_commands_pb.rb +28 -24
  164. data/lib/gen/temporal/sdk/core/workflow_completion/workflow_completion_pb.rb +12 -5
  165. data/lib/temporalio/activity/context.rb +13 -8
  166. data/lib/temporalio/activity/info.rb +1 -1
  167. data/lib/temporalio/bridge/connect_options.rb +15 -0
  168. data/lib/temporalio/bridge/retry_config.rb +24 -0
  169. data/lib/temporalio/bridge/tls_options.rb +19 -0
  170. data/lib/temporalio/client/implementation.rb +8 -8
  171. data/lib/temporalio/connection/retry_config.rb +44 -0
  172. data/lib/temporalio/connection/service.rb +20 -0
  173. data/lib/temporalio/connection/test_service.rb +92 -0
  174. data/lib/temporalio/connection/tls_options.rb +51 -0
  175. data/lib/temporalio/connection/workflow_service.rb +731 -0
  176. data/lib/temporalio/connection.rb +55 -720
  177. data/lib/temporalio/interceptor/activity_inbound.rb +22 -0
  178. data/lib/temporalio/interceptor/activity_outbound.rb +24 -0
  179. data/lib/temporalio/interceptor/chain.rb +5 -5
  180. data/lib/temporalio/interceptor/client.rb +8 -4
  181. data/lib/temporalio/interceptor.rb +22 -0
  182. data/lib/temporalio/retry_policy.rb +13 -3
  183. data/lib/temporalio/testing/time_skipping_handle.rb +32 -0
  184. data/lib/temporalio/testing/time_skipping_interceptor.rb +23 -0
  185. data/lib/temporalio/testing/workflow_environment.rb +112 -0
  186. data/lib/temporalio/testing.rb +175 -0
  187. data/lib/temporalio/version.rb +1 -1
  188. data/lib/temporalio/worker/activity_runner.rb +26 -4
  189. data/lib/temporalio/worker/activity_worker.rb +44 -18
  190. data/lib/temporalio/worker/sync_worker.rb +47 -11
  191. data/lib/temporalio/worker.rb +27 -21
  192. data/lib/temporalio/workflow/async.rb +46 -0
  193. data/lib/temporalio/workflow/future.rb +138 -0
  194. data/lib/temporalio/workflow/info.rb +76 -0
  195. data/temporalio.gemspec +4 -3
  196. metadata +67 -17
  197. data/bridge/sdk-core/Cargo.lock +0 -2606
  198. data/bridge/sdk-core/protos/api_upstream/temporal/api/interaction/v1/message.proto +0 -87
  199. data/lib/bridge.so +0 -0
  200. data/lib/gen/temporal/api/enums/v1/interaction_type_pb.rb +0 -25
  201. data/lib/gen/temporal/api/interaction/v1/message_pb.rb +0 -49
  202. data/lib/gen/temporal/sdk/core/bridge/bridge_pb.rb +0 -222
@@ -0,0 +1,111 @@
1
+ // The MIT License
2
+ //
3
+ // Copyright (c) 2020 Temporal Technologies Inc. All rights reserved.
4
+ //
5
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ // of this software and associated documentation files (the "Software"), to deal
7
+ // in the Software without restriction, including without limitation the rights
8
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ // copies of the Software, and to permit persons to whom the Software is
10
+ // furnished to do so, subject to the following conditions:
11
+ //
12
+ // The above copyright notice and this permission notice shall be included in
13
+ // all copies or substantial portions of the Software.
14
+ //
15
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ // THE SOFTWARE.
22
+
23
+ syntax = "proto3";
24
+
25
+ package temporal.api.update.v1;
26
+
27
+ option go_package = "go.temporal.io/api/update/v1;update";
28
+ option java_package = "io.temporal.api.update.v1";
29
+ option java_multiple_files = true;
30
+ option java_outer_classname = "MessageProto";
31
+ option ruby_package = "Temporalio::Api::Update::V1";
32
+ option csharp_namespace = "Temporalio.Api.Update.V1";
33
+
34
+ import "temporal/api/common/v1/message.proto";
35
+ import "temporal/api/enums/v1/update.proto";
36
+ import "temporal/api/failure/v1/message.proto";
37
+
38
+ // Sepcifies to the gRPC server how the client wants the UpdateWorkflowExecution
39
+ // call to wait before returning control to the caller.
40
+ message WaitPolicy {
41
+
42
+ // Indicates the update lifecycle stage that the gRPC call should wait for
43
+ // before returning.
44
+ temporal.api.enums.v1.UpdateWorkflowExecutionLifecycleStage lifecycle_stage = 1;
45
+ }
46
+
47
+ // The data needed by a client to refer to an previously invoked workflow
48
+ // execution update process.
49
+ message UpdateRef {
50
+ temporal.api.common.v1.WorkflowExecution workflow_execution = 1;
51
+ string update_id = 2;
52
+ }
53
+
54
+ // The outcome of a workflow update - success or failure.
55
+ message Outcome {
56
+ oneof value {
57
+ temporal.api.common.v1.Payloads success = 1;
58
+ temporal.api.failure.v1.Failure failure = 2;
59
+ }
60
+ }
61
+
62
+ // Metadata about a workflow execution update.
63
+ message Meta {
64
+ // An ID with workflow-scoped uniqueness for this update
65
+ string update_id = 1;
66
+
67
+ // A string identifying the agent that requested this update.
68
+ string identity = 2;
69
+ }
70
+
71
+ message Input {
72
+ // Headers that are passed with the update from the requesting entity.
73
+ // These can include things like auth or tracing tokens.
74
+ temporal.api.common.v1.Header header = 1;
75
+
76
+ // The name of the input handler to invoke on the target workflow
77
+ string name = 2;
78
+
79
+ // The arguments to pass to the named handler.
80
+ temporal.api.common.v1.Payloads args = 3;
81
+ }
82
+
83
+ // The client request that triggers a workflow execution update
84
+ message Request {
85
+ Meta meta = 1;
86
+ Input input = 2;
87
+ }
88
+
89
+ // An update protocol message indicating that a workflow execution update has
90
+ // been rejected.
91
+ message Rejection {
92
+ string rejected_request_message_id = 1;
93
+ int64 rejected_request_sequencing_event_id = 2;
94
+ Request rejected_request = 3;
95
+ temporal.api.failure.v1.Failure failure = 4;
96
+ }
97
+
98
+ // An update protocol message indicating that a workflow execution update has
99
+ // been accepted (i.e. passed the worker-side validation phase).
100
+ message Acceptance {
101
+ string accepted_request_message_id = 1;
102
+ int64 accepted_request_sequencing_event_id = 2;
103
+ Request accepted_request = 3;
104
+ }
105
+
106
+ // An update protocol message indicating that a workflow execution update has
107
+ // completed with the contained outcome.
108
+ message Response {
109
+ Meta meta = 1;
110
+ Outcome outcome = 2;
111
+ }
@@ -39,21 +39,22 @@ import "temporal/api/enums/v1/common.proto";
39
39
  import "temporal/api/enums/v1/query.proto";
40
40
  import "temporal/api/enums/v1/reset.proto";
41
41
  import "temporal/api/enums/v1/task_queue.proto";
42
- import "temporal/api/enums/v1/update.proto";
43
42
  import "temporal/api/common/v1/message.proto";
44
43
  import "temporal/api/history/v1/message.proto";
45
- import "temporal/api/interaction/v1/message.proto";
46
44
  import "temporal/api/workflow/v1/message.proto";
47
45
  import "temporal/api/command/v1/message.proto";
48
46
  import "temporal/api/failure/v1/message.proto";
49
47
  import "temporal/api/filter/v1/message.proto";
48
+ import "temporal/api/protocol/v1/message.proto";
50
49
  import "temporal/api/namespace/v1/message.proto";
51
50
  import "temporal/api/query/v1/message.proto";
52
51
  import "temporal/api/replication/v1/message.proto";
53
52
  import "temporal/api/schedule/v1/message.proto";
54
53
  import "temporal/api/taskqueue/v1/message.proto";
54
+ import "temporal/api/update/v1/message.proto";
55
55
  import "temporal/api/version/v1/message.proto";
56
56
  import "temporal/api/batch/v1/message.proto";
57
+ import "temporal/api/sdk/v1/task_complete_metadata.proto";
57
58
 
58
59
  import "google/protobuf/duration.proto";
59
60
  import "google/protobuf/timestamp.proto";
@@ -168,10 +169,25 @@ message StartWorkflowExecutionRequest {
168
169
  temporal.api.common.v1.Memo memo = 14;
169
170
  temporal.api.common.v1.SearchAttributes search_attributes = 15;
170
171
  temporal.api.common.v1.Header header = 16;
172
+ // Request to get the first workflow task inline in the response bypassing matching service and worker polling.
173
+ // If set to `true` the caller is expected to have a worker available and capable of processing the task.
174
+ // The returned task will be marked as started and is expected to be completed by the specified
175
+ // `workflow_task_timeout`.
176
+ bool request_eager_execution = 17;
177
+ // These values will be available as ContinuedFailure and LastCompletionResult in the
178
+ // WorkflowExecutionStarted event and through SDKs. The are currently only used by the
179
+ // server itself (for the schedules feature) and are not intended to be exposed in
180
+ // StartWorkflowExecution.
181
+ temporal.api.failure.v1.Failure continued_failure = 18;
182
+ temporal.api.common.v1.Payloads last_completion_result = 19;
171
183
  }
172
184
 
173
185
  message StartWorkflowExecutionResponse {
174
186
  string run_id = 1;
187
+ // When `request_eager_execution` is set on the `StartWorkflowExecutionRequest`, the server - if supported - will
188
+ // return the first workflow task to be eagerly executed.
189
+ // The caller is expected to have a worker available to process the task.
190
+ PollWorkflowTaskQueueResponse eager_workflow_task = 2;
175
191
  }
176
192
 
177
193
  message GetWorkflowExecutionHistoryRequest {
@@ -267,8 +283,8 @@ message PollWorkflowTaskQueueResponse {
267
283
  // Queries that should be executed after applying the history in this task. Responses should be
268
284
  // attached to `RespondWorkflowTaskCompletedRequest::query_results`
269
285
  map<string, temporal.api.query.v1.WorkflowQuery> queries = 14;
270
-
271
- repeated temporal.api.interaction.v1.Invocation interactions = 15;
286
+ // Protocol messages piggybacking on a WFT as a transport
287
+ repeated temporal.api.protocol.v1.Message messages = 15;
272
288
  }
273
289
 
274
290
  message RespondWorkflowTaskCompletedRequest {
@@ -299,6 +315,13 @@ message RespondWorkflowTaskCompletedRequest {
299
315
  // When `worker_versioning_id` has a `worker_build_id`, and `binary_checksum` is not
300
316
  // set, that value should also be considered as the `binary_checksum`.
301
317
  temporal.api.taskqueue.v1.VersionId worker_versioning_id = 10;
318
+ // Protocol messages piggybacking on a WFT as a transport
319
+ repeated temporal.api.protocol.v1.Message messages = 11;
320
+ // Data the SDK wishes to record for itself, but server need not interpret, and does not
321
+ // directly impact workflow state.
322
+ temporal.api.sdk.v1.WorkflowTaskCompletedMetadata sdk_metadata = 12;
323
+ // Local usage data collected for metering
324
+ temporal.api.common.v1.MeteringMetadata metering_metadata = 13;
302
325
  }
303
326
 
304
327
  message RespondWorkflowTaskCompletedResponse {
@@ -323,6 +346,8 @@ message RespondWorkflowTaskFailedRequest {
323
346
  // Worker process' unique binary id
324
347
  string binary_checksum = 5;
325
348
  string namespace = 6;
349
+ // Protocol messages piggybacking on a WFT as a transport
350
+ repeated temporal.api.protocol.v1.Message messages = 7;
326
351
  }
327
352
 
328
353
  message RespondWorkflowTaskFailedResponse {
@@ -851,6 +876,13 @@ message GetSystemInfoResponse {
851
876
 
852
877
  // True if server supports upserting workflow memo
853
878
  bool upsert_memo = 7;
879
+
880
+ // True if server supports eager workflow task dispatching for the StartWorkflowExecution API
881
+ bool eager_workflow_start = 8;
882
+
883
+ // True if the server knows about the sdk metadata field on WFT completions and will record
884
+ // it in history
885
+ bool sdk_metadata = 9;
854
886
  }
855
887
  }
856
888
 
@@ -1051,51 +1083,50 @@ message GetWorkerBuildIdOrderingResponse {
1051
1083
 
1052
1084
  // (-- api-linter: core::0134=disabled
1053
1085
  // aip.dev/not-precedent: Update RPCs don't follow Google API format. --)
1054
- message UpdateWorkflowRequest {
1055
- // A unique ID for this logical request
1056
- string request_id = 1;
1057
-
1058
- // The manner in which the update result will be accessed.
1059
- // This field requires a non-default value; the default value of the enum
1060
- // will result in an error.
1061
- temporal.api.enums.v1.WorkflowUpdateResultAccessStyle result_access_style = 2;
1062
-
1086
+ message UpdateWorkflowExecutionRequest {
1063
1087
  // The namespace name of the target workflow
1064
- string namespace = 3;
1088
+ string namespace = 1;
1065
1089
  // The target workflow id and (optionally) a specific run thereof
1066
1090
  // (-- api-linter: core::0203::optional=disabled
1067
1091
  // aip.dev/not-precedent: false positive triggered by the word "optional" --)
1068
- temporal.api.common.v1.WorkflowExecution workflow_execution = 4;
1092
+ temporal.api.common.v1.WorkflowExecution workflow_execution = 2;
1069
1093
  // If set, this call will error if the most recent (if no run id is set on
1070
1094
  // `workflow_execution`), or specified (if it is) workflow execution is not
1071
1095
  // part of the same execution chain as this id.
1072
- string first_execution_run_id = 5;
1096
+ string first_execution_run_id = 3;
1073
1097
 
1074
- // A string identifying the agent that requested this interaction.
1075
- string identity = 6;
1098
+ // Describes when this request should return - basically whether the
1099
+ // update is synchronous, asynchronous, or somewhere in between.
1100
+ temporal.api.update.v1.WaitPolicy wait_policy = 4;
1076
1101
 
1077
- // The name under which the workflow update function is registered and the
1078
- // arguments to pass to said function.
1079
- temporal.api.interaction.v1.Input input = 7;
1102
+ // The request information that will be delivered all the way down to the
1103
+ // workflow execution.
1104
+ temporal.api.update.v1.Request request = 5;
1080
1105
  }
1081
1106
 
1082
- message UpdateWorkflowResponse {
1083
- // An opaque token that can be used to retrieve the update result via
1084
- // polling if it is not returned as part of the gRPC response
1085
- bytes update_token = 1;
1086
- // The success or failure status of the update
1087
- temporal.api.interaction.v1.Output output = 2;
1107
+ message UpdateWorkflowExecutionResponse {
1108
+ // Enough information for subsequent poll calls if needed. Never null.
1109
+ temporal.api.update.v1.UpdateRef update_ref = 1;
1110
+
1111
+ // The outcome of the update if and only if the workflow execution update
1112
+ // has completed. If this response is being returned before the update has
1113
+ // completed then this field will not be set.
1114
+ temporal.api.update.v1.Outcome outcome = 2;
1088
1115
  }
1089
1116
 
1090
1117
  message StartBatchOperationRequest {
1091
1118
  // Namespace that contains the batch operation
1092
1119
  string namespace = 1;
1093
- // Visibility query defines the the group of workflow to do batch operation
1120
+ // Visibility query defines the the group of workflow to apply the batch operation
1121
+ // This field and Executions are mutually exclusive
1094
1122
  string visibility_query = 2;
1095
1123
  // Job ID defines the unique ID for the batch job
1096
1124
  string job_id = 3;
1097
1125
  // Reason to perform the batch operation
1098
1126
  string reason = 4;
1127
+ // Executions to apply the batch operation
1128
+ // This field and VisibilityQuery are mutually exclusive
1129
+ repeated temporal.api.common.v1.WorkflowExecution executions = 5;
1099
1130
  // Operation input
1100
1131
  oneof operation {
1101
1132
  temporal.api.batch.v1.BatchOperationTermination termination_operation = 10;
@@ -393,8 +393,8 @@ service WorkflowService {
393
393
 
394
394
  // Invokes the specified update function on user workflow code.
395
395
  // (-- api-linter: core::0134=disabled
396
- // aip.dev/not-precedent: UpdateWorkflow doesn't follow Google API format --)
397
- rpc UpdateWorkflow(UpdateWorkflowRequest) returns (UpdateWorkflowResponse) {
396
+ // aip.dev/not-precedent: UpdateWorkflowExecution doesn't follow Google API format --)
397
+ rpc UpdateWorkflowExecution(UpdateWorkflowExecutionRequest) returns (UpdateWorkflowExecutionResponse) {
398
398
  }
399
399
 
400
400
  // StartBatchOperation starts a new batch operation
@@ -1,6 +1,7 @@
1
1
  syntax = "proto3";
2
2
 
3
3
  package coresdk.activity_result;
4
+ option ruby_package = "Temporalio::Bridge::Api::ActivityResult";
4
5
 
5
6
  import "google/protobuf/duration.proto";
6
7
  import "google/protobuf/timestamp.proto";
@@ -4,6 +4,7 @@ syntax = "proto3";
4
4
  * Definitions of the different activity tasks returned from [crate::Core::poll_task].
5
5
  */
6
6
  package coresdk.activity_task;
7
+ option ruby_package = "Temporalio::Bridge::Api::ActivityTask";
7
8
 
8
9
  import "google/protobuf/duration.proto";
9
10
  import "google/protobuf/timestamp.proto";
@@ -1,6 +1,7 @@
1
1
  syntax = "proto3";
2
2
 
3
3
  package coresdk.child_workflow;
4
+ option ruby_package = "Temporalio::Bridge::Api::ChildWorkflow";
4
5
 
5
6
  import "temporal/api/common/v1/message.proto";
6
7
  import "temporal/api/failure/v1/message.proto";
@@ -1,6 +1,7 @@
1
1
  syntax = "proto3";
2
2
 
3
3
  package coresdk.common;
4
+ option ruby_package = "Temporalio::Bridge::Api::Common";
4
5
 
5
6
  import "google/protobuf/duration.proto";
6
7
 
@@ -1,6 +1,7 @@
1
1
  syntax = "proto3";
2
2
 
3
3
  package coresdk;
4
+ option ruby_package = "Temporalio::Bridge::Api::CoreInterface";
4
5
 
5
6
  // Note: Intellij will think the Google imports don't work because of the slightly odd nature of
6
7
  // the include paths. You can make it work by going to the "Protobuf Support" settings section
@@ -1,6 +1,7 @@
1
1
  syntax = "proto3";
2
2
 
3
3
  package coresdk.external_data;
4
+ option ruby_package = "Temporalio::Bridge::Api::ExternalData";
4
5
 
5
6
  import "google/protobuf/duration.proto";
6
7
  import "google/protobuf/timestamp.proto";
@@ -5,6 +5,7 @@ syntax = "proto3";
5
5
  * lang SDK applies these activation jobs to drive workflows.
6
6
  */
7
7
  package coresdk.workflow_activation;
8
+ option ruby_package = "Temporalio::Bridge::Api::WorkflowActivation";
8
9
 
9
10
  import "google/protobuf/timestamp.proto";
10
11
  import "google/protobuf/duration.proto";
@@ -30,6 +31,10 @@ message WorkflowActivation {
30
31
  uint32 history_length = 4;
31
32
  /// The things to do upon activating the workflow
32
33
  repeated WorkflowActivationJob jobs = 5;
34
+ // Internal flags which are available for use by lang. If `is_replaying` is false, all
35
+ // internal flags may be used. This is not a delta - all previously used flags always
36
+ // appear since this representation is cheap.
37
+ repeated uint32 available_internal_flags = 6;
33
38
  }
34
39
 
35
40
  message WorkflowActivationJob {
@@ -258,6 +263,8 @@ message RemoveFromCache {
258
263
  // There was some fatal error processing the workflow, typically an internal error, but
259
264
  // can also happen if then network drops out while paginating. Check message string.
260
265
  FATAL = 8;
266
+ // Something went wrong attempting to fetch more history events.
267
+ PAGINATION_OR_HISTORY_FETCH = 9;
261
268
  }
262
269
  EvictionReason reason = 2;
263
270
  }
@@ -6,6 +6,7 @@ syntax = "proto3";
6
6
  * activation.
7
7
  */
8
8
  package coresdk.workflow_commands;
9
+ option ruby_package = "Temporalio::Bridge::Api::WorkflowCommands";
9
10
 
10
11
  import "google/protobuf/duration.proto";
11
12
  import "google/protobuf/timestamp.proto";
@@ -1,8 +1,10 @@
1
1
  syntax = "proto3";
2
2
 
3
3
  package coresdk.workflow_completion;
4
+ option ruby_package = "Temporalio::Bridge::Api::WorkflowCompletion";
4
5
 
5
6
  import "temporal/api/failure/v1/message.proto";
7
+ import "temporal/api/enums/v1/failed_cause.proto";
6
8
  import "temporal/sdk/core/common/common.proto";
7
9
  import "temporal/sdk/core/workflow_commands/workflow_commands.proto";
8
10
 
@@ -20,10 +22,14 @@ message WorkflowActivationCompletion {
20
22
  message Success {
21
23
  // A list of commands to send back to the temporal server
22
24
  repeated workflow_commands.WorkflowCommand commands = 1;
25
+ // Any internal flags which the lang SDK used in the processing of this activation
26
+ repeated uint32 used_internal_flags = 6;
23
27
  }
24
28
 
25
29
  /// Failure to activate or execute a workflow
26
30
  message Failure {
27
31
  temporal.api.failure.v1.Failure failure = 1;
32
+ // Forces overriding the WFT failure cause
33
+ temporal.api.enums.v1.WorkflowTaskFailedCause force_cause = 2;
28
34
  }
29
35
 
@@ -14,14 +14,15 @@ categories = ["development-tools"]
14
14
 
15
15
  [dependencies]
16
16
  async-trait = "0.1"
17
+ thiserror = "1.0"
17
18
  anyhow = "1.0"
18
- base64 = "0.20"
19
+ base64 = "0.21"
19
20
  crossbeam = "0.8"
20
21
  derive_more = "0.99"
21
22
  futures = "0.3"
22
23
  once_cell = "1.10"
23
24
  parking_lot = { version = "0.12", features = ["send_guard"] }
24
- prost-types = "0.11"
25
+ prost-types = { version = "0.4", package = "prost-wkt-types" }
25
26
  sha2 = "0.10"
26
27
  serde = "1.0"
27
28
  tokio = { version = "1.1", features = ["rt", "rt-multi-thread", "parking_lot", "time", "fs"] }
@@ -66,10 +66,12 @@ use anyhow::{anyhow, bail, Context};
66
66
  use app_data::AppData;
67
67
  use futures::{future::BoxFuture, FutureExt, StreamExt, TryFutureExt, TryStreamExt};
68
68
  use std::{
69
+ any::{Any, TypeId},
69
70
  cell::RefCell,
70
71
  collections::HashMap,
71
72
  fmt::{Debug, Display, Formatter},
72
73
  future::Future,
74
+ panic::AssertUnwindSafe,
73
75
  sync::Arc,
74
76
  };
75
77
  use temporal_client::ClientOptionsBuilder;
@@ -306,22 +308,17 @@ impl Worker {
306
308
  // makes tests which use mocks dramatically more manageable.
307
309
  async {
308
310
  if !act_half.activity_fns.is_empty() {
309
- let shutdown_token = shutdown_token.clone();
310
311
  loop {
311
- tokio::select! {
312
- activity = common.worker.poll_activity_task() => {
313
- if matches!(activity, Err(PollActivityError::ShutDown)) {
314
- break;
315
- }
316
- act_half.activity_task_handler(
317
- common.worker.clone(),
318
- safe_app_data.clone(),
319
- common.task_queue.clone(),
320
- activity?
321
- )?;
322
- },
323
- _ = shutdown_token.cancelled() => { break }
312
+ let activity = common.worker.poll_activity_task().await;
313
+ if matches!(activity, Err(PollActivityError::ShutDown)) {
314
+ break;
324
315
  }
316
+ act_half.activity_task_handler(
317
+ common.worker.clone(),
318
+ safe_app_data.clone(),
319
+ common.task_queue.clone(),
320
+ activity?,
321
+ )?;
325
322
  }
326
323
  };
327
324
  Result::<_, anyhow::Error>::Ok(())
@@ -335,6 +332,7 @@ impl Worker {
335
332
  i.on_shutdown(self);
336
333
  }
337
334
  self.common.worker.shutdown().await;
335
+ debug!("Worker shutdown complete");
338
336
  self.app_data = Some(
339
337
  Arc::try_unwrap(safe_app_data)
340
338
  .map_err(|_| anyhow!("some references of AppData exist on worker shutdown"))?,
@@ -412,7 +410,7 @@ impl WorkflowHalf {
412
410
  );
413
411
  let jh = tokio::spawn(async move {
414
412
  tokio::select! {
415
- r = wff => r,
413
+ r = wff.fuse() => r,
416
414
  // TODO: This probably shouldn't abort early, as it could cause an in-progress
417
415
  // complete to abort. Send synthetic remove activation
418
416
  _ = shutdown_token.cancelled() => {
@@ -485,15 +483,30 @@ impl ActivityHalf {
485
483
  start,
486
484
  );
487
485
  tokio::spawn(async move {
488
- let output = (act_fn.act_func)(ctx, arg).await;
486
+ let output = AssertUnwindSafe((act_fn.act_func)(ctx, arg))
487
+ .catch_unwind()
488
+ .await;
489
489
  let result = match output {
490
- Ok(ActExitValue::Normal(p)) => ActivityExecutionResult::ok(p),
491
- Ok(ActExitValue::WillCompleteAsync) => {
490
+ Err(e) => ActivityExecutionResult::fail(Failure::application_failure(
491
+ format!("Activity function panicked: {}", panic_formatter(e)),
492
+ true,
493
+ )),
494
+ Ok(Ok(ActExitValue::Normal(p))) => ActivityExecutionResult::ok(p),
495
+ Ok(Ok(ActExitValue::WillCompleteAsync)) => {
492
496
  ActivityExecutionResult::will_complete_async()
493
497
  }
494
- Err(err) => match err.downcast::<ActivityCancelledError>() {
498
+ Ok(Err(err)) => match err.downcast::<ActivityCancelledError>() {
495
499
  Ok(ce) => ActivityExecutionResult::cancel_from_details(ce.details),
496
- Err(other_err) => ActivityExecutionResult::fail(other_err.into()),
500
+ Err(other_err) => {
501
+ match other_err.downcast::<NonRetryableActivityError>() {
502
+ Ok(nre) => ActivityExecutionResult::fail(
503
+ Failure::application_failure_from_error(nre.into(), true),
504
+ ),
505
+ Err(other_err) => ActivityExecutionResult::fail(
506
+ Failure::application_failure_from_error(other_err, false),
507
+ ),
508
+ }
509
+ }
497
510
  },
498
511
  };
499
512
  worker
@@ -748,6 +761,14 @@ pub struct ActivityFunction {
748
761
  pub struct ActivityCancelledError {
749
762
  details: Option<Payload>,
750
763
  }
764
+ impl ActivityCancelledError {
765
+ /// Include some details as part of concluding the activity as cancelled
766
+ pub fn with_details(payload: Payload) -> Self {
767
+ Self {
768
+ details: Some(payload),
769
+ }
770
+ }
771
+ }
751
772
  impl std::error::Error for ActivityCancelledError {}
752
773
  impl Display for ActivityCancelledError {
753
774
  fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
@@ -755,6 +776,16 @@ impl Display for ActivityCancelledError {
755
776
  }
756
777
  }
757
778
 
779
+ /// Return this error to indicate that your activity non-retryable
780
+ /// this is a transparent wrapper around anyhow Error so essentially any type of error
781
+ /// could be used here.
782
+ ///
783
+ /// In your activity function. Return something along the lines of:
784
+ /// `Err(NonRetryableActivityError(anyhow::anyhow!("This should *not* be retried")).into())`
785
+ #[derive(Debug, thiserror::Error)]
786
+ #[error(transparent)]
787
+ pub struct NonRetryableActivityError(pub anyhow::Error);
788
+
758
789
  /// Closures / functions which can be turned into activity functions implement this trait
759
790
  pub trait IntoActivityFunc<Args, Res, Out> {
760
791
  /// Consume the closure or fn pointer and turned it into a boxed activity function
@@ -792,3 +823,39 @@ where
792
823
  Arc::new(wrapper)
793
824
  }
794
825
  }
826
+
827
+ /// Attempts to turn caught panics into something printable
828
+ fn panic_formatter(panic: Box<dyn Any>) -> Box<dyn Display> {
829
+ _panic_formatter::<&str>(panic)
830
+ }
831
+ fn _panic_formatter<T: 'static + PrintablePanicType>(panic: Box<dyn Any>) -> Box<dyn Display> {
832
+ match panic.downcast::<T>() {
833
+ Ok(d) => d,
834
+ Err(orig) => {
835
+ if TypeId::of::<<T as PrintablePanicType>::NextType>()
836
+ == TypeId::of::<EndPrintingAttempts>()
837
+ {
838
+ return Box::new("Couldn't turn panic into a string");
839
+ }
840
+ _panic_formatter::<T::NextType>(orig)
841
+ }
842
+ }
843
+ }
844
+ trait PrintablePanicType: Display {
845
+ type NextType: PrintablePanicType;
846
+ }
847
+ impl PrintablePanicType for &str {
848
+ type NextType = String;
849
+ }
850
+ impl PrintablePanicType for String {
851
+ type NextType = EndPrintingAttempts;
852
+ }
853
+ struct EndPrintingAttempts {}
854
+ impl Display for EndPrintingAttempts {
855
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
856
+ write!(f, "Will never be printed")
857
+ }
858
+ }
859
+ impl PrintablePanicType for EndPrintingAttempts {
860
+ type NextType = EndPrintingAttempts;
861
+ }
@@ -1,6 +1,6 @@
1
1
  use crate::{
2
- workflow_context::WfContextSharedData, CancellableID, RustWfCmd, SignalData, TimerResult,
3
- UnblockEvent, WfContext, WfExitValue, WorkflowFunction, WorkflowResult,
2
+ panic_formatter, workflow_context::WfContextSharedData, CancellableID, RustWfCmd, SignalData,
3
+ TimerResult, UnblockEvent, WfContext, WfExitValue, WorkflowFunction, WorkflowResult,
4
4
  };
5
5
  use anyhow::{anyhow, bail, Context as AnyhowContext, Error};
6
6
  use crossbeam::channel::Receiver;
@@ -62,7 +62,9 @@ impl WorkflowFunction {
62
62
  // We need to mark the workflow future as unconstrained, otherwise Tokio will impose
63
63
  // an artificial limit on how many commands we can unblock in one poll round.
64
64
  // TODO: Now we *need* deadlock detection or we could hose the whole system
65
- inner: tokio::task::unconstrained((self.wf_func)(wf_context)).boxed(),
65
+ inner: tokio::task::unconstrained((self.wf_func)(wf_context))
66
+ .fuse()
67
+ .boxed(),
66
68
  incoming_commands: cmd_receiver,
67
69
  outgoing_completions,
68
70
  incoming_activations,
@@ -214,6 +216,9 @@ impl WorkflowFuture {
214
216
  }
215
217
 
216
218
  Variant::RemoveFromCache(_) => {
219
+ // TODO: Need to abort any spawned tasks, etc. See also cancel WF.
220
+ // How best to do this in executor agnostic way? Is that possible?
221
+ // -- tokio JoinSet does this in a nice way.
217
222
  return Ok(true);
218
223
  }
219
224
  }
@@ -279,11 +284,7 @@ impl Future for WorkflowFuture {
279
284
  .poll_unpin(cx)
280
285
  {
281
286
  Poll::Ready(Err(e)) => {
282
- let errmsg = format!(
283
- "Workflow function panicked: {:?}",
284
- // Panics are typically strings
285
- e.downcast::<String>()
286
- );
287
+ let errmsg = format!("Workflow function panicked: {}", panic_formatter(e));
287
288
  warn!("{}", errmsg);
288
289
  self.outgoing_completions
289
290
  .send(WorkflowActivationCompletion::fail(