temporalio 0.3.0-aarch64-linux → 0.5.0-aarch64-linux

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 (152) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -1
  3. data/Gemfile +4 -0
  4. data/Rakefile +1 -1
  5. data/lib/temporalio/activity/cancellation_details.rb +58 -0
  6. data/lib/temporalio/activity/context.rb +23 -1
  7. data/lib/temporalio/activity/definition.rb +63 -8
  8. data/lib/temporalio/activity/info.rb +28 -4
  9. data/lib/temporalio/activity.rb +2 -0
  10. data/lib/temporalio/api/activity/v1/message.rb +1 -1
  11. data/lib/temporalio/api/batch/v1/message.rb +9 -2
  12. data/lib/temporalio/api/cloud/account/v1/message.rb +1 -1
  13. data/lib/temporalio/api/cloud/cloudservice/v1/request_response.rb +11 -2
  14. data/lib/temporalio/api/cloud/cloudservice/v1/service.rb +2 -2
  15. data/lib/temporalio/api/cloud/identity/v1/message.rb +7 -2
  16. data/lib/temporalio/api/cloud/namespace/v1/message.rb +6 -2
  17. data/lib/temporalio/api/cloud/nexus/v1/message.rb +3 -2
  18. data/lib/temporalio/api/cloud/operation/v1/message.rb +1 -1
  19. data/lib/temporalio/api/cloud/region/v1/message.rb +1 -1
  20. data/lib/temporalio/api/cloud/resource/v1/message.rb +1 -1
  21. data/lib/temporalio/api/cloud/sink/v1/message.rb +1 -1
  22. data/lib/temporalio/api/cloud/usage/v1/message.rb +1 -1
  23. data/lib/temporalio/api/command/v1/message.rb +2 -2
  24. data/lib/temporalio/api/common/v1/grpc_status.rb +1 -1
  25. data/lib/temporalio/api/common/v1/message.rb +4 -2
  26. data/lib/temporalio/api/deployment/v1/message.rb +39 -0
  27. data/lib/temporalio/api/enums/v1/batch_operation.rb +2 -2
  28. data/lib/temporalio/api/enums/v1/command_type.rb +1 -1
  29. data/lib/temporalio/api/enums/v1/common.rb +5 -2
  30. data/lib/temporalio/api/enums/v1/deployment.rb +24 -0
  31. data/lib/temporalio/api/enums/v1/event_type.rb +2 -2
  32. data/lib/temporalio/api/enums/v1/failed_cause.rb +2 -2
  33. data/lib/temporalio/api/enums/v1/namespace.rb +1 -1
  34. data/lib/temporalio/api/enums/v1/nexus.rb +21 -0
  35. data/lib/temporalio/api/enums/v1/query.rb +1 -1
  36. data/lib/temporalio/api/enums/v1/reset.rb +2 -2
  37. data/lib/temporalio/api/enums/v1/schedule.rb +1 -1
  38. data/lib/temporalio/api/enums/v1/task_queue.rb +1 -1
  39. data/lib/temporalio/api/enums/v1/update.rb +1 -1
  40. data/lib/temporalio/api/enums/v1/workflow.rb +3 -2
  41. data/lib/temporalio/api/errordetails/v1/message.rb +4 -2
  42. data/lib/temporalio/api/export/v1/message.rb +1 -1
  43. data/lib/temporalio/api/failure/v1/message.rb +5 -2
  44. data/lib/temporalio/api/filter/v1/message.rb +1 -1
  45. data/lib/temporalio/api/history/v1/message.rb +6 -2
  46. data/lib/temporalio/api/namespace/v1/message.rb +1 -1
  47. data/lib/temporalio/api/nexus/v1/message.rb +3 -2
  48. data/lib/temporalio/api/operatorservice/v1/request_response.rb +1 -1
  49. data/lib/temporalio/api/operatorservice/v1/service.rb +1 -1
  50. data/lib/temporalio/api/payload_visitor.rb +162 -7
  51. data/lib/temporalio/api/protocol/v1/message.rb +1 -1
  52. data/lib/temporalio/api/query/v1/message.rb +3 -2
  53. data/lib/temporalio/api/replication/v1/message.rb +1 -1
  54. data/lib/temporalio/api/rules/v1/message.rb +27 -0
  55. data/lib/temporalio/api/schedule/v1/message.rb +2 -2
  56. data/lib/temporalio/api/sdk/v1/enhanced_stack_trace.rb +1 -1
  57. data/lib/temporalio/api/sdk/v1/task_complete_metadata.rb +1 -1
  58. data/lib/temporalio/api/sdk/v1/user_metadata.rb +1 -1
  59. data/lib/temporalio/api/sdk/v1/workflow_metadata.rb +1 -1
  60. data/lib/temporalio/api/taskqueue/v1/message.rb +5 -2
  61. data/lib/temporalio/api/testservice/v1/request_response.rb +1 -1
  62. data/lib/temporalio/api/testservice/v1/service.rb +1 -1
  63. data/lib/temporalio/api/update/v1/message.rb +1 -1
  64. data/lib/temporalio/api/version/v1/message.rb +1 -1
  65. data/lib/temporalio/api/worker/v1/message.rb +30 -0
  66. data/lib/temporalio/api/workflow/v1/message.rb +22 -2
  67. data/lib/temporalio/api/workflowservice/v1/request_response.rb +58 -12
  68. data/lib/temporalio/api/workflowservice/v1/service.rb +2 -2
  69. data/lib/temporalio/api.rb +1 -0
  70. data/lib/temporalio/client/async_activity_handle.rb +12 -4
  71. data/lib/temporalio/client/connection/cloud_service.rb +60 -0
  72. data/lib/temporalio/client/connection/workflow_service.rb +343 -28
  73. data/lib/temporalio/client/interceptor.rb +64 -7
  74. data/lib/temporalio/client/schedule.rb +35 -3
  75. data/lib/temporalio/client/with_start_workflow_operation.rb +123 -0
  76. data/lib/temporalio/client/workflow_execution.rb +19 -0
  77. data/lib/temporalio/client/workflow_handle.rb +47 -7
  78. data/lib/temporalio/client/workflow_update_handle.rb +9 -3
  79. data/lib/temporalio/client.rb +231 -4
  80. data/lib/temporalio/common_enums.rb +14 -0
  81. data/lib/temporalio/contrib/open_telemetry.rb +474 -0
  82. data/lib/temporalio/converters/data_converter.rb +18 -8
  83. data/lib/temporalio/converters/failure_converter.rb +6 -3
  84. data/lib/temporalio/converters/payload_converter/binary_null.rb +2 -2
  85. data/lib/temporalio/converters/payload_converter/binary_plain.rb +2 -2
  86. data/lib/temporalio/converters/payload_converter/binary_protobuf.rb +2 -2
  87. data/lib/temporalio/converters/payload_converter/composite.rb +6 -4
  88. data/lib/temporalio/converters/payload_converter/encoding.rb +4 -2
  89. data/lib/temporalio/converters/payload_converter/json_plain.rb +2 -2
  90. data/lib/temporalio/converters/payload_converter/json_protobuf.rb +2 -2
  91. data/lib/temporalio/converters/payload_converter.rb +16 -6
  92. data/lib/temporalio/error/failure.rb +19 -1
  93. data/lib/temporalio/error.rb +2 -1
  94. data/lib/temporalio/internal/bridge/3.2/temporalio_bridge.so +0 -0
  95. data/lib/temporalio/internal/bridge/3.3/temporalio_bridge.so +0 -0
  96. data/lib/temporalio/internal/bridge/3.4/temporalio_bridge.so +0 -0
  97. data/lib/temporalio/internal/bridge/api/activity_result/activity_result.rb +1 -1
  98. data/lib/temporalio/internal/bridge/api/activity_task/activity_task.rb +3 -2
  99. data/lib/temporalio/internal/bridge/api/child_workflow/child_workflow.rb +1 -1
  100. data/lib/temporalio/internal/bridge/api/common/common.rb +3 -2
  101. data/lib/temporalio/internal/bridge/api/core_interface.rb +1 -1
  102. data/lib/temporalio/internal/bridge/api/external_data/external_data.rb +1 -1
  103. data/lib/temporalio/internal/bridge/api/nexus/nexus.rb +3 -2
  104. data/lib/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rb +2 -2
  105. data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +3 -2
  106. data/lib/temporalio/internal/bridge/api/workflow_completion/workflow_completion.rb +3 -2
  107. data/lib/temporalio/internal/bridge/runtime.rb +3 -0
  108. data/lib/temporalio/internal/bridge/testing.rb +3 -0
  109. data/lib/temporalio/internal/bridge/worker.rb +28 -4
  110. data/lib/temporalio/internal/bridge.rb +1 -1
  111. data/lib/temporalio/internal/client/implementation.rb +281 -51
  112. data/lib/temporalio/internal/proto_utils.rb +38 -6
  113. data/lib/temporalio/internal/worker/activity_worker.rb +112 -27
  114. data/lib/temporalio/internal/worker/multi_runner.rb +2 -2
  115. data/lib/temporalio/internal/worker/workflow_instance/child_workflow_handle.rb +8 -6
  116. data/lib/temporalio/internal/worker/workflow_instance/context.rb +100 -5
  117. data/lib/temporalio/internal/worker/workflow_instance/details.rb +7 -2
  118. data/lib/temporalio/internal/worker/workflow_instance/external_workflow_handle.rb +2 -2
  119. data/lib/temporalio/internal/worker/workflow_instance/illegal_call_tracer.rb +64 -18
  120. data/lib/temporalio/internal/worker/workflow_instance/outbound_implementation.rb +39 -40
  121. data/lib/temporalio/internal/worker/workflow_instance/scheduler.rb +22 -2
  122. data/lib/temporalio/internal/worker/workflow_instance.rb +134 -55
  123. data/lib/temporalio/internal/worker/workflow_worker.rb +74 -21
  124. data/lib/temporalio/priority.rb +59 -0
  125. data/lib/temporalio/runtime/metric_buffer.rb +94 -0
  126. data/lib/temporalio/runtime.rb +48 -10
  127. data/lib/temporalio/search_attributes.rb +13 -0
  128. data/lib/temporalio/testing/activity_environment.rb +59 -16
  129. data/lib/temporalio/testing/workflow_environment.rb +29 -6
  130. data/lib/temporalio/version.rb +1 -1
  131. data/lib/temporalio/versioning_override.rb +56 -0
  132. data/lib/temporalio/worker/deployment_options.rb +45 -0
  133. data/lib/temporalio/worker/illegal_workflow_call_validator.rb +64 -0
  134. data/lib/temporalio/worker/interceptor.rb +16 -1
  135. data/lib/temporalio/worker/poller_behavior.rb +61 -0
  136. data/lib/temporalio/worker/thread_pool.rb +6 -6
  137. data/lib/temporalio/worker/tuner.rb +38 -0
  138. data/lib/temporalio/worker/workflow_executor/thread_pool.rb +14 -8
  139. data/lib/temporalio/worker/workflow_executor.rb +1 -1
  140. data/lib/temporalio/worker/workflow_replayer.rb +349 -0
  141. data/lib/temporalio/worker.rb +117 -75
  142. data/lib/temporalio/worker_deployment_version.rb +67 -0
  143. data/lib/temporalio/workflow/child_workflow_handle.rb +10 -2
  144. data/lib/temporalio/workflow/definition.rb +217 -35
  145. data/lib/temporalio/workflow/external_workflow_handle.rb +3 -1
  146. data/lib/temporalio/workflow/future.rb +2 -2
  147. data/lib/temporalio/workflow/info.rb +26 -1
  148. data/lib/temporalio/workflow.rb +119 -15
  149. data/lib/temporalio/workflow_history.rb +26 -1
  150. data/lib/temporalio.rb +1 -0
  151. data/temporalio.gemspec +3 -1
  152. metadata +34 -4
