temporalio 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -1
  3. data/Cargo.lock +679 -437
  4. data/Cargo.toml +5 -5
  5. data/README.md +98 -34
  6. data/ext/Cargo.toml +3 -3
  7. data/lib/temporalio/activity/cancellation_details.rb +58 -0
  8. data/lib/temporalio/activity/context.rb +10 -1
  9. data/lib/temporalio/activity/definition.rb +41 -3
  10. data/lib/temporalio/activity/info.rb +25 -4
  11. data/lib/temporalio/activity.rb +2 -0
  12. data/lib/temporalio/api/activity/v1/message.rb +1 -1
  13. data/lib/temporalio/api/batch/v1/message.rb +4 -2
  14. data/lib/temporalio/api/cloud/account/v1/message.rb +1 -1
  15. data/lib/temporalio/api/cloud/cloudservice/v1/request_response.rb +11 -2
  16. data/lib/temporalio/api/cloud/cloudservice/v1/service.rb +2 -2
  17. data/lib/temporalio/api/cloud/identity/v1/message.rb +7 -2
  18. data/lib/temporalio/api/cloud/namespace/v1/message.rb +6 -2
  19. data/lib/temporalio/api/cloud/nexus/v1/message.rb +3 -2
  20. data/lib/temporalio/api/cloud/operation/v1/message.rb +1 -1
  21. data/lib/temporalio/api/cloud/region/v1/message.rb +1 -1
  22. data/lib/temporalio/api/cloud/resource/v1/message.rb +1 -1
  23. data/lib/temporalio/api/cloud/sink/v1/message.rb +1 -1
  24. data/lib/temporalio/api/cloud/usage/v1/message.rb +1 -1
  25. data/lib/temporalio/api/command/v1/message.rb +2 -2
  26. data/lib/temporalio/api/common/v1/grpc_status.rb +1 -1
  27. data/lib/temporalio/api/common/v1/message.rb +3 -2
  28. data/lib/temporalio/api/deployment/v1/message.rb +3 -2
  29. data/lib/temporalio/api/enums/v1/batch_operation.rb +1 -1
  30. data/lib/temporalio/api/enums/v1/command_type.rb +1 -1
  31. data/lib/temporalio/api/enums/v1/common.rb +5 -2
  32. data/lib/temporalio/api/enums/v1/deployment.rb +3 -2
  33. data/lib/temporalio/api/enums/v1/event_type.rb +2 -2
  34. data/lib/temporalio/api/enums/v1/failed_cause.rb +2 -2
  35. data/lib/temporalio/api/enums/v1/namespace.rb +1 -1
  36. data/lib/temporalio/api/enums/v1/nexus.rb +1 -1
  37. data/lib/temporalio/api/enums/v1/query.rb +1 -1
  38. data/lib/temporalio/api/enums/v1/reset.rb +1 -1
  39. data/lib/temporalio/api/enums/v1/schedule.rb +1 -1
  40. data/lib/temporalio/api/enums/v1/task_queue.rb +1 -1
  41. data/lib/temporalio/api/enums/v1/update.rb +1 -1
  42. data/lib/temporalio/api/enums/v1/workflow.rb +2 -2
  43. data/lib/temporalio/api/errordetails/v1/message.rb +1 -1
  44. data/lib/temporalio/api/export/v1/message.rb +1 -1
  45. data/lib/temporalio/api/failure/v1/message.rb +3 -2
  46. data/lib/temporalio/api/filter/v1/message.rb +1 -1
  47. data/lib/temporalio/api/history/v1/message.rb +4 -2
  48. data/lib/temporalio/api/namespace/v1/message.rb +1 -1
  49. data/lib/temporalio/api/nexus/v1/message.rb +2 -2
  50. data/lib/temporalio/api/operatorservice/v1/request_response.rb +1 -1
  51. data/lib/temporalio/api/operatorservice/v1/service.rb +1 -1
  52. data/lib/temporalio/api/payload_visitor.rb +87 -0
  53. data/lib/temporalio/api/protocol/v1/message.rb +1 -1
  54. data/lib/temporalio/api/query/v1/message.rb +1 -1
  55. data/lib/temporalio/api/replication/v1/message.rb +1 -1
  56. data/lib/temporalio/api/rules/v1/message.rb +27 -0
  57. data/lib/temporalio/api/schedule/v1/message.rb +2 -2
  58. data/lib/temporalio/api/sdk/v1/enhanced_stack_trace.rb +1 -1
  59. data/lib/temporalio/api/sdk/v1/task_complete_metadata.rb +1 -1
  60. data/lib/temporalio/api/sdk/v1/user_metadata.rb +1 -1
  61. data/lib/temporalio/api/sdk/v1/workflow_metadata.rb +1 -1
  62. data/lib/temporalio/api/taskqueue/v1/message.rb +2 -2
  63. data/lib/temporalio/api/testservice/v1/request_response.rb +1 -1
  64. data/lib/temporalio/api/testservice/v1/service.rb +1 -1
  65. data/lib/temporalio/api/update/v1/message.rb +1 -1
  66. data/lib/temporalio/api/version/v1/message.rb +1 -1
  67. data/lib/temporalio/api/worker/v1/message.rb +30 -0
  68. data/lib/temporalio/api/workflow/v1/message.rb +14 -2
  69. data/lib/temporalio/api/workflowservice/v1/request_response.rb +19 -2
  70. data/lib/temporalio/api/workflowservice/v1/service.rb +2 -2
  71. data/lib/temporalio/client/async_activity_handle.rb +12 -4
  72. data/lib/temporalio/client/connection/cloud_service.rb +60 -0
  73. data/lib/temporalio/client/connection/workflow_service.rb +105 -0
  74. data/lib/temporalio/client/interceptor.rb +25 -7
  75. data/lib/temporalio/client/schedule.rb +10 -2
  76. data/lib/temporalio/client/with_start_workflow_operation.rb +9 -1
  77. data/lib/temporalio/client/workflow_handle.rb +50 -10
  78. data/lib/temporalio/client/workflow_update_handle.rb +9 -3
  79. data/lib/temporalio/client.rb +110 -6
  80. data/lib/temporalio/common_enums.rb +14 -0
  81. data/lib/temporalio/contrib/open_telemetry.rb +13 -9
  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 +1 -1
  94. data/lib/temporalio/internal/bridge/api/activity_result/activity_result.rb +1 -1
  95. data/lib/temporalio/internal/bridge/api/activity_task/activity_task.rb +3 -2
  96. data/lib/temporalio/internal/bridge/api/child_workflow/child_workflow.rb +1 -1
  97. data/lib/temporalio/internal/bridge/api/common/common.rb +1 -1
  98. data/lib/temporalio/internal/bridge/api/core_interface.rb +1 -1
  99. data/lib/temporalio/internal/bridge/api/external_data/external_data.rb +1 -1
  100. data/lib/temporalio/internal/bridge/api/nexus/nexus.rb +3 -2
  101. data/lib/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rb +2 -2
  102. data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +3 -2
  103. data/lib/temporalio/internal/bridge/api/workflow_completion/workflow_completion.rb +1 -1
  104. data/lib/temporalio/internal/bridge/worker.rb +28 -4
  105. data/lib/temporalio/internal/bridge.rb +1 -1
  106. data/lib/temporalio/internal/client/implementation.rb +60 -52
  107. data/lib/temporalio/internal/proto_utils.rb +4 -4
  108. data/lib/temporalio/internal/worker/activity_worker.rb +93 -20
  109. data/lib/temporalio/internal/worker/workflow_instance/child_workflow_handle.rb +8 -6
  110. data/lib/temporalio/internal/worker/workflow_instance/context.rb +65 -24
  111. data/lib/temporalio/internal/worker/workflow_instance/details.rb +5 -2
  112. data/lib/temporalio/internal/worker/workflow_instance/external_workflow_handle.rb +2 -2
  113. data/lib/temporalio/internal/worker/workflow_instance/illegal_call_tracer.rb +64 -18
  114. data/lib/temporalio/internal/worker/workflow_instance/outbound_implementation.rb +28 -14
  115. data/lib/temporalio/internal/worker/workflow_instance.rb +58 -23
  116. data/lib/temporalio/internal/worker/workflow_worker.rb +16 -6
  117. data/lib/temporalio/priority.rb +59 -0
  118. data/lib/temporalio/testing/activity_environment.rb +17 -2
  119. data/lib/temporalio/testing/workflow_environment.rb +3 -3
  120. data/lib/temporalio/version.rb +1 -1
  121. data/lib/temporalio/versioning_override.rb +56 -0
  122. data/lib/temporalio/worker/deployment_options.rb +45 -0
  123. data/lib/temporalio/worker/illegal_workflow_call_validator.rb +64 -0
  124. data/lib/temporalio/worker/interceptor.rb +13 -1
  125. data/lib/temporalio/worker/poller_behavior.rb +61 -0
  126. data/lib/temporalio/worker/thread_pool.rb +1 -1
  127. data/lib/temporalio/worker/workflow_executor/thread_pool.rb +2 -1
  128. data/lib/temporalio/worker/workflow_replayer.rb +12 -13
  129. data/lib/temporalio/worker.rb +63 -27
  130. data/lib/temporalio/worker_deployment_version.rb +67 -0
  131. data/lib/temporalio/workflow/child_workflow_handle.rb +10 -2
  132. data/lib/temporalio/workflow/definition.rb +183 -33
  133. data/lib/temporalio/workflow/external_workflow_handle.rb +3 -1
  134. data/lib/temporalio/workflow/info.rb +4 -1
  135. data/lib/temporalio/workflow.rb +61 -9
  136. data/lib/temporalio.rb +1 -0
  137. data/temporalio.gemspec +1 -0
  138. metadata +12 -3
