temporalio 0.4.0-aarch64-linux-musl

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 (183) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +2 -0
  3. data/Gemfile +27 -0
  4. data/Rakefile +101 -0
  5. data/lib/temporalio/activity/complete_async_error.rb +11 -0
  6. data/lib/temporalio/activity/context.rb +123 -0
  7. data/lib/temporalio/activity/definition.rb +192 -0
  8. data/lib/temporalio/activity/info.rb +67 -0
  9. data/lib/temporalio/activity.rb +12 -0
  10. data/lib/temporalio/api/activity/v1/message.rb +25 -0
  11. data/lib/temporalio/api/batch/v1/message.rb +36 -0
  12. data/lib/temporalio/api/cloud/account/v1/message.rb +28 -0
  13. data/lib/temporalio/api/cloud/cloudservice/v1/request_response.rb +126 -0
  14. data/lib/temporalio/api/cloud/cloudservice/v1/service.rb +25 -0
  15. data/lib/temporalio/api/cloud/cloudservice.rb +3 -0
  16. data/lib/temporalio/api/cloud/identity/v1/message.rb +41 -0
  17. data/lib/temporalio/api/cloud/namespace/v1/message.rb +42 -0
  18. data/lib/temporalio/api/cloud/nexus/v1/message.rb +31 -0
  19. data/lib/temporalio/api/cloud/operation/v1/message.rb +28 -0
  20. data/lib/temporalio/api/cloud/region/v1/message.rb +24 -0
  21. data/lib/temporalio/api/cloud/resource/v1/message.rb +23 -0
  22. data/lib/temporalio/api/cloud/sink/v1/message.rb +24 -0
  23. data/lib/temporalio/api/cloud/usage/v1/message.rb +31 -0
  24. data/lib/temporalio/api/command/v1/message.rb +46 -0
  25. data/lib/temporalio/api/common/v1/grpc_status.rb +23 -0
  26. data/lib/temporalio/api/common/v1/message.rb +48 -0
  27. data/lib/temporalio/api/deployment/v1/message.rb +38 -0
  28. data/lib/temporalio/api/enums/v1/batch_operation.rb +22 -0
  29. data/lib/temporalio/api/enums/v1/command_type.rb +21 -0
  30. data/lib/temporalio/api/enums/v1/common.rb +26 -0
  31. data/lib/temporalio/api/enums/v1/deployment.rb +23 -0
  32. data/lib/temporalio/api/enums/v1/event_type.rb +21 -0
  33. data/lib/temporalio/api/enums/v1/failed_cause.rb +26 -0
  34. data/lib/temporalio/api/enums/v1/namespace.rb +23 -0
  35. data/lib/temporalio/api/enums/v1/nexus.rb +21 -0
  36. data/lib/temporalio/api/enums/v1/query.rb +22 -0
  37. data/lib/temporalio/api/enums/v1/reset.rb +23 -0
  38. data/lib/temporalio/api/enums/v1/schedule.rb +21 -0
  39. data/lib/temporalio/api/enums/v1/task_queue.rb +25 -0
  40. data/lib/temporalio/api/enums/v1/update.rb +22 -0
  41. data/lib/temporalio/api/enums/v1/workflow.rb +31 -0
  42. data/lib/temporalio/api/errordetails/v1/message.rb +44 -0
  43. data/lib/temporalio/api/export/v1/message.rb +24 -0
  44. data/lib/temporalio/api/failure/v1/message.rb +37 -0
  45. data/lib/temporalio/api/filter/v1/message.rb +27 -0
  46. data/lib/temporalio/api/history/v1/message.rb +92 -0
  47. data/lib/temporalio/api/namespace/v1/message.rb +31 -0
  48. data/lib/temporalio/api/nexus/v1/message.rb +41 -0
  49. data/lib/temporalio/api/operatorservice/v1/request_response.rb +49 -0
  50. data/lib/temporalio/api/operatorservice/v1/service.rb +23 -0
  51. data/lib/temporalio/api/operatorservice.rb +3 -0
  52. data/lib/temporalio/api/payload_visitor.rb +1581 -0
  53. data/lib/temporalio/api/protocol/v1/message.rb +23 -0
  54. data/lib/temporalio/api/query/v1/message.rb +28 -0
  55. data/lib/temporalio/api/replication/v1/message.rb +26 -0
  56. data/lib/temporalio/api/schedule/v1/message.rb +43 -0
  57. data/lib/temporalio/api/sdk/v1/enhanced_stack_trace.rb +25 -0
  58. data/lib/temporalio/api/sdk/v1/task_complete_metadata.rb +21 -0
  59. data/lib/temporalio/api/sdk/v1/user_metadata.rb +23 -0
  60. data/lib/temporalio/api/sdk/v1/workflow_metadata.rb +23 -0
  61. data/lib/temporalio/api/taskqueue/v1/message.rb +48 -0
  62. data/lib/temporalio/api/testservice/v1/request_response.rb +31 -0
  63. data/lib/temporalio/api/testservice/v1/service.rb +23 -0
  64. data/lib/temporalio/api/update/v1/message.rb +33 -0
  65. data/lib/temporalio/api/version/v1/message.rb +26 -0
  66. data/lib/temporalio/api/workflow/v1/message.rb +51 -0
  67. data/lib/temporalio/api/workflowservice/v1/request_response.rb +233 -0
  68. data/lib/temporalio/api/workflowservice/v1/service.rb +23 -0
  69. data/lib/temporalio/api/workflowservice.rb +3 -0
  70. data/lib/temporalio/api.rb +15 -0
  71. data/lib/temporalio/cancellation.rb +170 -0
  72. data/lib/temporalio/client/activity_id_reference.rb +32 -0
  73. data/lib/temporalio/client/async_activity_handle.rb +85 -0
  74. data/lib/temporalio/client/connection/cloud_service.rb +726 -0
  75. data/lib/temporalio/client/connection/operator_service.rb +201 -0
  76. data/lib/temporalio/client/connection/service.rb +42 -0
  77. data/lib/temporalio/client/connection/test_service.rb +111 -0
  78. data/lib/temporalio/client/connection/workflow_service.rb +1251 -0
  79. data/lib/temporalio/client/connection.rb +316 -0
  80. data/lib/temporalio/client/interceptor.rb +455 -0
  81. data/lib/temporalio/client/schedule.rb +991 -0
  82. data/lib/temporalio/client/schedule_handle.rb +126 -0
  83. data/lib/temporalio/client/with_start_workflow_operation.rb +115 -0
  84. data/lib/temporalio/client/workflow_execution.rb +119 -0
  85. data/lib/temporalio/client/workflow_execution_count.rb +36 -0
  86. data/lib/temporalio/client/workflow_execution_status.rb +18 -0
  87. data/lib/temporalio/client/workflow_handle.rb +389 -0
  88. data/lib/temporalio/client/workflow_query_reject_condition.rb +14 -0
  89. data/lib/temporalio/client/workflow_update_handle.rb +65 -0
  90. data/lib/temporalio/client/workflow_update_wait_stage.rb +17 -0
  91. data/lib/temporalio/client.rb +607 -0
  92. data/lib/temporalio/common_enums.rb +41 -0
  93. data/lib/temporalio/contrib/open_telemetry.rb +470 -0
  94. data/lib/temporalio/converters/data_converter.rb +99 -0
  95. data/lib/temporalio/converters/failure_converter.rb +202 -0
  96. data/lib/temporalio/converters/payload_codec.rb +26 -0
  97. data/lib/temporalio/converters/payload_converter/binary_null.rb +34 -0
  98. data/lib/temporalio/converters/payload_converter/binary_plain.rb +35 -0
  99. data/lib/temporalio/converters/payload_converter/binary_protobuf.rb +42 -0
  100. data/lib/temporalio/converters/payload_converter/composite.rb +66 -0
  101. data/lib/temporalio/converters/payload_converter/encoding.rb +35 -0
  102. data/lib/temporalio/converters/payload_converter/json_plain.rb +44 -0
  103. data/lib/temporalio/converters/payload_converter/json_protobuf.rb +41 -0
  104. data/lib/temporalio/converters/payload_converter.rb +71 -0
  105. data/lib/temporalio/converters/raw_value.rb +20 -0
  106. data/lib/temporalio/converters.rb +9 -0
  107. data/lib/temporalio/error/failure.rb +219 -0
  108. data/lib/temporalio/error.rb +156 -0
  109. data/lib/temporalio/internal/bridge/3.2/temporalio_bridge.so +0 -0
  110. data/lib/temporalio/internal/bridge/3.3/temporalio_bridge.so +0 -0
  111. data/lib/temporalio/internal/bridge/3.4/temporalio_bridge.so +0 -0
  112. data/lib/temporalio/internal/bridge/api/activity_result/activity_result.rb +34 -0
  113. data/lib/temporalio/internal/bridge/api/activity_task/activity_task.rb +31 -0
  114. data/lib/temporalio/internal/bridge/api/child_workflow/child_workflow.rb +33 -0
  115. data/lib/temporalio/internal/bridge/api/common/common.rb +27 -0
  116. data/lib/temporalio/internal/bridge/api/core_interface.rb +40 -0
  117. data/lib/temporalio/internal/bridge/api/external_data/external_data.rb +27 -0
  118. data/lib/temporalio/internal/bridge/api/nexus/nexus.rb +33 -0
  119. data/lib/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rb +56 -0
  120. data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +57 -0
  121. data/lib/temporalio/internal/bridge/api/workflow_completion/workflow_completion.rb +31 -0
  122. data/lib/temporalio/internal/bridge/api.rb +3 -0
  123. data/lib/temporalio/internal/bridge/client.rb +95 -0
  124. data/lib/temporalio/internal/bridge/runtime.rb +56 -0
  125. data/lib/temporalio/internal/bridge/testing.rb +69 -0
  126. data/lib/temporalio/internal/bridge/worker.rb +85 -0
  127. data/lib/temporalio/internal/bridge.rb +36 -0
  128. data/lib/temporalio/internal/client/implementation.rb +922 -0
  129. data/lib/temporalio/internal/metric.rb +122 -0
  130. data/lib/temporalio/internal/proto_utils.rb +165 -0
  131. data/lib/temporalio/internal/worker/activity_worker.rb +385 -0
  132. data/lib/temporalio/internal/worker/multi_runner.rb +213 -0
  133. data/lib/temporalio/internal/worker/workflow_instance/child_workflow_handle.rb +54 -0
  134. data/lib/temporalio/internal/worker/workflow_instance/context.rb +383 -0
  135. data/lib/temporalio/internal/worker/workflow_instance/details.rb +46 -0
  136. data/lib/temporalio/internal/worker/workflow_instance/external_workflow_handle.rb +32 -0
  137. data/lib/temporalio/internal/worker/workflow_instance/externally_immutable_hash.rb +22 -0
  138. data/lib/temporalio/internal/worker/workflow_instance/handler_execution.rb +25 -0
  139. data/lib/temporalio/internal/worker/workflow_instance/handler_hash.rb +41 -0
  140. data/lib/temporalio/internal/worker/workflow_instance/illegal_call_tracer.rb +97 -0
  141. data/lib/temporalio/internal/worker/workflow_instance/inbound_implementation.rb +62 -0
  142. data/lib/temporalio/internal/worker/workflow_instance/outbound_implementation.rb +400 -0
  143. data/lib/temporalio/internal/worker/workflow_instance/replay_safe_logger.rb +37 -0
  144. data/lib/temporalio/internal/worker/workflow_instance/replay_safe_metric.rb +40 -0
  145. data/lib/temporalio/internal/worker/workflow_instance/scheduler.rb +183 -0
  146. data/lib/temporalio/internal/worker/workflow_instance.rb +774 -0
  147. data/lib/temporalio/internal/worker/workflow_worker.rb +239 -0
  148. data/lib/temporalio/internal.rb +7 -0
  149. data/lib/temporalio/metric.rb +109 -0
  150. data/lib/temporalio/retry_policy.rb +74 -0
  151. data/lib/temporalio/runtime/metric_buffer.rb +94 -0
  152. data/lib/temporalio/runtime.rb +352 -0
  153. data/lib/temporalio/scoped_logger.rb +96 -0
  154. data/lib/temporalio/search_attributes.rb +356 -0
  155. data/lib/temporalio/testing/activity_environment.rb +160 -0
  156. data/lib/temporalio/testing/workflow_environment.rb +406 -0
  157. data/lib/temporalio/testing.rb +10 -0
  158. data/lib/temporalio/version.rb +5 -0
  159. data/lib/temporalio/worker/activity_executor/fiber.rb +49 -0
  160. data/lib/temporalio/worker/activity_executor/thread_pool.rb +46 -0
  161. data/lib/temporalio/worker/activity_executor.rb +55 -0
  162. data/lib/temporalio/worker/interceptor.rb +365 -0
  163. data/lib/temporalio/worker/thread_pool.rb +237 -0
  164. data/lib/temporalio/worker/tuner.rb +189 -0
  165. data/lib/temporalio/worker/workflow_executor/thread_pool.rb +235 -0
  166. data/lib/temporalio/worker/workflow_executor.rb +26 -0
  167. data/lib/temporalio/worker/workflow_replayer.rb +350 -0
  168. data/lib/temporalio/worker.rb +603 -0
  169. data/lib/temporalio/workflow/activity_cancellation_type.rb +20 -0
  170. data/lib/temporalio/workflow/child_workflow_cancellation_type.rb +21 -0
  171. data/lib/temporalio/workflow/child_workflow_handle.rb +43 -0
  172. data/lib/temporalio/workflow/definition.rb +598 -0
  173. data/lib/temporalio/workflow/external_workflow_handle.rb +41 -0
  174. data/lib/temporalio/workflow/future.rb +151 -0
  175. data/lib/temporalio/workflow/handler_unfinished_policy.rb +13 -0
  176. data/lib/temporalio/workflow/info.rb +104 -0
  177. data/lib/temporalio/workflow/parent_close_policy.rb +19 -0
  178. data/lib/temporalio/workflow/update_info.rb +20 -0
  179. data/lib/temporalio/workflow.rb +575 -0
  180. data/lib/temporalio/workflow_history.rb +47 -0
  181. data/lib/temporalio.rb +11 -0
  182. data/temporalio.gemspec +29 -0
  183. metadata +258 -0