@@ -93,8 +93,10 @@ module Temporalio
93
93
  def handle_start_task(task_token, start)
94
94
  set_running_activity(task_token, nil)
95
95
 
96
- # Find activity definition, falling back to dynamic if present
97
- defn = @activities[start.activity_type] || @activities[nil]
96
+ # Find activity definition, falling back to dynamic if not found and not reserved name
97
+ defn = @activities[start.activity_type]
98
+ defn = @activities[nil] if !defn && !Internal::ProtoUtils.reserved_name?(start.activity_type)
99
+
98
100
  if defn.nil?
99
101
  raise Error::ApplicationError.new(
100
102
  "Activity #{start.activity_type} for workflow #{start.workflow_execution.workflow_id} " \
@@ -114,7 +116,7 @@ module Temporalio
114
116
  # Unset at the end
115
117
  Activity::Context._current_executor = nil
116
118
  end
117
- rescue Exception => e # rubocop:disable Lint/RescueException We are intending to catch everything here
119
+ rescue Exception => e # rubocop:disable Lint/RescueException -- We are intending to catch everything here
118
120
  remove_running_activity(task_token)
119
121
  @scoped_logger.warn("Failed starting activity #{start.activity_type}")
120
122
  @scoped_logger.warn(e)
@@ -146,10 +148,18 @@ module Temporalio
146
148
  @scoped_logger.warn("Cannot find activity to cancel for token #{task_token}")
147
149
  return
148
150
  end
149
- activity._server_requested_cancel = true
150
- _, cancel_proc = activity.cancellation
151
151
  begin
152
- cancel_proc.call(reason: cancel.reason.to_s)
152
+ activity._cancel(
153
+ reason: cancel.reason.to_s,
154
+ details: Activity::CancellationDetails.new(
155
+ gone_from_server: cancel.details.is_not_found,
156
+ cancel_requested: cancel.details.is_cancelled,
157
+ timed_out: cancel.details.is_timed_out,
158
+ worker_shutdown: cancel.details.is_worker_shutdown,
159
+ paused: cancel.details.is_paused,
160
+ reset: cancel.details.is_reset
161
+ )
162
+ )
153
163
  rescue StandardError => e
154
164
  @scoped_logger.warn("Failed cancelling activity #{activity.info.activity_type} \
155
165
  with ID #{activity.info.activity_id}")
@@ -166,12 +176,15 @@ module Temporalio
166
176
  current_attempt_scheduled_time: Internal::ProtoUtils.timestamp_to_time(
167
177
  start.current_attempt_scheduled_time
168
178
  ) || raise, # Never nil
169
- heartbeat_details: ProtoUtils.convert_from_payload_array(
170
- @worker.options.client.data_converter,
171
- start.heartbeat_details.to_ary
172
- ),
173
179
  heartbeat_timeout: Internal::ProtoUtils.duration_to_seconds(start.heartbeat_timeout),
174
180
  local?: start.is_local,
181
+ priority: Priority._from_proto(start.priority),
182
+ raw_heartbeat_details: begin
183
+ payloads = start.heartbeat_details.to_ary
184
+ codec = @worker.options.client.data_converter.payload_codec
185
+ payloads = codec.decode(payloads) if codec
186
+ payloads.map { |p| Temporalio::Converters::RawValue.new(p) }
187
+ end,
175
188
  schedule_to_close_timeout: Internal::ProtoUtils.duration_to_seconds(start.schedule_to_close_timeout),
176
189
  scheduled_time: Internal::ProtoUtils.timestamp_to_time(start.scheduled_time) || raise, # Never nil
177
190
  start_to_close_timeout: Internal::ProtoUtils.duration_to_seconds(start.start_to_close_timeout),
@@ -182,7 +195,7 @@ module Temporalio
182
195
  workflow_namespace: start.workflow_namespace,
183
196
  workflow_run_id: start.workflow_execution.run_id,
184
197
  workflow_type: start.workflow_type
185
- ).freeze
198
+ )
186
199
 