@@ -47,6 +47,21 @@ module Temporalio
47
47
  @workflow_raw_args = value
48
48
  end
49
49
 
50
+ # Add workflow hints to be passed to converter for workflow args.
51
+ #
52
+ # @param hints [Array<Object>] Hints to add.
53
+ def workflow_arg_hint(*hints)
54
+ @workflow_arg_hints ||= []
55
+ @workflow_arg_hints.concat(hints)
56
+ end
57
+
58
+ # Set workflow result hint to be passed to converter for workflow result.
59
+ #
60
+ # @param hint [Object] Hint to set.
61
+ def workflow_result_hint(hint)
62
+ @workflow_result_hint = hint
63
+ end
64
+
50
65
  # Configure workflow failure exception types. This sets the types of exceptions that, if a
51
66
  # workflow-thrown exception extends, will cause the workflow/update to fail instead of suspending the workflow
52
67
  # via task failure. These are applied in addition to the worker option. If {::Exception} is set, it effectively
@@ -55,7 +70,7 @@ module Temporalio
55
70
  # @param types [Array<Class<Exception>>] Exception types to turn into workflow failures.
56
71
  def workflow_failure_exception_type(*types)
57
72
  types.each do |t|
58
- raise ArgumentError, 'All types must classes inheriting Exception' unless t.is_a?(Class) && t < Exception
73
+ raise ArgumentError, 'All types must classes inheriting Exception' unless t.is_a?(Class) && t <= Exception
59
74
  end
