temporalio 0.3.0-x86_64-linux-musl → 0.5.0-x86_64-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 (149) 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 +17 -1
  7. data/lib/temporalio/activity/definition.rb +45 -4
  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 +107 -25
  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 +96 -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 +19 -6
  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 +49 -10
  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/workflow_executor/thread_pool.rb +9 -3
  138. data/lib/temporalio/worker/workflow_replayer.rb +19 -13
  139. data/lib/temporalio/worker.rb +97 -27
  140. data/lib/temporalio/worker_deployment_version.rb +67 -0
  141. data/lib/temporalio/workflow/child_workflow_handle.rb +10 -2
  142. data/lib/temporalio/workflow/definition.rb +217 -35
  143. data/lib/temporalio/workflow/external_workflow_handle.rb +3 -1
  144. data/lib/temporalio/workflow/future.rb +2 -2
  145. data/lib/temporalio/workflow/info.rb +26 -1
  146. data/lib/temporalio/workflow.rb +113 -15
  147. data/lib/temporalio.rb +1 -0
  148. data/temporalio.gemspec +3 -1
  149. metadata +33 -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,
@@ -211,7 +230,7 @@ module Temporalio
211
230
  Activity::Context._current_executor&.set_activity_context(defn, activity)
212
231
  set_running_activity(task_token, activity)
213
232
  run_activity(defn, activity, input)
214
- rescue Exception => e # rubocop:disable Lint/RescueException We are intending to catch everything here
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
@@ -247,7 +266,7 @@ module Temporalio
247
266
  impl = @worker._activity_interceptors.reverse_each.reduce(impl) do |acc, int|
248
267
  int.intercept_activity(acc)
249
268
  end
250
- impl.init(OutboundImplementation.new(self))
269
+ impl.init(OutboundImplementation.new(self, activity.info.task_token))
251
270
 
252
271
  # Execute
253
272
  result = impl.execute(input)
@@ -255,16 +274,40 @@ module Temporalio
255
274
  # Success
256
275
  Bridge::Api::ActivityResult::ActivityExecutionResult.new(
257
276
  completed: Bridge::Api::ActivityResult::Success.new(
258
- result: @worker.options.client.data_converter.to_payload(result)
277
+ result: @worker.options.client.data_converter.to_payload(result, hint: input.result_hint)
259
278
  )
260
279
  )
261
- 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
262
281
  if e.is_a?(Activity::CompleteAsyncError)
263
282
  # Wanting to complete async
264
283
  @scoped_logger.debug('Completing activity asynchronously')
265
284
  Bridge::Api::ActivityResult::ActivityExecutionResult.new(
266
285
  will_complete_async: Bridge::Api::ActivityResult::WillCompleteAsync.new
267
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
+ )
268
311
  elsif e.is_a?(Error::CanceledError) && activity._server_requested_cancel
269
312
  # Server requested cancel
270
313
  @scoped_logger.debug('Completing activity as canceled')
@@ -275,8 +318,13 @@ module Temporalio
275
318
  )
276
319
  else
277
320
  # General failure
278
- @scoped_logger.warn('Completing activity as failed')
279
- @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)
280
328
  Bridge::Api::ActivityResult::ActivityExecutionResult.new(
281
329
  failed: Bridge::Api::ActivityResult::Failure.new(
282
330
  failure: @worker.options.client.data_converter.to_failure(e)
@@ -294,11 +342,24 @@ module Temporalio
294
342
  )
295
343
  end
296
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
+
297
356
  class RunningActivity < Activity::Context
298
- attr_reader :info, :cancellation, :worker_shutdown_cancellation, :payload_converter, :logger
299
- attr_accessor :instance, :_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
300
360
 
301
361
  def initialize( # rubocop:disable Lint/MissingSuper
362
+ worker:,
302
363
  info:,
303
364
  cancellation:,
304
365
  worker_shutdown_cancellation:,
@@ -306,8 +367,10 @@ module Temporalio
306
367
  logger:,
307
368
  runtime_metric_meter:
308
369
  )
370
+ @worker = worker
309
371
  @info = info
310
372
  @cancellation = cancellation
373
+ @cancellation_details = nil
311
374
  @worker_shutdown_cancellation = worker_shutdown_cancellation
312
375
  @payload_converter = payload_converter
313
376
  @logger = logger
@@ -316,13 +379,15 @@ module Temporalio
316
379
  @_server_requested_cancel = false
317
380
  end
318
381
 
319
- def heartbeat(*details)
382
+ def heartbeat(*details, detail_hints: nil)
320
383
  raise 'Implementation not set yet' if _outbound_impl.nil?
321
384
 
322
385
  # No-op if local
323
386
  return if info.local?
324
387
 
325
- _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
+ )
326
391
  end