187
200
  # Build input
188
201
  input = Temporalio::Worker::Interceptor::Activity::ExecuteInput.new(
@@ -194,13 +207,19 @@ module Temporalio
194
207
  payloads = codec.decode(payloads) if codec
195
208
  payloads.map { |p| Temporalio::Converters::RawValue.new(p) }
196
209
  else
197
- ProtoUtils.convert_from_payload_array(@worker.options.client.data_converter, start.input.to_ary)
210
+ ProtoUtils.convert_from_payload_array(
211
+ @worker.options.client.data_converter,
212
+ start.input.to_ary,
213
+ hints: defn.arg_hints
214
+ )
198
215
  end,
216
+ result_hint: defn.result_hint,
199
217
  headers: ProtoUtils.headers_from_proto_map(start.header_fields, @worker.options.client.data_converter) || {}
200
218
  )
201
219
 
202
220
  # Run
203
221
  activity = RunningActivity.new(
222
+ worker: @worker,
204
223
  info:,
205
224
  cancellation: Cancellation.new,
206
225
  worker_shutdown_cancellation: @worker._worker_shutdown_cancellation,
@@ -210,8 +229,8 @@ module Temporalio
210
229
  )
211
230
  Activity::Context._current_executor&.set_activity_context(defn, activity)
212
231
  set_running_activity(task_token, activity)