60
75
  @workflow_failure_exception_types ||= []
61
76
  @workflow_failure_exception_types.concat(types)
@@ -91,6 +106,15 @@ module Temporalio
91
106
  end
92
107
  end
93
108
 
109
+ # Set the versioning behavior of this workflow.
110
+ #
111
+ # WARNING: This method is experimental and may change in future versions.
112
+ #
113
+ # @param behavior [VersioningBehavior] The versioning behavior.
114
+ def workflow_versioning_behavior(behavior)
115
+ @versioning_behavior = behavior
116
+ end
117
+
94
118
  # Mark an `initialize` as needing the workflow start arguments. Otherwise, `initialize` must accept no required
95
119
  # arguments. This must be placed above the `initialize` method or it will fail.
96
120
  #
@@ -112,16 +136,20 @@ module Temporalio
112
136
  # {Converters::RawValue} which is a raw payload wrapper, convertible with {Workflow.payload_converter}.
113
137
  # @param unfinished_policy [HandlerUnfinishedPolicy] How to treat unfinished handlers if they are still running
114
138
  # when the workflow ends. The default warns, but this can be disabled.
139
+ # @param arg_hints [Array<Object>, nil] Argument hint(s) for the signal.
115
140
  def workflow_signal(
116
141
  name: nil,
117
142
  description: nil,
118
143
  dynamic: false,
119
144
  raw_args: false,
120
- unfinished_policy: HandlerUnfinishedPolicy::WARN_AND_ABANDON
145
+ unfinished_policy: HandlerUnfinishedPolicy::WARN_AND_ABANDON,
146
+ arg_hints: nil
121
147
  )
122
148
  raise 'Cannot provide name if dynamic is true' if name && dynamic
123
149
 
124
- self.pending_handler_details = { type: :signal, name:, description:, dynamic:, raw_args:, unfinished_policy: }
150
+ self.pending_handler_details =
151
+ { type: :signal, name:, description:, dynamic:, raw_args:, unfinished_policy:,
152
+ arg_hints: Array(arg_hints) }
125
153
  end
126
154
 
127
155
  # Mark the next method as a workflow query with a default name as the name of the method. Queries can not have
@@ -135,15 +163,20 @@ module Temporalio
135
163
  # it is useful to have the second parameter be `*args` and `raw_args` be true.
136
164
  # @param raw_args [Boolean] If true, does not convert arguments, but instead provides each argument as
137
165
  # {Converters::RawValue} which is a raw payload wrapper, convertible with {Workflow.payload_converter}.
166
+ # @param arg_hints [Object, Array<Object>, nil] Argument hint(s) for the query.
167
+ # @param result_hint [Object, nil] Result hint for the query.
138
168
  def workflow_query(
139
169
  name: nil,
140
170
  description: nil,
141
171
  dynamic: false,
142
- raw_args: false
172
+ raw_args: false,
173
+ arg_hints: nil,
174
+ result_hint: nil
143
175
  )
144
176
  raise 'Cannot provide name if dynamic is true' if name && dynamic
145
177
 
146
- self.pending_handler_details = { type: :query, name:, description:, dynamic:, raw_args: }
178
+ self.pending_handler_details = { type: :query, name:, description:, dynamic:, raw_args:,
179
+ arg_hints: Array(arg_hints), result_hint: }
147
180
  end
148
181
 
149
182
  # Mark the next method as a workflow update with a default name as the name of the method. Updates can return
@@ -159,16 +192,21 @@ module Temporalio
159
192
  # {Converters::RawValue} which is a raw payload wrapper, convertible with {Workflow.payload_converter}.
160
193
  # @param unfinished_policy [HandlerUnfinishedPolicy] How to treat unfinished handlers if they are still running
161
194
  # when the workflow ends. The default warns, but this can be disabled.
195
+ # @param arg_hints [Object, Array<Object>, nil] Argument hint(s) for the update.
196
+ # @param result_hint [Object, nil] Result hint for the update.
162
197
  def workflow_update(
163
198
  name: nil,
164
199
  description: nil,
165
200
  dynamic: false,
166
201
  raw_args: false,
167
- unfinished_policy: HandlerUnfinishedPolicy::WARN_AND_ABANDON
202
+ unfinished_policy: HandlerUnfinishedPolicy::WARN_AND_ABANDON,
203
+ arg_hints: nil,
204
+ result_hint: nil
168
205
  )
169
206
  raise 'Cannot provide name if dynamic is true' if name && dynamic
170
207
 
171
- self.pending_handler_details = { type: :update, name:, description:, dynamic:, raw_args:, unfinished_policy: }
208
+ self.pending_handler_details = { type: :update, name:, description:, dynamic:, raw_args:, unfinished_policy:,
209
+ arg_hints: Array(arg_hints), result_hint: }
172
210
  end
173
211
 
174
212
  # Mark the next method as a workflow update validator to the given update method. The validator is expected to
@@ -181,6 +219,24 @@ module Temporalio
181
219
  self.pending_handler_details = { type: :update_validator, update_method: }
182
220
  end
183
221
 