@@ -0,0 +1,922 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'google/protobuf/well_known_types'
4
+ require 'securerandom'
5
+ require 'temporalio/api'
6
+ require 'temporalio/client/activity_id_reference'
7
+ require 'temporalio/client/async_activity_handle'
8
+ require 'temporalio/client/connection'
9
+ require 'temporalio/client/interceptor'
10
+ require 'temporalio/client/schedule'
11
+ require 'temporalio/client/schedule_handle'
12
+ require 'temporalio/client/with_start_workflow_operation'
13
+ require 'temporalio/client/workflow_execution'
14
+ require 'temporalio/client/workflow_execution_count'
15
+ require 'temporalio/client/workflow_handle'
16
+ require 'temporalio/common_enums'
17
+ require 'temporalio/converters'
18
+ require 'temporalio/error'
19
+ require 'temporalio/error/failure'
20
+ require 'temporalio/internal/proto_utils'
21
+ require 'temporalio/runtime'
22
+ require 'temporalio/search_attributes'
23
+ require 'temporalio/workflow/definition'
24
+
25
+ module Temporalio
26
+ module Internal
27
+ module Client
28
+ class Implementation < Temporalio::Client::Interceptor::Outbound
29
+ def self.with_default_rpc_options(user_rpc_options)
30
+ # If the user did not provide an override_retry, we need to make sure
31
+ # we use an option set that has it as "true"
32
+ if user_rpc_options.nil?
33
+ user_rpc_options = @always_retry_options ||= Temporalio::Client::RPCOptions.new(override_retry: true)
34
+ elsif !user_rpc_options.is_a?(Temporalio::Client::RPCOptions)
35
+ raise ArgumentError, 'rpc_options must be RPCOptions'
36
+ elsif user_rpc_options.override_retry.nil?
37
+ # Copy and set as true
38
+ user_rpc_options = user_rpc_options.dup
39
+ user_rpc_options.override_retry = true
40
+ end
41
+ user_rpc_options
42
+ end
43
+
44
+ def initialize(client)
45
+ super(nil) # steep:ignore
46
+ @client = client
47
+ end
48
+
49
+ def start_workflow(input)
50
+ req = Api::WorkflowService::V1::StartWorkflowExecutionRequest.new(
51
+ request_id: SecureRandom.uuid,
52
+ namespace: @client.namespace,
53
+ workflow_type: Api::Common::V1::WorkflowType.new(name: input.workflow),
54
+ workflow_id: input.workflow_id,
55
+ task_queue: Api::TaskQueue::V1::TaskQueue.new(name: input.task_queue.to_s),
56
+ input: @client.data_converter.to_payloads(input.args),
57
+ workflow_execution_timeout: ProtoUtils.seconds_to_duration(input.execution_timeout),
58
+ workflow_run_timeout: ProtoUtils.seconds_to_duration(input.run_timeout),
59
+ workflow_task_timeout: ProtoUtils.seconds_to_duration(input.task_timeout),
60
+ identity: @client.connection.identity,
61
+ workflow_id_reuse_policy: input.id_reuse_policy,
62
+ workflow_id_conflict_policy: input.id_conflict_policy,
63
+ retry_policy: input.retry_policy&._to_proto,
64
+ cron_schedule: input.cron_schedule,
65
+ memo: ProtoUtils.memo_to_proto(input.memo, @client.data_converter),
66
+ search_attributes: input.search_attributes&._to_proto,
67
+ workflow_start_delay: ProtoUtils.seconds_to_duration(input.start_delay),
68
+ request_eager_execution: input.request_eager_start,
69
+ user_metadata: ProtoUtils.to_user_metadata(
70
+ input.static_summary, input.static_details, @client.data_converter
71
+ ),
72
+ header: ProtoUtils.headers_to_proto(input.headers, @client.data_converter)
73
+ )
74
+
75
+ # Send request
76
+ begin
77
+ resp = @client.workflow_service.start_workflow_execution(
78
+ req,
79
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
80
+ )
81
+ rescue Error::RPCError => e
82
+ # Unpack and raise already started if that's the error, otherwise default raise
83
+ if e.code == Error::RPCError::Code::ALREADY_EXISTS && e.grpc_status.details.first
84
+ details = e.grpc_status.details.first.unpack(
85
+ Api::ErrorDetails::V1::WorkflowExecutionAlreadyStartedFailure
86
+ )
87
+ if details
88
+ raise Error::WorkflowAlreadyStartedError.new(
89
+ workflow_id: req.workflow_id,
90
+ workflow_type: req.workflow_type.name,
91
+ run_id: details.run_id
92
+ )
93
+ end
94
+ end
95
+ raise
96
+ end
97
+
98
+ # Return handle
99
+ Temporalio::Client::WorkflowHandle.new(
100
+ client: @client,
101
+ id: input.workflow_id,
102
+ run_id: nil,
103
+ result_run_id: resp.run_id,
104
+ first_execution_run_id: resp.run_id
105
+ )
106
+ end
107
+
108
+ def start_update_with_start_workflow(input)
109
+ raise ArgumentError, 'Start operation is required' unless input.start_workflow_operation
110
+
111
+ if input.start_workflow_operation.options.id_conflict_policy == WorkflowIDConflictPolicy::UNSPECIFIED
112
+ raise ArgumentError, 'ID conflict policy is required in start operation'
113
+ end
114
+
115
+ # Try to mark used before using
116
+ input.start_workflow_operation._mark_used
117
+
118
+ # Build request
119
+ start_options = input.start_workflow_operation.options
120
+ start_req = _start_workflow_request_from_with_start_options(
121
+ Api::WorkflowService::V1::StartWorkflowExecutionRequest, start_options
122
+ )
123
+ req = Api::WorkflowService::V1::ExecuteMultiOperationRequest.new(
124
+ namespace: @client.namespace,
125
+ operations: [
126
+ Api::WorkflowService::V1::ExecuteMultiOperationRequest::Operation.new(start_workflow: start_req),
127
+ Api::WorkflowService::V1::ExecuteMultiOperationRequest::Operation.new(
128
+ update_workflow: Api::WorkflowService::V1::UpdateWorkflowExecutionRequest.new(
129
+ namespace: @client.namespace,
130
+ workflow_execution: Api::Common::V1::WorkflowExecution.new(
131
+ workflow_id: start_options.id
132
+ ),
133
+ request: Api::Update::V1::Request.new(
134
+ meta: Api::Update::V1::Meta.new(
135
+ update_id: input.update_id,
136
+ identity: @client.connection.identity
137
+ ),
138
+ input: Api::Update::V1::Input.new(
139
+ name: input.update,
140
+ args: @client.data_converter.to_payloads(input.args),
141
+ header: Internal::ProtoUtils.headers_to_proto(input.headers, @client.data_converter)
142
+ )
143
+ ),
144
+ wait_policy: Api::Update::V1::WaitPolicy.new(
145
+ lifecycle_stage: input.wait_for_stage
146
+ )
147
+ )
148
+ )
149
+ ]
150
+ )
151
+
152
+ # Continually try to start until an exception occurs, the user-asked stage is reached, or the stage is
153
+ # accepted. But we will set the workflow handle as soon as we can.
154
+ # @type var update_resp: untyped
155
+ update_resp = nil
156
+ run_id = nil
157
+ begin
158
+ loop do
159
+ resp = @client.workflow_service.execute_multi_operation(
160
+ req, rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
161
+ )
162
+ run_id = resp.responses.first.start_workflow.run_id
163
+ # Set workflow handle (no-op if already set)
164
+ input.start_workflow_operation._set_workflow_handle(
165
+ Temporalio::Client::WorkflowHandle.new(
166
+ client: @client,
167
+ id: start_options.id,
168
+ run_id: nil,
169
+ result_run_id: run_id,
170
+ first_execution_run_id: run_id
171
+ )
172
+ )
173
+ update_resp = resp.responses.last.update_workflow
174
+
175
+ # We're only done if the response stage is at least accepted
176
+ if update_resp && Api::Enums::V1::UpdateWorkflowExecutionLifecycleStage.resolve(update_resp.stage) >=
177
+ Temporalio::Client::WorkflowUpdateWaitStage::ACCEPTED
178
+ break
179
+ end
180
+ end
181
+
182
+ # If the user wants to wait until completed, we must poll until outcome if not already there
183
+ if input.wait_for_stage == Temporalio::Client::WorkflowUpdateWaitStage::COMPLETED && update_resp.outcome
184
+ update_resp.outcome = @client._impl.poll_workflow_update(
185
+ Temporalio::Client::Interceptor::PollWorkflowUpdateInput.new(
186
+ workflow_id: start_options.id,
187
+ run_id:,
188
+ update_id: input.update_id,
189
+ rpc_options: input.rpc_options
190
+ )
191
+ )
192
+ end
193
+ rescue Error => e
194
+ # If this is a multi-operation failure, set exception to the first present, non-OK, non-aborted error
195
+ if e.is_a?(Error::RPCError)
196
+ multi_err = e.grpc_status.details&.first&.unpack(Api::ErrorDetails::V1::MultiOperationExecutionFailure)
197
+ if multi_err
198
+ non_aborted = multi_err.statuses.find do |s|
199
+ # Exists, not-ok, not-aborted
200
+ s && s.code != Error::RPCError::Code::OK &&
201
+ !s.details&.first&.is(Api::Failure::V1::MultiOperationExecutionAborted)
202
+ end
203
+ if non_aborted
204
+ e = Error::RPCError.new(
205
+ non_aborted.message,
206
+ code: non_aborted.code,
207
+ raw_grpc_status: Api::Common::V1::GrpcStatus.new(
208
+ code: non_aborted.code, message: non_aborted.message, details: non_aborted.details.to_a
209
+ )
210
+ )
211
+ end
212
+ end
213
+ end
214
+ if e.is_a?(Error::RPCError)
215
+ # Deadline exceeded or cancel is a special error type
216
+ if e.code == Error::RPCError::Code::DEADLINE_EXCEEDED || e.code == Error::RPCError::Code::CANCELED
217
+ e = Error::WorkflowUpdateRPCTimeoutOrCanceledError.new
218
+ elsif e.code == Error::RPCError::Code::ALREADY_EXISTS && e.grpc_status.details.first
219
+ # Unpack and set already started if that's the error
220
+ details = e.grpc_status.details.first.unpack(
221
+ Api::ErrorDetails::V1::WorkflowExecutionAlreadyStartedFailure
222
+ )
223
+ if details
224
+ e = Error::WorkflowAlreadyStartedError.new(
225
+ workflow_id: start_options.id,
226
+ workflow_type: start_req.workflow_type,
227
+ run_id: details.run_id
228
+ )
229
+ end
230
+ end
231
+ end
232
+ # Cancel is a special type
233
+ e = Error::WorkflowUpdateRPCTimeoutOrCanceledError.new if e.is_a?(Error::CanceledError)
234
+ # Before we raise here, we want to try to set the start operation exception (no-op if already set with a
235
+ # handle)
236
+ input.start_workflow_operation._set_workflow_handle(e)
237
+ raise e
238
+ end
239
+
240
+ # Return handle
241
+ Temporalio::Client::WorkflowUpdateHandle.new(
242
+ client: @client,
243
+ id: input.update_id,
244
+ workflow_id: start_options.id,
245
+ workflow_run_id: run_id,
246
+ known_outcome: update_resp.outcome
247
+ )
248
+ end
249
+
250
+ def signal_with_start_workflow(input)
251
+ raise ArgumentError, 'Start operation is required' unless input.start_workflow_operation
252
+
253
+ # Try to mark used before using
254
+ input.start_workflow_operation._mark_used
255
+
256
+ # Build req
257
+ start_options = input.start_workflow_operation.options
258
+ req = _start_workflow_request_from_with_start_options(
259
+ Api::WorkflowService::V1::SignalWithStartWorkflowExecutionRequest, start_options
260
+ )
261
+ req.signal_name = input.signal
262
+ req.signal_input = @client.data_converter.to_payloads(input.args)
263
+
264
+ # Send request
265
+ begin
266
+ resp = @client.workflow_service.signal_with_start_workflow_execution(
267
+ req,
268
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
269
+ )
270
+ rescue Error::RPCError => e
271
+ # Unpack and raise already started if that's the error, otherwise default raise
272
+ if e.code == Error::RPCError::Code::ALREADY_EXISTS && e.grpc_status.details.first
273
+ details = e.grpc_status.details.first.unpack(
274
+ Api::ErrorDetails::V1::WorkflowExecutionAlreadyStartedFailure
275
+ )
276
+ if details
277
+ e = Error::WorkflowAlreadyStartedError.new(
278
+ workflow_id: req.workflow_id,
279
+ workflow_type: req.workflow_type.name,
280
+ run_id: details.run_id
281
+ )
282
+ end
283
+ end
284
+ # Before we raise here, we want to the start operation exception
285
+ input.start_workflow_operation._set_workflow_handle(e)
286
+ raise e
287
+ end
288
+
289
+ # Set handle and return handle
290
+ handle = Temporalio::Client::WorkflowHandle.new(
291
+ client: @client,
292
+ id: start_options.id,
293
+ run_id: nil,
294
+ result_run_id: resp.run_id,
295
+ first_execution_run_id: resp.run_id
296
+ )
297
+ input.start_workflow_operation._set_workflow_handle(handle)
298
+ handle
299
+ end
300
+
301
+ def _start_workflow_request_from_with_start_options(klass, start_options)
302
+ klass.new(
303
+ request_id: SecureRandom.uuid,
304
+ namespace: @client.namespace,
305
+ workflow_type: Api::Common::V1::WorkflowType.new(name: start_options.workflow),
306
+ workflow_id: start_options.id,
307
+ task_queue: Api::TaskQueue::V1::TaskQueue.new(name: start_options.task_queue.to_s),
308
+ input: @client.data_converter.to_payloads(start_options.args),
309
+ workflow_execution_timeout: ProtoUtils.seconds_to_duration(start_options.execution_timeout),
310
+ workflow_run_timeout: ProtoUtils.seconds_to_duration(start_options.run_timeout),
311
+ workflow_task_timeout: ProtoUtils.seconds_to_duration(start_options.task_timeout),
312
+ identity: @client.connection.identity,
313
+ workflow_id_reuse_policy: start_options.id_reuse_policy,
314
+ workflow_id_conflict_policy: start_options.id_conflict_policy,
315
+ retry_policy: start_options.retry_policy&._to_proto,
316
+ cron_schedule: start_options.cron_schedule,
317
+ memo: ProtoUtils.memo_to_proto(start_options.memo, @client.data_converter),
318
+ search_attributes: start_options.search_attributes&._to_proto,
319
+ workflow_start_delay: ProtoUtils.seconds_to_duration(start_options.start_delay),
320
+ user_metadata: ProtoUtils.to_user_metadata(
321
+ start_options.static_summary, start_options.static_details, @client.data_converter
322
+ ),
323
+ header: ProtoUtils.headers_to_proto(start_options.headers, @client.data_converter)
324
+ )
325
+ end
326
+
327
+ def list_workflows(input)
328
+ Enumerator.new do |yielder|
329
+ req = Api::WorkflowService::V1::ListWorkflowExecutionsRequest.new(
330
+ namespace: @client.namespace,
331
+ query: input.query || ''
332
+ )
333
+ loop do
334
+ resp = @client.workflow_service.list_workflow_executions(
335
+ req,
336
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
337
+ )
338
+ resp.executions.each do |raw_info|
339
+ yielder << Temporalio::Client::WorkflowExecution.new(raw_info, @client.data_converter)
340
+ end
341
+ break if resp.next_page_token.empty?
342
+
343
+ req.next_page_token = resp.next_page_token
344
+ end
345
+ end
346
+ end
347
+
348
+ def count_workflows(input)
349
+ resp = @client.workflow_service.count_workflow_executions(
350
+ Api::WorkflowService::V1::CountWorkflowExecutionsRequest.new(
351
+ namespace: @client.namespace,
352
+ query: input.query || ''
353
+ ),
354
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
355
+ )
356
+ Temporalio::Client::WorkflowExecutionCount.new(
357
+ resp.count,
358
+ resp.groups.map do |group|
359
+ Temporalio::Client::WorkflowExecutionCount::AggregationGroup.new(
360
+ group.count,
361
+ group.group_values.map { |payload| SearchAttributes._value_from_payload(payload) }
362
+ )
363
+ end
364
+ )
365
+ end
366
+
367
+ def describe_workflow(input)
368
+ resp = @client.workflow_service.describe_workflow_execution(
369
+ Api::WorkflowService::V1::DescribeWorkflowExecutionRequest.new(
370
+ namespace: @client.namespace,
371
+ execution: Api::Common::V1::WorkflowExecution.new(
372
+ workflow_id: input.workflow_id,
373
+ run_id: input.run_id || ''
374
+ )
375
+ ),
376
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
377
+ )
378
+ Temporalio::Client::WorkflowExecution::Description.new(resp, @client.data_converter)
379
+ end
380
+
381
+ def fetch_workflow_history_events(input)
382
+ Enumerator.new do |yielder|
383
+ req = Api::WorkflowService::V1::GetWorkflowExecutionHistoryRequest.new(
384
+ namespace: @client.namespace,
385
+ execution: Api::Common::V1::WorkflowExecution.new(
386
+ workflow_id: input.workflow_id,
387
+ run_id: input.run_id || ''
388
+ ),
389
+ wait_new_event: input.wait_new_event,
390
+ history_event_filter_type: input.event_filter_type,
391
+ skip_archival: input.skip_archival
392
+ )
393
+ loop do
394
+ resp = @client.workflow_service.get_workflow_execution_history(
395
+ req,
396
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
397
+ )
398
+ resp.history&.events&.each { |event| yielder << event }
399
+ break if resp.next_page_token.empty?
400
+
401
+ req.next_page_token = resp.next_page_token
402
+ end
403
+ end
404
+ end
405
+
406
+ def signal_workflow(input)
407
+ @client.workflow_service.signal_workflow_execution(
408
+ Api::WorkflowService::V1::SignalWorkflowExecutionRequest.new(
409
+ namespace: @client.namespace,
410
+ workflow_execution: Api::Common::V1::WorkflowExecution.new(
411
+ workflow_id: input.workflow_id,
412
+ run_id: input.run_id || ''
413
+ ),
414
+ signal_name: input.signal,
415
+ input: @client.data_converter.to_payloads(input.args),
416
+ header: Internal::ProtoUtils.headers_to_proto(input.headers, @client.data_converter),
417
+ identity: @client.connection.identity,
418
+ request_id: SecureRandom.uuid
419
+ ),
420
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
421
+ )
422
+ nil
423
+ end
424
+
425
+ def query_workflow(input)
426
+ begin
427
+ resp = @client.workflow_service.query_workflow(
428
+ Api::WorkflowService::V1::QueryWorkflowRequest.new(
429
+ namespace: @client.namespace,
430
+ execution: Api::Common::V1::WorkflowExecution.new(
431
+ workflow_id: input.workflow_id,
432
+ run_id: input.run_id || ''
433
+ ),
434
+ query: Api::Query::V1::WorkflowQuery.new(
435
+ query_type: input.query,
436
+ query_args: @client.data_converter.to_payloads(input.args),
437
+ header: Internal::ProtoUtils.headers_to_proto(input.headers, @client.data_converter)
438
+ ),
439
+ query_reject_condition: input.reject_condition || 0
440
+ ),
441
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
442
+ )
443
+ rescue Error::RPCError => e
444
+ # If the status is INVALID_ARGUMENT, we can assume it's a query failed
445
+ # error
446
+ raise Error::WorkflowQueryFailedError, e.message if e.code == Error::RPCError::Code::INVALID_ARGUMENT
447
+
448
+ raise
449
+ end
450
+ unless resp.query_rejected.nil?
451
+ raise Error::WorkflowQueryRejectedError.new(status: ProtoUtils.enum_to_int(
452
+ Api::Enums::V1::WorkflowExecutionStatus, resp.query_rejected.status
453
+ ))
454
+ end
455
+
456
+ results = @client.data_converter.from_payloads(resp.query_result)
457
+ warn("Expected 0 or 1 query result, got #{results.size}") if results.size > 1
458
+ results&.first
459
+ end
460
+
461
+ def start_workflow_update(input)
462
+ if input.wait_for_stage == Temporalio::Client::WorkflowUpdateWaitStage::ADMITTED
463
+ raise ArgumentError, 'ADMITTED wait stage not supported'
464
+ end
465
+
466
+ req = Api::WorkflowService::V1::UpdateWorkflowExecutionRequest.new(
467
+ namespace: @client.namespace,
468
+ workflow_execution: Api::Common::V1::WorkflowExecution.new(
469
+ workflow_id: input.workflow_id,
470
+ run_id: input.run_id || ''
471
+ ),
472
+ request: Api::Update::V1::Request.new(
473
+ meta: Api::Update::V1::Meta.new(
474
+ update_id: input.update_id,
475
+ identity: @client.connection.identity
476
+ ),
477
+ input: Api::Update::V1::Input.new(
478
+ name: input.update,
479
+ args: @client.data_converter.to_payloads(input.args),
480
+ header: Internal::ProtoUtils.headers_to_proto(input.headers, @client.data_converter)
481
+ )
482
+ ),
483
+ wait_policy: Api::Update::V1::WaitPolicy.new(
484
+ lifecycle_stage: input.wait_for_stage
485
+ )
486
+ )
487
+
488
+ # Repeatedly try to invoke start until the update reaches user-provided
489
+ # wait stage or is at least ACCEPTED (as of the time of this writing,
490
+ # the user cannot specify sooner than ACCEPTED)
491
+ # @type var resp: untyped
492
+ resp = nil
493
+ loop do
494
+ resp = @client.workflow_service.update_workflow_execution(
495
+ req,
496
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
497
+ )
498
+
499
+ # We're only done if the response stage is after the requested stage
500
+ # or the response stage is accepted
501
+ if resp.stage >= req.wait_policy.lifecycle_stage ||
502
+ resp.stage >= Temporalio::Client::WorkflowUpdateWaitStage::ACCEPTED
503
+ break
504
+ end
505
+ rescue Error::RPCError => e
506
+ # Deadline exceeded or cancel is a special error type
507
+ if e.code == Error::RPCError::Code::DEADLINE_EXCEEDED || e.code == Error::RPCError::Code::CANCELED
508
+ raise Error::WorkflowUpdateRPCTimeoutOrCanceledError
509
+ end
510
+
511
+ raise
512
+ rescue Error::CanceledError
513
+ raise Error::WorkflowUpdateRPCTimeoutOrCanceledError
514
+ end
515
+
516
+ # If the user wants to wait until completed, we must poll until outcome
517
+ # if not already there
518
+ if input.wait_for_stage == Temporalio::Client::WorkflowUpdateWaitStage::COMPLETED && !resp.outcome
519
+ resp.outcome = @client._impl.poll_workflow_update(
520
+ Temporalio::Client::Interceptor::PollWorkflowUpdateInput.new(
521
+ workflow_id: input.workflow_id,
522
+ run_id: input.run_id,
523
+ update_id: input.update_id,
524
+ rpc_options: input.rpc_options
525
+ )
526
+ )
527
+ end
528
+
529
+ Temporalio::Client::WorkflowUpdateHandle.new(
530
+ client: @client,
531
+ id: input.update_id,
532
+ workflow_id: input.workflow_id,
533
+ workflow_run_id: input.run_id,
534
+ known_outcome: resp.outcome
535
+ )
536
+ end
537
+
538
+ def poll_workflow_update(input)
539
+ req = Api::WorkflowService::V1::PollWorkflowExecutionUpdateRequest.new(
540
+ namespace: @client.namespace,
541
+ update_ref: Api::Update::V1::UpdateRef.new(
542
+ workflow_execution: Api::Common::V1::WorkflowExecution.new(
543
+ workflow_id: input.workflow_id,
544
+ run_id: input.run_id || ''
545
+ ),
546
+ update_id: input.update_id
547
+ ),
548
+ identity: @client.connection.identity,
549
+ wait_policy: Api::Update::V1::WaitPolicy.new(
550
+ lifecycle_stage: Temporalio::Client::WorkflowUpdateWaitStage::COMPLETED
551
+ )
552
+ )
553
+
554
+ # Continue polling as long as we have no outcome
555
+ loop do
556
+ resp = @client.workflow_service.poll_workflow_execution_update(
557
+ req,
558
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
559
+ )
560
+ return resp.outcome if resp.outcome
561
+ rescue Error::RPCError => e
562
+ # Deadline exceeded or cancel is a special error type
563
+ if e.code == Error::RPCError::Code::DEADLINE_EXCEEDED || e.code == Error::RPCError::Code::CANCELED
564
+ raise Error::WorkflowUpdateRPCTimeoutOrCanceledError
565
+ end
566
+
567
+ raise
568
+ end
569
+ end
570
+
571
+ def cancel_workflow(input)
572
+ @client.workflow_service.request_cancel_workflow_execution(
573
+ Api::WorkflowService::V1::RequestCancelWorkflowExecutionRequest.new(
574
+ namespace: @client.namespace,
575
+ workflow_execution: Api::Common::V1::WorkflowExecution.new(
576
+ workflow_id: input.workflow_id,
577
+ run_id: input.run_id || ''
578
+ ),
579
+ first_execution_run_id: input.first_execution_run_id,
580
+ identity: @client.connection.identity,
581
+ request_id: SecureRandom.uuid
582
+ ),
583
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
584
+ )
585
+ nil
586
+ end
587
+
588
+ def terminate_workflow(input)
589
+ @client.workflow_service.terminate_workflow_execution(
590
+ Api::WorkflowService::V1::TerminateWorkflowExecutionRequest.new(
591
+ namespace: @client.namespace,
592
+ workflow_execution: Api::Common::V1::WorkflowExecution.new(
593
+ workflow_id: input.workflow_id,
594
+ run_id: input.run_id || ''
595
+ ),
596
+ reason: input.reason || '',
597
+ first_execution_run_id: input.first_execution_run_id,
598
+ details: @client.data_converter.to_payloads(input.details),
599
+ identity: @client.connection.identity
600
+ ),
601
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
602
+ )
603
+ nil
604
+ end
605
+
606
+ def create_schedule(input)
607
+ if input.schedule.state.limited_actions && input.schedule.state.remaining_actions.zero?
608
+ raise 'Must set limited actions to false if there are no remaining actions set'
609
+ end
610
+ if !input.schedule.state.limited_actions && !input.schedule.state.remaining_actions.zero?
611
+ raise 'Must set limited actions to true if there are remaining actions set'
612
+ end
613
+
614
+ @client.workflow_service.create_schedule(
615
+ Api::WorkflowService::V1::CreateScheduleRequest.new(
616
+ namespace: @client.namespace,
617
+ schedule_id: input.id,
618
+ schedule: input.schedule._to_proto(@client.data_converter),
619
+ initial_patch: if input.trigger_immediately || !input.backfills.empty?
620
+ Api::Schedule::V1::SchedulePatch.new(
621
+ trigger_immediately: if input.trigger_immediately
622
+ Api::Schedule::V1::TriggerImmediatelyRequest.new(
623
+ overlap_policy: input.schedule.policy.overlap
624
+ )
625
+ end,
626
+ backfill_request: input.backfills.map(&:_to_proto)
627
+ )
628
+ end,
629
+ identity: @client.connection.identity,
630
+ request_id: SecureRandom.uuid,
631
+ memo: ProtoUtils.memo_to_proto(input.memo, @client.data_converter),
632
+ search_attributes: input.search_attributes&._to_proto
633
+ ),
634
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
635
+ )
636
+ Temporalio::Client::ScheduleHandle.new(client: @client, id: input.id)
637
+ rescue Error::RPCError => e
638
+ # Unpack and raise already started if that's the error, otherwise default raise
639
+ details = if e.code == Error::RPCError::Code::ALREADY_EXISTS && e.grpc_status.details.first
640
+ e.grpc_status.details.first.unpack(Api::ErrorDetails::V1::WorkflowExecutionAlreadyStartedFailure)
641
+ end
642
+ raise Error::ScheduleAlreadyRunningError if details
643
+
644
+ raise
645
+ end
646
+
647
+ def list_schedules(input)
648
+ Enumerator.new do |yielder|
649
+ req = Api::WorkflowService::V1::ListSchedulesRequest.new(
650
+ namespace: @client.namespace,
651
+ query: input.query || ''
652
+ )
653
+ loop do
654
+ resp = @client.workflow_service.list_schedules(
655
+ req,
656
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
657
+ )
658
+ resp.schedules.each do |raw_entry|
659
+ yielder << Temporalio::Client::Schedule::List::Description.new(
660
+ raw_entry:,
661
+ data_converter: @client.data_converter
662
+ )
663
+ end
664
+ break if resp.next_page_token.empty?
665
+
666
+ req.next_page_token = resp.next_page_token
667
+ end
668
+ end
669
+ end
670
+
671
+ def backfill_schedule(input)
672
+ @client.workflow_service.patch_schedule(
673
+ Api::WorkflowService::V1::PatchScheduleRequest.new(
674
+ namespace: @client.namespace,
675
+ schedule_id: input.id,
676
+ patch: Api::Schedule::V1::SchedulePatch.new(
677
+ backfill_request: input.backfills.map(&:_to_proto)
678
+ ),
679
+ identity: @client.connection.identity,
680
+ request_id: SecureRandom.uuid
681
+ ),
682
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
683
+ )
684
+ nil
685
+ end
686
+
687
+ def delete_schedule(input)
688
+ @client.workflow_service.delete_schedule(
689
+ Api::WorkflowService::V1::DeleteScheduleRequest.new(
690
+ namespace: @client.namespace,
691
+ schedule_id: input.id,
692
+ identity: @client.connection.identity
693
+ ),
694
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
695
+ )
696
+ nil
697
+ end
698
+
699
+ def describe_schedule(input)
700
+ Temporalio::Client::Schedule::Description.new(
701
+ id: input.id,
702
+ raw_description: @client.workflow_service.describe_schedule(
703
+ Api::WorkflowService::V1::DescribeScheduleRequest.new(
704
+ namespace: @client.namespace,
705
+ schedule_id: input.id
706
+ ),
707
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
708
+ ),
709
+ data_converter: @client.data_converter
710
+ )
711
+ end
712
+
713
+ def pause_schedule(input)
714
+ @client.workflow_service.patch_schedule(
715
+ Api::WorkflowService::V1::PatchScheduleRequest.new(
716
+ namespace: @client.namespace,
717
+ schedule_id: input.id,
718
+ patch: Api::Schedule::V1::SchedulePatch.new(pause: input.note),
719
+ identity: @client.connection.identity,
720
+ request_id: SecureRandom.uuid
721
+ ),
722
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
723
+ )
724
+ nil
725
+ end
726
+
727
+ def trigger_schedule(input)
728
+ @client.workflow_service.patch_schedule(
729
+ Api::WorkflowService::V1::PatchScheduleRequest.new(
730
+ namespace: @client.namespace,
731
+ schedule_id: input.id,
732
+ patch: Api::Schedule::V1::SchedulePatch.new(
733
+ trigger_immediately: Api::Schedule::V1::TriggerImmediatelyRequest.new(
734
+ overlap_policy: input.overlap || 0
735
+ )
736
+ ),
737
+ identity: @client.connection.identity,
738
+ request_id: SecureRandom.uuid
739
+ ),
740
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
741
+ )
742
+ nil
743
+ end
744
+
745
+ def unpause_schedule(input)
746
+ @client.workflow_service.patch_schedule(
747
+ Api::WorkflowService::V1::PatchScheduleRequest.new(
748
+ namespace: @client.namespace,
749
+ schedule_id: input.id,
750
+ patch: Api::Schedule::V1::SchedulePatch.new(unpause: input.note),
751
+ identity: @client.connection.identity,
752
+ request_id: SecureRandom.uuid
753
+ ),
754
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
755
+ )
756
+ nil
757
+ end
758
+
759
+ def update_schedule(input)
760
+ # TODO(cretz): This is supposed to be a retry-conflict loop, but we do
761
+ # not yet have a way to know update failure is due to conflict token
762
+ # mismatch
763
+ update = input.updater.call(
764
+ Temporalio::Client::Schedule::Update::Input.new(
765
+ description: Temporalio::Client::Schedule::Description.new(
766
+ id: input.id,
767
+ raw_description: @client.workflow_service.describe_schedule(
768
+ Api::WorkflowService::V1::DescribeScheduleRequest.new(
769
+ namespace: @client.namespace,
770
+ schedule_id: input.id
771
+ ),
772
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
773
+ ),
774
+ data_converter: @client.data_converter
775
+ )
776
+ )
777
+ )
778
+ # Do nothing if update is nil, fail if not an expected update
779
+ return nil if update.nil?
780
+
781
+ unless update.is_a?(Temporalio::Client::Schedule::Update)
782
+ raise TypeError,
783
+ 'Expected result of update block to be a Schedule::Update'
784
+ end
785
+
786
+ @client.workflow_service.update_schedule(
787
+ Api::WorkflowService::V1::UpdateScheduleRequest.new(
788
+ namespace: @client.namespace,
789
+ schedule_id: input.id,
790
+ schedule: update.schedule._to_proto(@client.data_converter),
791
+ search_attributes: update.search_attributes&._to_proto,
792
+ identity: @client.connection.identity,
793
+ request_id: SecureRandom.uuid
794
+ ),
795
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
796
+ )
797
+ nil
798
+ end
799
+
800
+ def heartbeat_async_activity(input)
801
+ resp = if input.task_token_or_id_reference.is_a?(Temporalio::Client::ActivityIDReference)
802
+ @client.workflow_service.record_activity_task_heartbeat_by_id(
803
+ Api::WorkflowService::V1::RecordActivityTaskHeartbeatByIdRequest.new(
804
+ workflow_id: input.task_token_or_id_reference.workflow_id,
805
+ run_id: input.task_token_or_id_reference.run_id,
806
+ activity_id: input.task_token_or_id_reference.activity_id,
807
+ namespace: @client.namespace,
808
+ identity: @client.connection.identity,
809
+ details: @client.data_converter.to_payloads(input.details)
810
+ ),
811
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
812
+ )
813
+ else
814
+ @client.workflow_service.record_activity_task_heartbeat(
815
+ Api::WorkflowService::V1::RecordActivityTaskHeartbeatRequest.new(
816
+ task_token: input.task_token_or_id_reference,
817
+ namespace: @client.namespace,
818
+ identity: @client.connection.identity,
819
+ details: @client.data_converter.to_payloads(input.details)
820
+ ),
821
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
822
+ )
823
+ end
824
+ raise Error::AsyncActivityCanceledError if resp.cancel_requested
825
+
826
+ nil
827
+ end
828
+
829
+ def complete_async_activity(input)
830
+ if input.task_token_or_id_reference.is_a?(Temporalio::Client::ActivityIDReference)
831
+ @client.workflow_service.respond_activity_task_completed_by_id(
832
+ Api::WorkflowService::V1::RespondActivityTaskCompletedByIdRequest.new(
833
+ workflow_id: input.task_token_or_id_reference.workflow_id,
834
+ run_id: input.task_token_or_id_reference.run_id,
835
+ activity_id: input.task_token_or_id_reference.activity_id,
836
+ namespace: @client.namespace,
837
+ identity: @client.connection.identity,
838
+ result: @client.data_converter.to_payloads([input.result])
839
+ ),
840
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
841
+ )
842
+ else
843
+ @client.workflow_service.respond_activity_task_completed(
844
+ Api::WorkflowService::V1::RespondActivityTaskCompletedRequest.new(
845
+ task_token: input.task_token_or_id_reference,
846
+ namespace: @client.namespace,
847
+ identity: @client.connection.identity,
848
+ result: @client.data_converter.to_payloads([input.result])
849
+ ),
850
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
851
+ )
852
+ end
853
+ nil
854
+ end
855
+
856
+ def fail_async_activity(input)
857
+ if input.task_token_or_id_reference.is_a?(Temporalio::Client::ActivityIDReference)
858
+ @client.workflow_service.respond_activity_task_failed_by_id(
859
+ Api::WorkflowService::V1::RespondActivityTaskFailedByIdRequest.new(
860
+ workflow_id: input.task_token_or_id_reference.workflow_id,
861
+ run_id: input.task_token_or_id_reference.run_id,
862
+ activity_id: input.task_token_or_id_reference.activity_id,
863
+ namespace: @client.namespace,
864
+ identity: @client.connection.identity,
865
+ failure: @client.data_converter.to_failure(input.error),
866
+ last_heartbeat_details: if input.last_heartbeat_details.empty?
867
+ nil
868
+ else
869
+ @client.data_converter.to_payloads(input.last_heartbeat_details)
870
+ end
871
+ ),
872
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
873
+ )
874
+ else
875
+ @client.workflow_service.respond_activity_task_failed(
876
+ Api::WorkflowService::V1::RespondActivityTaskFailedRequest.new(
877
+ task_token: input.task_token_or_id_reference,
878
+ namespace: @client.namespace,
879
+ identity: @client.connection.identity,
880
+ failure: @client.data_converter.to_failure(input.error),
881
+ last_heartbeat_details: if input.last_heartbeat_details.empty?
882
+ nil
883
+ else
884
+ @client.data_converter.to_payloads(input.last_heartbeat_details)
885
+ end
886
+ ),
887
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
888
+ )
889
+ end
890
+ nil
891
+ end
892
+
893
+ def report_cancellation_async_activity(input)
894
+ if input.task_token_or_id_reference.is_a?(Temporalio::Client::ActivityIDReference)
895
+ @client.workflow_service.respond_activity_task_canceled_by_id(
896
+ Api::WorkflowService::V1::RespondActivityTaskCanceledByIdRequest.new(
897
+ workflow_id: input.task_token_or_id_reference.workflow_id,
898
+ run_id: input.task_token_or_id_reference.run_id,
899
+ activity_id: input.task_token_or_id_reference.activity_id,
900
+ namespace: @client.namespace,
901
+ identity: @client.connection.identity,
902
+ details: @client.data_converter.to_payloads(input.details)
903
+ ),
904
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
905
+ )
906
+ else
907
+ @client.workflow_service.respond_activity_task_canceled(
908
+ Api::WorkflowService::V1::RespondActivityTaskCanceledRequest.new(
909
+ task_token: input.task_token_or_id_reference,
910
+ namespace: @client.namespace,
911
+ identity: @client.connection.identity,
912
+ details: @client.data_converter.to_payloads(input.details)
913
+ ),
914
+ rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
915
+ )
916
+ end
917
+ nil
918
+ end
919
+ end
920
+ end
921
+ end
922
+ end