213
- run_activity(activity, input)
214
- rescue Exception => e # rubocop:disable Lint/RescueException We are intending to catch everything here
232
+ run_activity(defn, activity, input)
233
+ rescue Exception => e # rubocop:disable Lint/RescueException -- We are intending to catch everything here
215
234
  @scoped_logger.warn("Failed starting or sending completion for activity #{start.activity_type}")
216
235
  @scoped_logger.warn(e)
217
236
  # This means that the activity couldn't start or send completion (run
@@ -236,15 +255,18 @@ module Temporalio
236
255
  remove_running_activity(task_token)
237
256
  end
238
257
 
239
- def run_activity(activity, input)
258
+ def run_activity(defn, activity, input)
240
259
  result = begin
260
+ # Create the instance. We choose to do this before interceptors so that it is available in the interceptor.
261
+ activity.instance = defn.instance.is_a?(Proc) ? defn.instance.call : defn.instance # steep:ignore
262
+
241
263
  # Build impl with interceptors
242
264
  # @type var impl: Temporalio::Worker::Interceptor::Activity::Inbound
243
265
  impl = InboundImplementation.new(self)
244
266
  impl = @worker._activity_interceptors.reverse_each.reduce(impl) do |acc, int|
245
267
  int.intercept_activity(acc)
246
268
  end
247
- impl.init(OutboundImplementation.new(self))
269
+ impl.init(OutboundImplementation.new(self, activity.info.task_token))
248
270
 
249
271
  # Execute
250
272
  result = impl.execute(input)
@@ -252,16 +274,40 @@ module Temporalio
252
274
  # Success
253
275
  Bridge::Api::ActivityResult::ActivityExecutionResult.new(
254
276
  completed: Bridge::Api::ActivityResult::Success.new(
255
- result: @worker.options.client.data_converter.to_payload(result)
277
+ result: @worker.options.client.data_converter.to_payload(result, hint: input.result_hint)
256
278
  )
257
279
  )
258
- rescue Exception => e # rubocop:disable Lint/RescueException We are intending to catch everything here
280
+ rescue Exception => e # rubocop:disable Lint/RescueException -- We are intending to catch everything here
259
281
  if e.is_a?(Activity::CompleteAsyncError)
260
282
  # Wanting to complete async
261
283
  @scoped_logger.debug('Completing activity asynchronously')
262
284
  Bridge::Api::ActivityResult::ActivityExecutionResult.new(
263
285
  will_complete_async: Bridge::Api::ActivityResult::WillCompleteAsync.new
264
286
  )