222
+ # Mark the next method as returning some dynamic configuraion.
223
+ #
224
+ # Because dynamic workflows may conceptually represent more than one workflow type, it may
225
+ # be desirable to have different settings for fields that would normally be passed to
226
+ # `workflow_xxx` setters, but vary based on the workflow type name or other information
227
+ # available in the workflow's context. This function will be called after the workflow's
228
+ # `initialize`, if it has one, but before the workflow's `execute` method.
229
+ #
230
+ # The method must only take self as a parameter, and any values set in the class it returns
231
+ # will override those provided to other `workflow_xxx` setters.
232
+ #
233
+ # Cannot be specified on non-dynamic workflows.
234
+ def workflow_dynamic_options
235
+ raise 'Dynamic options method can only be set on workflows using `workflow_dynamic`' unless @workflow_dynamic
236
+
237
+ self.pending_handler_details = { type: :dynamic_options }
238
+ end
239
+
184
240
  private
185
241
 
186
242
  attr_reader :pending_handler_details
@@ -208,6 +264,15 @@ module Temporalio
208
264
  # Reset details
209
265
  self.pending_handler_details = nil
210
266
 
267
+ # Disallow kwargs in parameters
268
+ begin
269
+ if instance_method(method_name).parameters.any? { |t, _| t == :key || t == :keyreq }
270
+ raise "Workflow #{handler[:type]} cannot have keyword arguments"
271
+ end
272
+ rescue NameError
273
+ # Ignore name error
274
+ end
275
+
211
276
  # Initialize class variables if not done already
212
277
  @workflow_signals ||= {}
213
278
  @workflow_queries ||= {}
@@ -239,14 +304,17 @@ module Temporalio
239
304
  to_invoke: method_name,
240
305
  description: handler[:description],
241
306
  raw_args: handler[:raw_args],
242
- unfinished_policy: handler[:unfinished_policy]
307
+ unfinished_policy: handler[:unfinished_policy],
308
+ arg_hints: handler[:arg_hints]
243
309
  ), @workflow_signals, [@workflow_queries, @workflow_updates]]
244
310
  when :query
245
311
  [Query.new(
246
312
  name: handler[:dynamic] ? nil : (handler[:name] || method_name).to_s,
247
313
  to_invoke: method_name,
248
314
  description: handler[:description],
249
- raw_args: handler[:raw_args]
315
+ raw_args: handler[:raw_args],
316
+ arg_hints: handler[:arg_hints],
317
+ result_hint: handler[:result_hint]
250
318
  ), @workflow_queries, [@workflow_signals, @workflow_updates]]
251
319
  when :update
252
320
  [Update.new(
@@ -254,8 +322,15 @@ module Temporalio
254
322
  to_invoke: method_name,
255
323
  description: handler[:description],
256
324
  raw_args: handler[:raw_args],
257
- unfinished_policy: handler[:unfinished_policy]
325
+ unfinished_policy: handler[:unfinished_policy],
326
+ arg_hints: handler[:arg_hints],
327
+ result_hint: handler[:result_hint]
258
328
  ), @workflow_updates, [@workflow_signals, @workflow_queries]]
329
+ when :dynamic_options
330
+ raise 'Dynamic options method already set' if @dynamic_options_method
331
+
332
+ @dynamic_options_method = method_name
333
+ return
259
334
  else
260
335
  raise "Unrecognized handler type #{handler[:type]}"
261
336
  end
@@ -293,7 +368,7 @@ module Temporalio
293
368
  end
294
369
 
295
370
  # @!visibility private
296
- def self._workflow_type_from_workflow_parameter(workflow)
371
+ def self._workflow_type_and_hints_from_workflow_parameter(workflow)
297
372
  case workflow
298
373
  when Class
299
374
  unless workflow < Definition
@@ -301,11 +376,15 @@ module Temporalio
301
376
  end
302
377
 
303
378
  info = Info.from_class(workflow)
304
- info.name || raise(ArgumentError, 'Cannot pass dynamic workflow to start')
379
+ raise(ArgumentError, 'Cannot pass dynamic workflow to start') unless info.name
380
+
381
+ [info.name.to_s, info.arg_hints, info.result_hint]
305
382
  when Info
306
- workflow.name || raise(ArgumentError, 'Cannot pass dynamic workflow to start')
383
+ raise(ArgumentError, 'Cannot pass dynamic workflow to start') unless workflow.name
384
+
385
+ [workflow.name.to_s, nil, nil]
307
386
  when String, Symbol
308
- workflow.to_s
387
+ [workflow.to_s, nil, nil]
309
388
  else
310
389
  raise ArgumentError, 'Workflow is not a workflow class or string/symbol'
311
390
  end
@@ -318,6 +397,11 @@ module Temporalio
318
397
  raise "Leftover #{pending_handler_details&.[](:type)} handler not applied to a method"
319
398
  end
320
399
 
400
+ # Disallow kwargs in execute parameters
401
+ if instance_method(:execute).parameters.any? { |t, _| t == :key || t == :keyreq }
402
+ raise 'Workflow execute cannot have keyword arguments'
403
+ end
404
+
321
405
  # Apply all update validators before merging with super
322
406
  updates = @workflow_updates&.dup || {}
323
407
  @workflow_update_validators&.each_value do |validator|
@@ -387,6 +471,10 @@ module Temporalio
387
471
 
388
472
  raise 'Workflow cannot be given a name and be dynamic' if dynamic && override_name
389
473
 