327
392
 
328
393
  def metric_meter
@@ -334,6 +399,21 @@ module Temporalio
334
399
  }
335
400
  )
336
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
337
417
  end
338
418
 
339
419
  class InboundImplementation < Temporalio::Worker::Interceptor::Activity::Inbound
@@ -355,17 +435,19 @@ module Temporalio
355
435
  end
356
436
 
357
437
  class OutboundImplementation < Temporalio::Worker::Interceptor::Activity::Outbound
358
- def initialize(worker)
438
+ def initialize(worker, task_token)
359
439
  super(nil) # steep:ignore
360
440
  @worker = worker
441
+ @task_token = task_token
361
442
  end
362
443
 
363
444
  def heartbeat(input)
364
445
  @worker.bridge_worker.record_activity_heartbeat(
365
446
  Bridge::Api::CoreInterface::ActivityHeartbeat.new(
366
- task_token: Activity::Context.current.info.task_token,
447
+ task_token: @task_token,
367
448
  details: ProtoUtils.convert_to_payload_array(@worker.worker.options.client.data_converter,
368
- input.details)
449
+ input.details,
450
+ hints: input.detail_hints)
369
451
  ).to_proto
370
452
  )
371
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
  )
@@ -132,6 +193,16 @@ module Temporalio
132
193
  )
133
194
  end
134
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
+
135
206
  def logger
136
207
  @instance.logger
137
208
  end
@@ -191,6 +262,8 @@ module Temporalio
191
262
  *args,
192
263
  id:,
193
264
  task_queue:,
265
+ static_summary:,
266
+ static_details:,
194
267
  cancellation:,
195
268
  cancellation_type:,
196
269
  parent_close_policy:,
@@ -201,14 +274,21 @@ module Temporalio
201
274
  retry_policy:,
202
275
  cron_schedule:,
203
276
  memo:,
204
- search_attributes:
277
+ search_attributes:,
278
+ priority:,
279
+ arg_hints:,
280
+ result_hint:
205
281
  )
282
+ workflow, defn_arg_hints, defn_result_hint =
283
+ Workflow::Definition._workflow_type_and_hints_from_workflow_parameter(workflow)
206
284
  @outbound.start_child_workflow(
207
285
  Temporalio::Worker::Interceptor::Workflow::StartChildWorkflowInput.new(
208
286
  workflow:,
209
287
  args:,
210
288
  id:,
211
289
  task_queue:,
290
+ static_summary:,
291
+ static_details:,
212
292
  cancellation:,
213
293
  cancellation_type:,
214
294
  parent_close_policy:,
@@ -220,11 +300,18 @@ module Temporalio
220
300
  cron_schedule:,
221
301
  memo:,
222
302
  search_attributes:,
303
+ priority:,
304
+ arg_hints: arg_hints || defn_arg_hints,
305
+ result_hint: result_hint || defn_result_hint,
223
306
  headers: {}
224
307
  )
225
308
  )
226
309
  end
227
310
 
311
+ def storage
312
+ @storage ||= {}
313
+ end
314
+
228
315
  def timeout(duration, exception_class, *exception_args, summary:, &)
229
316
  raise 'Block required for timeout' unless block_given?
230
317
 
@@ -302,19 +389,22 @@ module Temporalio
302
389
  @outbound = outbound
303
390
  end
304
391
 
305
- 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)
306
394
  @outbound.signal_child_workflow(
307
395
  Temporalio::Worker::Interceptor::Workflow::SignalChildWorkflowInput.new(
308
396
  id:,
309
397
  signal:,
310
398
  args:,
311
399
  cancellation:,
400
+ arg_hints: arg_hints || defn_arg_hints,
312
401
  headers: {}
313
402
  )
314
403
  )
315
404
  end
316
405
 
317
- 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)
318
408
  @outbound.signal_external_workflow(
319
409
  Temporalio::Worker::Interceptor::Workflow::SignalExternalWorkflowInput.new(
320
410
  id:,
@@ -322,6 +412,7 @@ module Temporalio
322
412
  signal:,
323
413
  args:,
324
414
  cancellation:,
415
+ arg_hints: arg_hints || defn_arg_hints,
325
416
  headers: {}
326
417
  )
327
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