287
+ elsif e.is_a?(Error::CanceledError) && activity.cancellation_details&.paused?
288
+ # Server requested pause
289
+ @scoped_logger.debug('Completing activity as failed due to exception caused by pause')
290
+ Bridge::Api::ActivityResult::ActivityExecutionResult.new(
291
+ failed: Bridge::Api::ActivityResult::Failure.new(
292
+ failure: @worker.options.client.data_converter.to_failure(
293
+ Error._with_backtrace_and_cause(
294
+ Error::ApplicationError.new('Activity paused', type: 'ActivityPause'), backtrace: nil, cause: e
295
+ )
296
+ )
297
+ )
298
+ )
299
+ elsif e.is_a?(Error::CanceledError) && activity.cancellation_details&.reset?
300
+ # Server requested reset
301
+ @scoped_logger.debug('Completing activity as failed due to exception caused by reset')
302
+ Bridge::Api::ActivityResult::ActivityExecutionResult.new(
303
+ failed: Bridge::Api::ActivityResult::Failure.new(
304
+ failure: @worker.options.client.data_converter.to_failure(
305
+ Error._with_backtrace_and_cause(
306
+ Error::ApplicationError.new('Activity reset', type: 'ActivityReset'), backtrace: nil, cause: e
307
+ )
308
+ )
309
+ )
310
+ )
265
311
  elsif e.is_a?(Error::CanceledError) && activity._server_requested_cancel
266
312
  # Server requested cancel
267
313
  @scoped_logger.debug('Completing activity as canceled')
@@ -272,8 +318,13 @@ module Temporalio
272
318
  )
273
319
  else
274
320
  # General failure
275
- @scoped_logger.warn('Completing activity as failed')
276
- @scoped_logger.warn(e)
321
+ log_level = if e.is_a?(Error::ApplicationError) && e.category == Error::ApplicationError::Category::BENIGN
322
+ Logger::DEBUG
323
+ else
324
+ Logger::WARN
325
+ end
326
+ @scoped_logger.add(log_level, 'Completing activity as failed')
327
+ @scoped_logger.add(log_level, e)
277
328
  Bridge::Api::ActivityResult::ActivityExecutionResult.new(
278
329
  failed: Bridge::Api::ActivityResult::Failure.new(
279
330
  failure: @worker.options.client.data_converter.to_failure(e)
@@ -291,11 +342,24 @@ module Temporalio
291
342
  )
292
343
  end
293
344
 
345
+ def assert_valid_activity(activity)
346
+ defn = @activities[activity]
347
+ defn = @activities[nil] if !defn && !Internal::ProtoUtils.reserved_name?(activity)
348
+
349
+ return unless defn.nil?
350
+
351
+ raise ArgumentError,
352
+ "Activity #{activity} " \
353
+ "is not registered on this worker, available activities: #{@activities.keys.sort.join(', ')}"
354
+ end
355
+
294
356
  class RunningActivity < Activity::Context
295
- attr_reader :info, :cancellation, :worker_shutdown_cancellation, :payload_converter, :logger
296
- attr_accessor :_outbound_impl, :_server_requested_cancel
357
+ attr_reader :info, :cancellation, :cancellation_details, :worker_shutdown_cancellation,
358
+ :payload_converter, :logger, :_server_requested_cancel
359
+ attr_accessor :instance, :_outbound_impl
297
360
 
298
361
  def initialize( # rubocop:disable Lint/MissingSuper
362
+ worker:,
299
363
  info:,
300
364
  cancellation:,
301
365
  worker_shutdown_cancellation:,
@@ -303,8 +367,10 @@ module Temporalio
303
367
  logger:,
304
368
  runtime_metric_meter:
305
369
  )
370
+ @worker = worker
306
371
  @info = info
307
372
  @cancellation = cancellation
373
+ @cancellation_details = nil
308
374
  @worker_shutdown_cancellation = worker_shutdown_cancellation
309
375
  @payload_converter = payload_converter
310
376
  @logger = logger
@@ -313,13 +379,15 @@ module Temporalio
313
379
  @_server_requested_cancel = false
314
380
  end
315
381
 
316
- def heartbeat(*details)
382
+ def heartbeat(*details, detail_hints: nil)
317
383
  raise 'Implementation not set yet' if _outbound_impl.nil?
318
384
 
319
385
  # No-op if local
320
386
  return if info.local?
321
387
 
322
- _outbound_impl.heartbeat(Temporalio::Worker::Interceptor::Activity::HeartbeatInput.new(details:))
388
+ _outbound_impl.heartbeat(
389
+ Temporalio::Worker::Interceptor::Activity::HeartbeatInput.new(details:, detail_hints:)
390
+ )
323
391
  end
324
392
 
325
393
  def metric_meter
@@ -331,6 +399,21 @@ module Temporalio
331
399
  }
332
400
  )
333
401
  end
402
+
403
+ def client
404
+ @worker.client
405
+ end
406
+
407
+ def _cancel(reason:, details:)
408
+ # Do not issue cancel if already canceled
409
+ return if @cancellation_details
410
+
411
+ @_server_requested_cancel = true
412
+ # Set the cancellation details _before_ issuing the cancel itself
413
+ @cancellation_details = details
414
+ _, cancel_proc = cancellation
415
+ cancel_proc.call(reason:)
416
+ end
334
417
  end