474
+ if !dynamic && !@dynamic_options_method.nil?
475
+ raise 'Workflow cannot have a dynamic_options_method unless it is dynamic'
476
+ end
477
+
390
478
  Info.new(
391
479
  workflow_class: self,
392
480
  override_name:,
@@ -396,7 +484,11 @@ module Temporalio
396
484
  failure_exception_types: @workflow_failure_exception_types || [],
397
485
  signals:,
398
486
  queries:,
399
- updates:
487
+ updates:,
488
+ versioning_behavior: @versioning_behavior || VersioningBehavior::UNSPECIFIED,
489
+ dynamic_options_method: @dynamic_options_method,
490
+ arg_hints: @workflow_arg_hints,
491
+ result_hint: @workflow_result_hint
400
492
  )
401
493
  end
402
494
 
@@ -409,7 +501,8 @@ module Temporalio
409
501
  # Information about the workflow definition. This is usually not used directly.
410
502
  class Info
411
503
  attr_reader :workflow_class, :override_name, :dynamic, :init, :raw_args,
412
- :failure_exception_types, :signals, :queries, :updates
504
+ :failure_exception_types, :signals, :queries, :updates, :versioning_behavior,
505
+ :dynamic_options_method, :arg_hints, :result_hint
413
506
 
414
507
  # Derive the workflow definition info from the class.
415
508
  #
@@ -434,7 +527,11 @@ module Temporalio
434
527
  failure_exception_types: [],
435
528
  signals: {},
436
529
  queries: {},
437
- updates: {}
530
+ updates: {},
531
+ versioning_behavior: VersioningBehavior::UNSPECIFIED,
532
+ dynamic_options_method: nil,
533
+ arg_hints: nil,
534
+ result_hint: nil
438
535
  )
439
536
  @workflow_class = workflow_class
440
537
  @override_name = override_name
@@ -445,6 +542,10 @@ module Temporalio
445
542
  @signals = signals.dup.freeze
446
543
  @queries = queries.dup.freeze
447
544
  @updates = updates.dup.freeze
545
+ @versioning_behavior = versioning_behavior
546
+ @dynamic_options_method = dynamic_options_method
547
+ @arg_hints = arg_hints
548
+ @result_hint = result_hint
448
549
  Internal::ProtoUtils.assert_non_reserved_name(name)
449
550
  end
450
551
 
@@ -457,15 +558,17 @@ module Temporalio
457
558
  # A signal definition. This is usually built as a result of a {Definition.workflow_signal} method, but can be
458
559
  # manually created to set at runtime on {Workflow.signal_handlers}.
459
560
  class Signal
460
- attr_reader :name, :to_invoke, :description, :raw_args, :unfinished_policy
561
+ attr_reader :name, :to_invoke, :description, :raw_args, :unfinished_policy, :arg_hints
461
562
 
462
563
  # @!visibility private
463
- def self._name_from_parameter(signal)
564
+ def self._name_and_hints_from_parameter(signal)
464
565
  case signal
465
566
  when Workflow::Definition::Signal
466
- signal.name || raise(ArgumentError, 'Cannot call dynamic signal directly')
567
+ raise(ArgumentError, 'Cannot call dynamic signal directly') unless signal.name
568
+
569
+ [signal.name, signal.arg_hints]
467
570
  when String, Symbol
468
- signal.to_s
571
+ [signal.to_s, nil]
469
572
  else
470
573
  raise ArgumentError, 'Signal is not a definition or string/symbol'
471
574
  end
@@ -481,18 +584,21 @@ module Temporalio
481
584
  # @param raw_args [Boolean] Whether the parameters should be raw values.
482
585
  # @param unfinished_policy [HandlerUnfinishedPolicy] How the workflow reacts when this handler is still running
483
586
  # on workflow completion.
587
+ # @param arg_hints [Array<Object>, nil] Argument hints for the signal.
484
588
  def initialize(
485
589
  name:,
486
590
  to_invoke:,
487
591
  description: nil,
488
592
  raw_args: false,
489
- unfinished_policy: HandlerUnfinishedPolicy::WARN_AND_ABANDON
593
+ unfinished_policy: HandlerUnfinishedPolicy::WARN_AND_ABANDON,
594
+ arg_hints: nil
490
595
  )
491
596
  @name = name
492
597
  @to_invoke = to_invoke
493
598
  @description = description
494
599
  @raw_args = raw_args
495
600
  @unfinished_policy = unfinished_policy
601
+ @arg_hints = arg_hints
496
602
  Internal::ProtoUtils.assert_non_reserved_name(name)
497
603
  end
498
604
  end
@@ -500,15 +606,17 @@ module Temporalio
500
606
  # A query definition. This is usually built as a result of a {Definition.workflow_query} method, but can be
501
607
  # manually created to set at runtime on {Workflow.query_handlers}.
502
608
  class Query
503
- attr_reader :name, :to_invoke, :description, :raw_args
609
+ attr_reader :name, :to_invoke, :description, :raw_args, :arg_hints, :result_hint
504
610
 
505
611
  # @!visibility private
506
- def self._name_from_parameter(query)
612
+ def self._name_and_hints_from_parameter(query)
507
613
  case query
508
614
  when Workflow::Definition::Query
509
- query.name || raise(ArgumentError, 'Cannot call dynamic query directly')
615
+ raise(ArgumentError, 'Cannot call dynamic query directly') unless query.name
616
+
617
+ [query.name, query.arg_hints, query.result_hint]
510
618
  when String, Symbol
511
- query.to_s
619
+ [query.to_s, nil, nil]
512
620
  else
513
621
  raise ArgumentError, 'Query is not a definition or string/symbol'
514
622
  end