335
418
 
336
419
  class InboundImplementation < Temporalio::Worker::Interceptor::Activity::Inbound
@@ -352,17 +435,19 @@ module Temporalio
352
435
  end
353
436
 
354
437
  class OutboundImplementation < Temporalio::Worker::Interceptor::Activity::Outbound
355
- def initialize(worker)
438
+ def initialize(worker, task_token)
356
439
  super(nil) # steep:ignore
357
440
  @worker = worker
441
+ @task_token = task_token
358
442
  end
359
443
 
360
444
  def heartbeat(input)
361
445
  @worker.bridge_worker.record_activity_heartbeat(
362
446
  Bridge::Api::CoreInterface::ActivityHeartbeat.new(
363
- task_token: Activity::Context.current.info.task_token,
447
+ task_token: @task_token,
364
448
  details: ProtoUtils.convert_to_payload_array(@worker.worker.options.client.data_converter,
365
- input.details)
449
+ input.details,
450
+ hints: input.detail_hints)
366
451
  ).to_proto
367
452
  )
368
453
  end
@@ -34,7 +34,7 @@ module Temporalio
34
34
  rescue InjectEventForTesting => e
35
35
  @queue.push(e.event)
36
36
  @queue.push(Event::BlockSuccess.new(result: e))
37
- rescue Exception => e # rubocop:disable Lint/RescueException Intentionally catch all
37
+ rescue Exception => e # rubocop:disable Lint/RescueException -- Intentionally catch all
38
38
  @queue.push(Event::BlockFailure.new(error: e))
39
39
  end
40
40
  else
@@ -43,7 +43,7 @@ module Temporalio
43
43
  rescue InjectEventForTesting => e
44
44
  @queue.push(e.event)
45
45
  @queue.push(Event::BlockSuccess.new(result: e))
46
- rescue Exception => e # rubocop:disable Lint/RescueException Intentionally catch all
46
+ rescue Exception => e # rubocop:disable Lint/RescueException -- Intentionally catch all
47
47
  @queue.push(Event::BlockFailure.new(error: e))
48
48
  end
49
49
  end
@@ -10,18 +10,20 @@ module Temporalio
10
10
  class WorkflowInstance
11
11
  # Implementation of the child workflow handle.
12
12
  class ChildWorkflowHandle < Workflow::ChildWorkflowHandle
13
- attr_reader :id, :first_execution_run_id
13
+ attr_reader :id, :first_execution_run_id, :result_hint
14
14
 
15
- def initialize(id:, first_execution_run_id:, instance:, cancellation:, cancel_callback_key:) # rubocop:disable Lint/MissingSuper
15
+ def initialize(id:, first_execution_run_id:, instance:, # rubocop:disable Lint/MissingSuper
16
+ cancellation:, cancel_callback_key:, result_hint:)
16
17
  @id = id
17
18
  @first_execution_run_id = first_execution_run_id
18
19
  @instance = instance
19
20
  @cancellation = cancellation
20
21
  @cancel_callback_key = cancel_callback_key
22
+ @result_hint = result_hint
21
23
  @resolution = nil
22
24
  end
23
25
 
24
- def result
26
+ def result(result_hint: nil)
25
27
  # Notice that we actually provide a detached cancellation here instead of defaulting to workflow
26
28
  # cancellation because we don't want workflow cancellation (or a user-provided cancellation to this result
27
29
  # call) to be able to interrupt waiting on a child that may be processing the cancellation.
@@ -29,7 +31,7 @@ module Temporalio
29
31
 
30
32
  case @resolution.status
31
33
  when :completed
32
- @instance.payload_converter.from_payload(@resolution.completed.result)
34
+ @instance.payload_converter.from_payload(@resolution.completed.result, hint: result_hint || @result_hint)
33
35
  when :failed
34
36
  raise @instance.failure_converter.from_failure(@resolution.failed.failure, @instance.payload_converter)
35
37
  when :cancelled
@@ -44,8 +46,8 @@ module Temporalio
44
46
  @resolution = resolution
45
47
  end
46
48
 
47
- def signal(signal, *args, cancellation: Workflow.cancellation)
48
- @instance.context._signal_child_workflow(id:, signal:, args:, cancellation:)
49
+ def signal(signal, *args, cancellation: Workflow.cancellation, arg_hints: nil)
50
+ @instance.context._signal_child_workflow(id:, signal:, args:, cancellation:, arg_hints:)
49
51
  end
50
52
  end
51
53
  end
@@ -32,6 +32,20 @@ module Temporalio
32
32
  @instance.continue_as_new_suggested
33
33
  end
34
34
 
35
+ def current_details
36
+ @instance.current_details || ''
37
+ end
38
+
39
+ def current_details=(details)
40
+ raise 'Details must be a String' unless details.nil? || details.is_a?(String)
41
+
42
+ @instance.current_details = (details || '')
43
+ end
44
+
45
+ def current_deployment_version
46
+ @instance.current_deployment_version
47
+ end
48
+
35
49
  def current_history_length