@@ -522,16 +630,22 @@ module Temporalio
522
630
  # @param description [String, nil] Description for this handler that may appear in CLI/UI. This is currently
523
631
  # experimental.
524
632
  # @param raw_args [Boolean] Whether the parameters should be raw values.
633
+ # @param arg_hints [Array<Object>, nil] Argument hints for the query.
634
+ # @param result_hint [Object, nil] Result hints for the query.
525
635
  def initialize(
526
636
  name:,
527
637
  to_invoke:,
528
638
  description: nil,
529
- raw_args: false
639
+ raw_args: false,
640
+ arg_hints: nil,
641
+ result_hint: nil
530
642
  )
531
643
  @name = name
532
644
  @to_invoke = to_invoke
533
645
  @description = description
534
646
  @raw_args = raw_args
647
+ @arg_hints = arg_hints
648
+ @result_hint = result_hint
535
649
  Internal::ProtoUtils.assert_non_reserved_name(name)
536
650
  end
537
651
  end
@@ -539,15 +653,18 @@ module Temporalio
539
653
  # An update definition. This is usually built as a result of a {Definition.workflow_update} method, but can be
540
654
  # manually created to set at runtime on {Workflow.update_handlers}.
541
655
  class Update
542
- attr_reader :name, :to_invoke, :description, :raw_args, :unfinished_policy, :validator_to_invoke
656
+ attr_reader :name, :to_invoke, :description, :raw_args, :unfinished_policy, :validator_to_invoke,
657
+ :arg_hints, :result_hint
543
658
 
544
659
  # @!visibility private
545
- def self._name_from_parameter(update)
660
+ def self._name_and_hints_from_parameter(update)
546
661
  case update
547
662
  when Workflow::Definition::Update
548
- update.name || raise(ArgumentError, 'Cannot call dynamic update directly')
663
+ raise(ArgumentError, 'Cannot call dynamic update directly') unless update.name
664
+
665
+ [update.name, update.arg_hints, update.result_hint]
549
666
  when String, Symbol
550
- update.to_s
667
+ [update.to_s, nil, nil]
551
668
  else
552
669
  raise ArgumentError, 'Update is not a definition or string/symbol'
553
670
  end
@@ -564,13 +681,17 @@ module Temporalio
564
681
  # @param unfinished_policy [HandlerUnfinishedPolicy] How the workflow reacts when this handler is still running
565
682
  # on workflow completion.
566
683
  # @param validator_to_invoke [Symbol, Proc, nil] Method name or proc validator to invoke.
684
+ # @param arg_hints [Array<Object>, nil] Argument hints for the update.
685
+ # @param result_hint [Object, nil] Result hints for the update.
567
686
  def initialize(
568
687
  name:,
569
688
  to_invoke:,
570
689
  description: nil,
571
690
  raw_args: false,
572
691
  unfinished_policy: HandlerUnfinishedPolicy::WARN_AND_ABANDON,
573
- validator_to_invoke: nil
692
+ validator_to_invoke: nil,
693
+ arg_hints: nil,
694
+ result_hint: nil
574
695
  )
575
696
  @name = name
576
697
  @to_invoke = to_invoke
@@ -578,6 +699,8 @@ module Temporalio
578
699
  @raw_args = raw_args
579
700
  @unfinished_policy = unfinished_policy
580
701
  @validator_to_invoke = validator_to_invoke
702
+ @arg_hints = arg_hints
703
+ @result_hint = result_hint
581
704
  Internal::ProtoUtils.assert_non_reserved_name(name)
582
705
  end
583
706
 
@@ -589,10 +712,37 @@ module Temporalio
589
712
  description:,
590
713
  raw_args:,
591
714
  unfinished_policy:,
592
- validator_to_invoke:
715
+ validator_to_invoke:,
716
+ arg_hints:,
717
+ result_hint:
593
718
  )
594
719
  end
595
720
  end
596
721
  end
722
+
723
+ DefinitionOptions = Struct.new(
724
+ :failure_exception_types,
725
+ :versioning_behavior
726
+ )
727
+ # @!attribute failure_exception_types
728
+ # Dynamic equivalent of {Definition.workflow_failure_exception_type}.
729
+ # Will override any types set there if set, including if set to an empty array.
730
+ # @return [Array<Class<Exception>>, nil] The failure exception types
731
+ #
732
+ # @!attribute versioning_behavior
733
+ # Dynamic equivalent of {Definition.workflow_versioning_behavior}.
734
+ # Will override any behavior set there if set.
735
+ # WARNING: Deployment-based versioning is experimental and APIs may change.
736
+ # @return [VersioningBehavior, nil] The versioning behavior
737
+ #
738
+ # @return [VersioningBehavior, nil] The versioning behavior
739
+ class DefinitionOptions
740
+ def initialize(
741
+ failure_exception_types: nil,
742
+ versioning_behavior: nil
743
+ )
744
+ super
745
+ end
746
+ end
597
747
  end
598
748
  end
@@ -28,7 +28,9 @@ module Temporalio
28
28
  # @param signal [Workflow::Definition::Signal, Symbol, String] Signal definition or name.
29
29
  # @param args [Array<Object>] Signal args.
30
30
  # @param cancellation [Cancellation] Cancellation for canceling the signalling.
31
- def signal(signal, *args, cancellation: Workflow.cancellation)
31
+ # @param arg_hints [Array<Object>, nil] Overrides converter hints for arguments if any. If unset/nil and the
32
+ # signal definition has arg hints, those are used by default.
33
+ def signal(signal, *args, cancellation: Workflow.cancellation, arg_hints: nil)
32
34
  raise NotImplementedError
33
35
  end
34
36
 
@@ -12,6 +12,7 @@ module Temporalio
12
12
  :last_result,
13
13
  :namespace,
14
14
  :parent,
15
+ :priority,
15
16
  :retry_policy,
16
17
  :root,
17
18
  :run_id,
@@ -44,6 +45,8 @@ module Temporalio
44
45
  # @return [String] Namespace for the workflow.
45
46
  # @!attribute parent
46
47
  # @return [ParentInfo, nil] Parent information for the workflow if this is a child.
48
+ # @!attribute priority
49
+ # @return [Priority] The priority of this workflow.
47
50
  # @!attribute retry_policy
48
51
  # @return [RetryPolicy, nil] Retry policy for the workflow.
49
52
  # @!attribute root
@@ -54,7 +57,7 @@ module Temporalio
54
57
  # @!attribute run_timeout
55
58
  # @return [Float, nil] Run timeout for the workflow.
56
59
  # @!attribute start_time
57
- # @return [Time] Time when the workflow started.
60
+ # @return [Time] Time when the workflow started on the server.
58
61
  # @!attribute task_queue
59
62
  # @return [String] Task queue for the workflow.
60
63
  # @!attribute task_timeout
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'random/formatter'
4
4
  require 'temporalio/error'
5
+ require 'temporalio/priority'
5
6
  require 'temporalio/workflow/activity_cancellation_type'
6
7
  require 'temporalio/workflow/child_workflow_cancellation_type'
7
8
  require 'temporalio/workflow/child_workflow_handle'
@@ -56,6 +57,18 @@ module Temporalio
56
57
  _current.current_details = details
57
58
  end
58
59
 
60
+ # Get the deployment version of the worker which executed the current Workflow Task.
61
+ #
62
+ # May be nil if the task was completed by a worker without a deployment version or build id. If
63
+ # this worker is the one executing this task for the first time and has a deployment version
64
+ # set, then its ID will be used. This value may change over the lifetime of the workflow run,
65
+ # but is deterministic and safe to use for branching. This is currently experimental.
66
+ #
67
+ # @return [WorkerDeploymentVersion, nil] the current deployment version if any.
68
+ def self.current_deployment_version
69
+ _current.current_deployment_version
70
+ end
71
+
59
72
  # @return [Integer] Current number of events in history. This value is the current history event count up until the
60
73
  # current task. Note, this value may not be up to date when accessed in a query.
61
74
  def self.current_history_length
@@ -118,6 +131,11 @@ module Temporalio
118
131
  # optimization on some servers that sends activities back to the same worker as the calling workflow if they can
119
132
  # run there. If `false` (the default), eager execution may still be disabled at the worker level or may not be
120
133
  # requested due to lack of available slots.
134
+ # @param priority [Priority] Priority of the activity. This is currently experimental.
135
+ # @param arg_hints [Array<Object>, nil] Overrides converter hints for arguments if any. If unset/nil and the
136
+ # activity definition has arg hints, those are used by default.
137
+ # @param result_hint [Object, nil] Overrides converter hint for result if any. If unset/nil and the activity
138
+ # definition has result hint, it is used by default.
121
139
  #
122
140
  # @return [Object] Result of the activity.
123
141
  # @raise [Error::ActivityError] Activity failed (and retry was disabled or exhausted).
@@ -136,12 +154,16 @@ module Temporalio
136
154
  cancellation: Workflow.cancellation,
137
155
  cancellation_type: ActivityCancellationType::TRY_CANCEL,
138
156
  activity_id: nil,
139
- disable_eager_execution: false
157
+ disable_eager_execution: false,
158
+ priority: Priority.default,
159
+ arg_hints: nil,
160
+ result_hint: nil
140
161
  )
141
162
  _current.execute_activity(
142
163
  activity, *args,
143
164
  task_queue:, summary:, schedule_to_close_timeout:, schedule_to_start_timeout:, start_to_close_timeout:,
144
- heartbeat_timeout:, retry_policy:, cancellation:, cancellation_type:, activity_id:, disable_eager_execution:
165
+ heartbeat_timeout:, retry_policy:, cancellation:, cancellation_type:, activity_id:, disable_eager_execution:,
166
+ priority:, arg_hints:, result_hint:
145
167
  )
146
168
  end
147
169
 
@@ -163,13 +185,16 @@ module Temporalio
163
185
  retry_policy: nil,
164
186
  cron_schedule: nil,
165
187
  memo: nil,
166
- search_attributes: nil
188
+ search_attributes: nil,
189
+ priority: Priority.default,
190
+ arg_hints: nil,
191
+ result_hint: nil
167
192
  )
168
193
  start_child_workflow(
169
194
  workflow, *args,
170
195
  id:, task_queue:, static_summary:, static_details:, cancellation:, cancellation_type:,
171
196
  parent_close_policy:, execution_timeout:, run_timeout:, task_timeout:, id_reuse_policy:,
172
- retry_policy:, cron_schedule:, memo:, search_attributes:
197
+ retry_policy:, cron_schedule:, memo:, search_attributes:, priority:, arg_hints:, result_hint:
173
198
  ).result
174
199
  end
175
200
 
@@ -200,6 +225,10 @@ module Temporalio
200
225
  # workflow.
201
226
  # @param activity_id [String, nil] Optional unique identifier for the activity. This is an advanced setting that
202
227
  # should not be set unless users are sure they need to. Contact Temporal before setting this value.