36
50
  @instance.current_history_length
37
51
  end
@@ -48,10 +62,21 @@ module Temporalio
48
62
  @instance.patch(patch_id:, deprecated: true)
49
63
  end
50
64
 
65
+ def durable_scheduler_disabled(&)
66
+ prev = Fiber.current_scheduler
67
+ illegal_call_tracing_disabled { Fiber.set_scheduler(nil) }
68
+ begin
69
+ yield
70
+ ensure
71
+ illegal_call_tracing_disabled { Fiber.set_scheduler(prev) }
72
+ end
73
+ end
74
+
51
75
  def execute_activity(
52
76
  activity,
53
77
  *args,
54
78
  task_queue:,
79
+ summary:,
55
80
  schedule_to_close_timeout:,
56
81
  schedule_to_start_timeout:,
57
82
  start_to_close_timeout:,
@@ -60,13 +85,30 @@ module Temporalio
60
85
  cancellation:,
61
86
  cancellation_type:,
62
87
  activity_id:,
63
- disable_eager_execution:
88
+ disable_eager_execution:,
89
+ priority:,
90
+ arg_hints:,
91
+ result_hint:
64
92
  )
93
+ activity, defn_arg_hints, defn_result_hint =
94
+ case activity
95
+ when Class
96
+ defn = Activity::Definition::Info.from_activity(activity)
97
+ [defn.name&.to_s, defn.arg_hints, defn.result_hint]
98
+ when Symbol, String
99
+ [activity.to_s, nil, nil]
100
+ else
101
+ raise ArgumentError,
102
+ 'Activity must be a definition class, or a symbol/string'
103
+ end
104
+ raise 'Cannot invoke dynamic activities' unless activity
105
+
65
106
  @outbound.execute_activity(
66
107
  Temporalio::Worker::Interceptor::Workflow::ExecuteActivityInput.new(
67
108
  activity:,
68
109
  args:,
69
110
  task_queue: task_queue || info.task_queue,
111
+ summary:,
70
112
  schedule_to_close_timeout:,
71
113
  schedule_to_start_timeout:,
72
114
  start_to_close_timeout:,
@@ -76,6 +118,9 @@ module Temporalio
76
118
  cancellation_type:,
77
119
  activity_id:,
78
120
  disable_eager_execution: disable_eager_execution || @instance.disable_eager_activity_execution,
121
+ priority:,
122
+ arg_hints: arg_hints || defn_arg_hints,
123
+ result_hint: result_hint || defn_result_hint,
79
124
  headers: {}
80
125
  )
81
126
  )
@@ -91,8 +136,22 @@ module Temporalio
91
136
  local_retry_threshold:,
92
137
  cancellation:,
93
138
  cancellation_type:,
94
- activity_id:
139
+ activity_id:,
140
+ arg_hints:,
141
+ result_hint:
95
142
  )
143
+ activity, defn_arg_hints, defn_result_hint =
144
+ case activity
145
+ when Class
146
+ defn = Activity::Definition::Info.from_activity(activity)
147
+ [defn.name&.to_s, defn.arg_hints, defn.result_hint]
148
+ when Symbol, String
149
+ [activity.to_s, nil, nil]
150
+ else
151
+ raise ArgumentError, 'Activity must be a definition class, or a symbol/string'
152
+ end
153
+ raise 'Cannot invoke dynamic activities' unless activity
154
+
96
155
  @outbound.execute_local_activity(
97
156
  Temporalio::Worker::Interceptor::Workflow::ExecuteLocalActivityInput.new(
98
157
  activity:,
@@ -105,6 +164,8 @@ module Temporalio
105
164
  cancellation:,
106
165
  cancellation_type:,
107
166
  activity_id:,
167
+ arg_hints: arg_hints || defn_arg_hints,
168
+ result_hint: result_hint || defn_result_hint,
108
169
  headers: {}
109
170
  )
110
171
  )
@@ -122,12 +183,26 @@ module Temporalio
122
183
  @instance.info
123
184
  end
124
185
 
186
+ def instance
187
+ @instance.instance
188
+ end
189
+
125
190
  def initialize_continue_as_new_error(error)
126
191
  @outbound.initialize_continue_as_new_error(
127
192
  Temporalio::Worker::Interceptor::Workflow::InitializeContinueAsNewErrorInput.new(error:)
128
193
  )
129
194
  end
130
195
 
196
+ def io_enabled(&)
197
+ prev = @instance.io_enabled
198
+ @instance.io_enabled = true
199
+ begin
200
+ yield
201
+ ensure
202
+ @instance.io_enabled = prev
203
+ end
204
+ end
205
+
131
206
  def logger
132
207
  @instance.logger
133
208
  end
@@ -187,6 +262,8 @@ module Temporalio
187
262
  *args,
188
263
  id:,
189
264
  task_queue:,
265
+ static_summary:,
266
+ static_details:,
190
267
  cancellation:,
191
268
  cancellation_type:,
192
269
  parent_close_policy:,
@@ -197,14 +274,21 @@ module Temporalio
197
274
  retry_policy:,