228
+ # @param arg_hints [Array<Object>, nil] Overrides converter hints for arguments if any. If unset/nil and the
229
+ # activity definition has arg hints, those are used by default.
230
+ # @param result_hint [Object, nil] Overrides converter hint for result if any. If unset/nil and the activity
231
+ # definition has result hint, it is used by default.
203
232
  #
204
233
  # @return [Object] Result of the activity.
205
234
  # @raise [Error::ActivityError] Activity failed (and retry was disabled or exhausted).
@@ -215,12 +244,15 @@ module Temporalio
215
244
  local_retry_threshold: nil,
216
245
  cancellation: Workflow.cancellation,
217
246
  cancellation_type: ActivityCancellationType::TRY_CANCEL,
218
- activity_id: nil
247
+ activity_id: nil,
248
+ arg_hints: nil,
249
+ result_hint: nil
219
250
  )
220
251
  _current.execute_local_activity(
221
252
  activity, *args,
222
253
  schedule_to_close_timeout:, schedule_to_start_timeout:, start_to_close_timeout:,
223
- retry_policy:, local_retry_threshold:, cancellation:, cancellation_type:, activity_id:
254
+ retry_policy:, local_retry_threshold:, cancellation:, cancellation_type:,
255
+ activity_id:, arg_hints:, result_hint:
224
256
  )
225
257
  end
226
258
 
@@ -360,6 +392,11 @@ module Temporalio
360
392
  # @param cron_schedule [String, nil] Cron schedule. Users should use schedules instead of this.
361
393
  # @param memo [Hash{String, Symbol => Object}, nil] Memo for the workflow.
362
394
  # @param search_attributes [SearchAttributes, nil] Search attributes for the workflow.
395
+ # @param priority [Priority] Priority of the workflow. This is currently experimental.
396
+ # @param arg_hints [Array<Object>, nil] Overrides converter hints for arguments if any. If unset/nil and the
397
+ # workflow definition has arg hints, those are used by default.
398
+ # @param result_hint [Object, nil] Overrides converter hint for result if any. If unset/nil and the workflow
399
+ # definition has result hint, it is used by default.
363
400
  #
364
401
  # @return [ChildWorkflowHandle] Workflow handle to the started workflow.
365
402
  # @raise [Error::WorkflowAlreadyStartedError] Workflow already exists for the ID.
@@ -381,13 +418,16 @@ module Temporalio
381
418
  retry_policy: nil,
382
419
  cron_schedule: nil,
383
420
  memo: nil,
384
- search_attributes: nil
421
+ search_attributes: nil,
422
+ priority: Priority.default,
423
+ arg_hints: nil,
424
+ result_hint: nil
385
425
  )
386
426
  _current.start_child_workflow(
387
427
  workflow, *args,
388
428
  id:, task_queue:, static_summary:, static_details:, cancellation:, cancellation_type:,
389
429
  parent_close_policy:, execution_timeout:, run_timeout:, task_timeout:, id_reuse_policy:,
390
- retry_policy:, cron_schedule:, memo:, search_attributes:
430
+ retry_policy:, cron_schedule:, memo:, search_attributes:, priority:, arg_hints:, result_hint:
391
431
  )
392
432
  end
393
433
 
@@ -510,12 +550,20 @@ module Temporalio
510
550
  def self.io_enabled(&)
511
551
  Workflow._current.io_enabled(&)
512
552
  end
553
+
554
+ # Run a block of code with the durable/deterministic workflow Fiber scheduler off. This means fallback to default
555
+ # fiber scheduler and no workflow helpers will be available in the block. This is usually only needed in advanced
556
+ # situations where a third party library does something like use "Timeout" in a way that shouldn't be made
557
+ # durable.
558
+ def self.durable_scheduler_disabled(&)
559
+ Workflow._current.durable_scheduler_disabled(&)
560
+ end
513
561
  end
514
562
 
515
563
  # Error that is raised by a workflow out of the primary workflow method to issue a continue-as-new.
516
564
  class ContinueAsNewError < Error
517
565
  attr_accessor :args, :workflow, :task_queue, :run_timeout, :task_timeout,
518
- :retry_policy, :memo, :search_attributes, :headers
566
+ :retry_policy, :memo, :search_attributes, :arg_hints, :headers
519
567
 
520
568
  # Create a continue as new error.
521
569
  #
@@ -534,6 +582,8 @@ module Temporalio
534
582
  # is used.
535
583
  # @param search_attributes [SearchAttributes, nil] Search attributes for the workflow. If unset/nil, the current
536
584
  # workflow search attributes are used.
585
+ # @param arg_hints [Array<Object>, nil] Overrides converter hints for arguments if any. If unset/nil and the
586
+ # workflow definition has arg hints, those are used by default.
537
587
  # @param headers [Hash<String, Object>] Headers for the workflow. The default is _not_ carried over from the
538
588
  # current workflow.
539
589
  def initialize(
@@ -545,6 +595,7 @@ module Temporalio
545
595
  retry_policy: nil,
546
596
  memo: nil,
547
597
  search_attributes: nil,
598
+ arg_hints: nil,
548
599
  headers: {}
549
600
  )
550
601
  super('Continue as new')
@@ -556,6 +607,7 @@ module Temporalio
556
607
  @retry_policy = retry_policy
557
608
  @memo = memo
558
609
  @search_attributes = search_attributes
610
+ @arg_hints = arg_hints
559
611
  @headers = headers
560
612
  Workflow._current.initialize_continue_as_new_error(self)
561
613
  end