198
275
  cron_schedule:,
199
276
  memo:,
200
- search_attributes:
277
+ search_attributes:,
278
+ priority:,
279
+ arg_hints:,
280
+ result_hint:
201
281
  )
282
+ workflow, defn_arg_hints, defn_result_hint =
283
+ Workflow::Definition._workflow_type_and_hints_from_workflow_parameter(workflow)
202
284
  @outbound.start_child_workflow(
203
285
  Temporalio::Worker::Interceptor::Workflow::StartChildWorkflowInput.new(
204
286
  workflow:,
205
287
  args:,
206
288
  id:,
207
289
  task_queue:,
290
+ static_summary:,
291
+ static_details:,
208
292
  cancellation:,
209
293
  cancellation_type:,
210
294
  parent_close_policy:,
@@ -216,11 +300,18 @@ module Temporalio
216
300
  cron_schedule:,
217
301
  memo:,
218
302
  search_attributes:,
303
+ priority:,
304
+ arg_hints: arg_hints || defn_arg_hints,
305
+ result_hint: result_hint || defn_result_hint,
219
306
  headers: {}
220
307
  )
221
308
  )
222
309
  end
223
310
 
311
+ def storage
312
+ @storage ||= {}
313
+ end
314
+
224
315
  def timeout(duration, exception_class, *exception_args, summary:, &)
225
316
  raise 'Block required for timeout' unless block_given?
226
317
 
@@ -298,19 +389,22 @@ module Temporalio
298
389
  @outbound = outbound
299
390
  end
300
391
 
301
- def _signal_child_workflow(id:, signal:, args:, cancellation:)
392
+ def _signal_child_workflow(id:, signal:, args:, cancellation:, arg_hints:)
393
+ signal, defn_arg_hints = Workflow::Definition::Signal._name_and_hints_from_parameter(signal)
302
394
  @outbound.signal_child_workflow(
303
395
  Temporalio::Worker::Interceptor::Workflow::SignalChildWorkflowInput.new(
304
396
  id:,
305
397
  signal:,
306
398
  args:,
307
399
  cancellation:,
400
+ arg_hints: arg_hints || defn_arg_hints,
308
401
  headers: {}
309
402
  )
310
403
  )
311
404
  end
312
405
 
313
- def _signal_external_workflow(id:, run_id:, signal:, args:, cancellation:)
406
+ def _signal_external_workflow(id:, run_id:, signal:, args:, cancellation:, arg_hints:)
407
+ signal, defn_arg_hints = Workflow::Definition::Signal._name_and_hints_from_parameter(signal)
314
408
  @outbound.signal_external_workflow(
315
409
  Temporalio::Worker::Interceptor::Workflow::SignalExternalWorkflowInput.new(
316
410
  id:,
@@ -318,6 +412,7 @@ module Temporalio
318
412
  signal:,
319
413
  args:,
320
414
  cancellation:,
415
+ arg_hints: arg_hints || defn_arg_hints,
321
416
  headers: {}
322
417
  )
323
418
  )
@@ -8,7 +8,8 @@ module Temporalio
8
8
  class Details
9
9
  attr_reader :namespace, :task_queue, :definition, :initial_activation, :logger, :metric_meter,
10
10
  :payload_converter, :failure_converter, :interceptors, :disable_eager_activity_execution,
11
- :illegal_calls, :workflow_failure_exception_types
11
+ :illegal_calls, :workflow_failure_exception_types, :unsafe_workflow_io_enabled,
12
+ :assert_valid_local_activity
12
13
 
13
14
  def initialize(
14
15
  namespace:,
@@ -22,7 +23,9 @@ module Temporalio
22
23
  interceptors:,
23
24
  disable_eager_activity_execution:,
24
25
  illegal_calls:,
25
- workflow_failure_exception_types:
26
+ workflow_failure_exception_types:,
27
+ unsafe_workflow_io_enabled:,
28
+ assert_valid_local_activity:
26
29
  )
27
30
  @namespace = namespace
28
31
  @task_queue = task_queue
@@ -36,6 +39,8 @@ module Temporalio
36
39
  @disable_eager_activity_execution = disable_eager_activity_execution
37
40
  @illegal_calls = illegal_calls
38
41
  @workflow_failure_exception_types = workflow_failure_exception_types
42
+ @unsafe_workflow_io_enabled = unsafe_workflow_io_enabled
43
+ @assert_valid_local_activity = assert_valid_local_activity
39
44
  end
40
45
  end
41
46
  end
@@ -18,8 +18,8 @@ module Temporalio
18
18
  @instance = instance
19
19
  end
20
20
 
21
- def signal(signal, *args, cancellation: Workflow.cancellation)
22
- @instance.context._signal_external_workflow(id:, run_id:, signal:, args:, cancellation:)
21
+ def signal(signal, *args, cancellation: Workflow.cancellation, arg_hints: nil)
22
+ @instance.context._signal_external_workflow(id:, run_id:, signal:, args:, cancellation:, arg_hints:)
23
23
  end
24
24
 
25
25
  def cancel