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
@@ -6,12 +6,16 @@ require 'temporalio/client'
6
6
  require 'temporalio/error'
7
7
  require 'temporalio/internal/bridge'
8
8
  require 'temporalio/internal/bridge/worker'
9
+ require 'temporalio/internal/proto_utils'
9
10
  require 'temporalio/internal/worker/activity_worker'
10
11
  require 'temporalio/internal/worker/multi_runner'
11
12
  require 'temporalio/internal/worker/workflow_instance'
12
13
  require 'temporalio/internal/worker/workflow_worker'
13
14
  require 'temporalio/worker/activity_executor'
15
+ require 'temporalio/worker/deployment_options'
16
+ require 'temporalio/worker/illegal_workflow_call_validator'
14
17
  require 'temporalio/worker/interceptor'
18
+ require 'temporalio/worker/poller_behavior'
15
19
  require 'temporalio/worker/thread_pool'
16
20
  require 'temporalio/worker/tuner'
17
21
  require 'temporalio/worker/workflow_executor'
@@ -32,7 +36,6 @@ module Temporalio
32
36
  :activity_executors,
33
37
  :workflow_executor,
34
38
  :interceptors,
35
- :build_id,
36
39
  :identity,
37
40
  :logger,
38
41
  :max_cached_workflows,
@@ -46,15 +49,20 @@ module Temporalio
46
49
  :max_activities_per_second,
47
50
  :max_task_queue_activities_per_second,
48
51
  :graceful_shutdown_period,
49
- :use_worker_versioning,
50
52
  :disable_eager_activity_execution,
51
53
  :illegal_workflow_calls,
52
54
  :workflow_failure_exception_types,
53
55
  :workflow_payload_codec_thread_pool,
56
+ :unsafe_workflow_io_enabled,
57
+ :deployment_options,
58
+ :workflow_task_poller_behavior,
59
+ :activity_task_poller_behavior,
54
60
  :debug_mode
55
61
  )
56
62
 
57
63
  # Options as returned from {options} for `**to_h` splat use in {initialize}. See {initialize} for details.
64
+ #
65
+ # Note, the `client` within can be replaced via client setter.
58
66
  class Options; end # rubocop:disable Lint/EmptyClass
59
67
 
60
68
  # @return [String] Memoized default build ID. This default value is built as a checksum of all of the loaded Ruby
@@ -85,6 +93,14 @@ module Temporalio
85
93
  build_id
86
94
  end
87
95
 
96
+ # @return [DeploymentOptions] Default deployment options, which does not use worker versioning
97
+ # or a deployment name, and sets the build id to the one from {self.default_build_id}.
98
+ def self.default_deployment_options
99
+ @default_deployment_options ||= DeploymentOptions.new(
100
+ version: WorkerDeploymentVersion.new(deployment_name: '', build_id: Worker.default_build_id)
101
+ )
102
+ end
103
+
88
104
  # Run all workers until cancellation or optional block completes. When the cancellation or block is complete, the
89
105
  # workers are shut down. This will return the block result if everything successful or raise an error if not. See
90
106
  # {run} for details on how worker shutdown works.
@@ -137,7 +153,8 @@ module Temporalio
137
153
  case event
138
154
  when Internal::Worker::MultiRunner::Event::PollSuccess
139
155
  # Successful poll
140
- event.worker._on_poll_bytes(runner, event.worker_type, event.bytes)
156
+ event.worker #: Worker
157
+ ._on_poll_bytes(runner, event.worker_type, event.bytes)
141
158
  when Internal::Worker::MultiRunner::Event::PollFailure
142
159
  # Poll failure, this causes shutdown of all workers
143
160
  logger.error('Poll failure (beginning worker shutdown if not already occurring)')
@@ -227,8 +244,9 @@ module Temporalio
227
244
  end
228
245
  end
229
246
 
230
- # @return [Hash<String, [:all, Array<Symbol>]>] Default, immutable set illegal calls used for the
231
- # `illegal_workflow_calls` worker option. See the documentation of that option for more details.
247
+ # @return [Hash<String, [:all, Array<Symbol, IllegalWorkflowCallValidator>, IllegalWorkflowCallValidator]>] Default,
248
+ # immutable set illegal calls used for the `illegal_workflow_calls` worker option. See the documentation of that
249
+ # option for more details.
232
250
  def self.default_illegal_workflow_calls
233
251
  @default_illegal_workflow_calls ||= begin
234
252
  hash = {
@@ -267,14 +285,14 @@ module Temporalio
267
285
  'Thread' => %i[abort_on_exception= exit fork handle_interrupt ignore_deadlock= kill new pass
268
286
  pending_interrupt? report_on_exception= start stop initialize join name= priority= raise run
269
287
  terminate thread_variable_set wakeup],
270
- 'Time' => %i[initialize now]
288
+ 'Time' => IllegalWorkflowCallValidator.default_time_validators
271
289
  } #: Hash[String, :all | Array[Symbol]]
272
290
  hash.each_value(&:freeze)
273
291
  hash.freeze
274
292
  end
275
293
  end
276
294
 
277
- # @return [Options] Frozen options for this client which has the same attributes as {initialize}.
295
+ # @return [Options] Options for this worker which has the same attributes as {initialize}.
278
296
  attr_reader :options
279
297
 
280
298
  # Create a new worker. At least one activity or workflow must be present.
@@ -291,9 +309,6 @@ module Temporalio
291
309
  # @param interceptors [Array<Interceptor::Activity, Interceptor::Workflow>] Interceptors specific to this worker.
292
310
  # Note, interceptors set on the client that include the {Interceptor::Activity} or {Interceptor::Workflow} module
293
311
  # are automatically included here, so no need to specify them again.
294
- # @param build_id [String] Unique identifier for the current runtime. This is best set as a unique value
295
- # representing all code and should change only when code does. This can be something like a git commit hash. If
296
- # unset, default is hash of known Ruby code.
297
312
  # @param identity [String, nil] Override the identity for this worker. If unset, client identity is used.
298
313
  # @param logger [Logger] Logger to override client logger with. Default is the client logger.
299
314
  # @param max_cached_workflows [Integer] Number of workflows held in cache for use by sticky task queue. If set to 0,
@@ -322,19 +337,19 @@ module Temporalio
322
337
  # multiple workers on the same queue have different values set, they will thrash with the last poller winning.
323
338
  # @param graceful_shutdown_period [Float] Amount of time after shutdown is called that activities are given to
324
339
  # complete before their tasks are canceled.
325
- # @param use_worker_versioning [Boolean] If true, the `build_id` argument must be specified, and this worker opts
326
- # into the worker versioning feature. This ensures it only receives workflow tasks for workflows which it claims
327
- # to be compatible with. For more information, see https://docs.temporal.io/workers#worker-versioning.
328
340
  # @param disable_eager_activity_execution [Boolean] If true, disables eager activity execution. Eager activity
329
341
  # execution is an optimization on some servers that sends activities back to the same worker as the calling
330
342
  # workflow if they can run there. This should be set to true for `max_task_queue_activities_per_second` to work
331
343
  # and in a future version of this API may be implied as such (i.e. this setting will be ignored if that setting is
332
344
  # set).
333
- # @param illegal_workflow_calls [Hash<String, [:all, Array<Symbol>]>] Set of illegal workflow calls that are
334
- # considered unsafe/non-deterministic and will raise if seen. The key of the hash is the fully qualified string
335
- # class name (no leading `::`). The value is either `:all` which means any use of the class, or an array of
336
- # symbols for methods on the class that cannot be used. The methods refer to either instance or class methods,
337
- # there is no way to differentiate at this time.
345
+ # @param illegal_workflow_calls [Hash<String,
346
+ # [:all, Array<Symbol, IllegalWorkflowCallValidator>, IllegalWorkflowCallValidator]>] Set of illegal workflow
347
+ # calls that are considered unsafe/non-deterministic and will raise if seen. The key of the hash is the fully
348
+ # qualified string class name (no leading `::`). The value can be `:all` which means any use of the class is
349
+ # illegal. The value can be an array of symbols/validators for methods on the class that cannot be used. The
350
+ # methods refer to either instance or class methods, there is no way to differentiate at this time. Symbol method
351
+ # names are the normal way to say the method cannot be used, validators are only for advanced situations. Finally,
352
+ # for advanced situations, the hash value can be a class-level validator that is not tied to a specific method.
338
353
  # @param workflow_failure_exception_types [Array<Class<Exception>>] Workflow failure exception types. This is the
339
354
  # set of exception types that, if a workflow-thrown exception extends, will cause the workflow/update to fail
340
355
  # instead of suspending the workflow via task failure. These are applied in addition to the
@@ -343,6 +358,15 @@ module Temporalio
343
358
  # @param workflow_payload_codec_thread_pool [ThreadPool, nil] Thread pool to run payload codec encode/decode within.
344
359
  # This is required if a payload codec exists and the worker is not fiber based. Codecs can potentially block
345
360
  # execution which is why they need to be run in the background.
361
+ # @param unsafe_workflow_io_enabled [Boolean] If false, the default, workflow code that invokes io_wait on the fiber
362
+ # scheduler will fail. Instead of setting this to true, users are encouraged to use {Workflow::Unsafe.io_enabled}
363
+ # with a block for narrower enabling of IO.
364
+ # @param deployment_options [DeploymentOptions, nil] Deployment options for the worker.
365
+ # WARNING: This is an experimental feature and may change in the future.
366
+ # @param workflow_task_poller_behavior [PollerBehavior] Specify the behavior of workflow task
367
+ # polling. Defaults to a 5-poller maximum.
368
+ # @param activity_task_poller_behavior [PollerBehavior] Specify the behavior of activity task
369
+ # polling. Defaults to a 5-poller maximum.
346
370
  # @param debug_mode [Boolean] If true, deadlock detection is disabled. Deadlock detection will fail workflow tasks
347
371
  # if they block the thread for too long. This defaults to true if the `TEMPORAL_DEBUG` environment variable is
348
372
  # `true` or `1`.
@@ -355,7 +379,6 @@ module Temporalio
355
379
  activity_executors: ActivityExecutor.defaults,
356
380
  workflow_executor: WorkflowExecutor::ThreadPool.default,
357
381
  interceptors: [],
358
- build_id: Worker.default_build_id,
359
382
  identity: nil,
360
383
  logger: client.options.logger,
361
384
  max_cached_workflows: 1000,
@@ -369,15 +392,20 @@ module Temporalio
369
392
  max_activities_per_second: nil,
370
393
  max_task_queue_activities_per_second: nil,
371
394
  graceful_shutdown_period: 0,
372
- use_worker_versioning: false,
373
395
  disable_eager_activity_execution: false,
374
396
  illegal_workflow_calls: Worker.default_illegal_workflow_calls,
375
397
  workflow_failure_exception_types: [],
376
398
  workflow_payload_codec_thread_pool: nil,
399
+ unsafe_workflow_io_enabled: false,
400
+ deployment_options: Worker.default_deployment_options,
401
+ workflow_task_poller_behavior: PollerBehavior::SimpleMaximum.new(max_concurrent_workflow_task_polls),
402
+ activity_task_poller_behavior: PollerBehavior::SimpleMaximum.new(max_concurrent_activity_task_polls),
377
403
  debug_mode: %w[true 1].include?(ENV['TEMPORAL_DEBUG'].to_s.downcase)
378
404
  )
379
405
  raise ArgumentError, 'Must have at least one activity or workflow' if activities.empty? && workflows.empty?
380
406
 
407
+ Internal::ProtoUtils.assert_non_reserved_name(task_queue)
408
+
381
409
  @options = Options.new(
382
410
  client:,
383
411
  task_queue:,
@@ -387,7 +415,6 @@ module Temporalio
387
415
  activity_executors:,
388
416
  workflow_executor:,
389
417
  interceptors:,
390
- build_id:,
391
418
  identity:,
392
419
  logger:,
393
420
  max_cached_workflows:,
@@ -401,29 +428,29 @@ module Temporalio
401
428
  max_activities_per_second:,
402
429
  max_task_queue_activities_per_second:,
403
430
  graceful_shutdown_period:,
404
- use_worker_versioning:,
405
431
  disable_eager_activity_execution:,
406
432
  illegal_workflow_calls:,
407
433
  workflow_failure_exception_types:,
408
434
  workflow_payload_codec_thread_pool:,
435
+ unsafe_workflow_io_enabled:,
436
+ deployment_options:,
437
+ workflow_task_poller_behavior:,
438
+ activity_task_poller_behavior:,
409
439
  debug_mode:
410
440
  ).freeze
411
441
 
442
+ should_enforce_versioning_behavior =
443
+ deployment_options.use_worker_versioning &&
444
+ deployment_options.default_versioning_behavior == VersioningBehavior::UNSPECIFIED
412
445
  # Preload workflow definitions and some workflow settings for the bridge
413
- workflow_definitions = Internal::Worker::WorkflowWorker.workflow_definitions(workflows)
414
- nondeterminism_as_workflow_fail = workflow_failure_exception_types.any? do |t|
415
- t.is_a?(Class) && t >= Workflow::NondeterminismError
416
- end
417
- nondeterminism_as_workflow_fail_for_types = workflow_definitions.values.map do |defn|
418
- next unless defn.failure_exception_types.any? { |t| t.is_a?(Class) && t >= Workflow::NondeterminismError }
419
-
420
- # If they tried to do this on a dynamic workflow and haven't already set worker-level option, warn
421
- unless defn.name || nondeterminism_as_workflow_fail
422
- warn('Note, dynamic workflows cannot trap non-determinism errors, so worker-level ' \
423
- 'workflow_failure_exception_types should be set to capture that if that is the intention')
424
- end
425
- defn.name
426
- end.compact
446
+ workflow_definitions = Internal::Worker::WorkflowWorker.workflow_definitions(
447
+ workflows,
448
+ should_enforce_versioning_behavior: should_enforce_versioning_behavior
449
+ )
450
+ nondeterminism_as_workflow_fail, nondeterminism_as_workflow_fail_for_types =
451
+ Internal::Worker::WorkflowWorker.bridge_workflow_failure_exception_type_options(
452
+ workflow_failure_exception_types:, workflow_definitions:
453
+ )
427
454
 
428
455
  # Create the bridge worker
429
456
  @bridge_worker = Internal::Bridge::Worker.new(
@@ -433,17 +460,12 @@ module Temporalio
433
460
  workflow: !workflows.empty?,
434
461
  namespace: client.namespace,
435
462
  task_queue:,
436
- tuner: Internal::Bridge::Worker::TunerOptions.new(
437
- workflow_slot_supplier: to_bridge_slot_supplier_options(tuner.workflow_slot_supplier),
438
- activity_slot_supplier: to_bridge_slot_supplier_options(tuner.activity_slot_supplier),
439
- local_activity_slot_supplier: to_bridge_slot_supplier_options(tuner.local_activity_slot_supplier)
440
- ),
441
- build_id:,
463
+ tuner: tuner._to_bridge_options,
442
464
  identity_override: identity,
443
465
  max_cached_workflows:,
444
- max_concurrent_workflow_task_polls:,
466
+ workflow_task_poller_behavior: workflow_task_poller_behavior._to_bridge_options,
445
467
  nonsticky_to_sticky_poll_ratio:,
446
- max_concurrent_activity_task_polls:,
468
+ activity_task_poller_behavior: activity_task_poller_behavior._to_bridge_options,
447
469
  # For shutdown to work properly, we must disable remote activities
448
470
  # ourselves if there are no activities
449
471
  no_remote_activities: no_remote_activities || activities.empty?,
@@ -453,9 +475,9 @@ module Temporalio
453
475
  max_worker_activities_per_second: max_activities_per_second,
454
476
  max_task_queue_activities_per_second:,
455
477
  graceful_shutdown_period:,
456
- use_worker_versioning:,
457
478
  nondeterminism_as_workflow_fail:,
458
- nondeterminism_as_workflow_fail_for_types:
479
+ nondeterminism_as_workflow_fail_for_types:,
480
+ deployment_options: deployment_options._to_bridge_options
459
481
  )
460
482
  )
461
483
 
@@ -476,13 +498,31 @@ module Temporalio
476
498
  bridge_worker: @bridge_worker)
477
499
  end
478
500
  unless workflows.empty?
479
- @workflow_worker = Internal::Worker::WorkflowWorker.new(worker: self,
480
- bridge_worker: @bridge_worker,
481
- workflow_definitions:)
501
+ @workflow_worker = Internal::Worker::WorkflowWorker.new(
502
+ bridge_worker: @bridge_worker,
503
+ namespace: client.namespace,
504
+ task_queue:,
505
+ workflow_definitions:,
506
+ workflow_executor:,
507
+ logger:,
508
+ data_converter: client.data_converter,
509
+ metric_meter: client.connection.options.runtime.metric_meter,
510
+ workflow_interceptors: @workflow_interceptors,
511
+ disable_eager_activity_execution:,
512
+ illegal_workflow_calls:,
513
+ workflow_failure_exception_types:,
514
+ workflow_payload_codec_thread_pool:,
515
+ unsafe_workflow_io_enabled:,
516
+ debug_mode:,
517
+ assert_valid_local_activity: ->(activity) { _assert_valid_local_activity(activity) }
518
+ )
482
519
  end
483
520
 
484
521
  # Validate worker
485
522
  @bridge_worker.validate
523
+
524
+ # Mutex needed for accessing and replacing a client
525
+ @client_mutex = Mutex.new
486
526
  end
487
527
 
488
528
  # @return [String] Task queue set on the worker options.
@@ -490,6 +530,25 @@ module Temporalio
490
530
  @options.task_queue
491
531
  end
492
532
 
533
+ # @return [Client] Client for this worker. This is the same as {Options.client} in {options}, but surrounded by a
534
+ # mutex to be safe for client replacement in {client=}.
535
+ def client
536
+ @client_mutex.synchronize { @options.client }
537
+ end
538
+
539
+ # Replace the worker's client. When this is called, the client is replaced on the internal worker which means any
540
+ # new calls will be made on the new client (but existing calls will still complete on the previous one). This is
541
+ # commonly used for providing a new client with updated authentication credentials.
542
+ #
543
+ # @param new_client [Client] New client to use for new calls.
544
+ def client=(new_client)
545
+ @client_mutex.synchronize do
546
+ @bridge_worker.replace_client(new_client.connection._core_client)
547
+ @options = @options.with(client: new_client)
548
+ new_client
549
+ end
550
+ end
551
+
493
552
  # Run this worker until cancellation or optional block completes. When the cancellation or block is complete, the
494
553
  # worker is shut down. This will return the block result if everything successful or raise an error if not.
495
554
  #
@@ -543,11 +602,6 @@ module Temporalio
543
602
  @activity_interceptors
544
603
  end
545
604
 
546
- # @!visibility private
547
- def _workflow_interceptors
548
- @workflow_interceptors
549
- end
550
-
551
605
  # @!visibility private
552
606
  def _on_poll_bytes(runner, worker_type, bytes)
553
607
  case worker_type
@@ -570,28 +624,16 @@ module Temporalio
570
624
  @workflow_worker = nil
571
625
  end
572
626
 
573
- private
574
-
575
- def to_bridge_slot_supplier_options(slot_supplier)
576
- if slot_supplier.is_a?(Tuner::SlotSupplier::Fixed)
577
- Internal::Bridge::Worker::TunerSlotSupplierOptions.new(
578
- fixed_size: slot_supplier.slots,
579
- resource_based: nil
580
- )
581
- elsif slot_supplier.is_a?(Tuner::SlotSupplier::ResourceBased)
582
- Internal::Bridge::Worker::TunerSlotSupplierOptions.new(
583
- fixed_size: nil,
584
- resource_based: Internal::Bridge::Worker::TunerResourceBasedSlotSupplierOptions.new(
585
- target_mem_usage: slot_supplier.tuner_options.target_memory_usage,
586
- target_cpu_usage: slot_supplier.tuner_options.target_cpu_usage,
587
- min_slots: slot_supplier.slot_options.min_slots,
588
- max_slots: slot_supplier.slot_options.max_slots,
589
- ramp_throttle: slot_supplier.slot_options.ramp_throttle
590
- )
591
- )
592
- else
593
- raise ArgumentError, 'Tuner slot suppliers must be instances of Fixed or ResourceBased'
627
+ # @!visibility private
628
+ def _assert_valid_local_activity(activity)
629
+ unless @activity_worker.nil?
630
+ @activity_worker.assert_valid_activity(activity)
631
+ return
594
632
  end
633
+
634
+ raise ArgumentError,
635
+ "Activity #{activity} " \
636
+ 'is not registered on this worker, no available activities.'
595
637
  end
596
638
  end
597
639
  end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'temporalio/internal/bridge/worker'
4
+
5
+ module Temporalio
6
+ WorkerDeploymentVersion = Data.define(
7
+ :deployment_name,
8
+ :build_id
9
+ )
10
+
11
+ # Represents the version of a specific worker deployment.
12
+ #
13
+ # WARNING: Experimental API.
14
+ class WorkerDeploymentVersion
15
+ # Parse a version from a canonical string, which must be in the format
16
+ # `<deployment_name>.<build_id>`. Deployment name must not have a `.` in it.
17
+ #
18
+ # @param canonical [String] The canonical string representation of the version.
19
+ # @return [WorkerDeploymentVersion] The parsed version.
20
+ def self.from_canonical_string(canonical)
21
+ parts = canonical.split('.', 2)
22
+ if parts.length != 2
23
+ raise ArgumentError,
24
+ "Cannot parse version string: #{canonical}, must be in format <deployment_name>.<build_id>"
25
+ end
26
+ new(deployment_name: parts[0], build_id: parts[1])
27
+ end
28
+
29
+ # @!visibility private
30
+ def self._from_bridge(bridge)
31
+ return nil if bridge.nil?
32
+
33
+ new(deployment_name: bridge.deployment_name, build_id: bridge.build_id)
34
+ end
35
+
36
+ # Create WorkerDeploymentVersion.
37
+ #
38
+ # @param deployment_name [String] The name of the deployment.
39
+ # @param build_id [String] The build identifier specific to this worker build.
40
+ def initialize(deployment_name:, build_id:) # rubocop:disable Lint/UselessMethodDefinition
41
+ super
42
+ end
43
+
44
+ # Returns the canonical string representation of the version.
45
+ #
46
+ # @return [String]
47
+ def to_canonical_string
48
+ "#{deployment_name}.#{build_id}"
49
+ end
50
+
51
+ # @!visibility private
52
+ def _to_bridge_options
53
+ Internal::Bridge::Worker::WorkerDeploymentVersion.new(
54
+ deployment_name: deployment_name,
55
+ build_id: build_id
56
+ )
57
+ end
58
+
59
+ # @!visibility private
60
+ def _to_proto
61
+ Api::Deployment::V1::WorkerDeploymentVersion.new(
62
+ deployment_name: deployment_name,
63
+ build_id: build_id
64
+ )
65
+ end
66
+ end
67
+ end
@@ -21,12 +21,18 @@ module Temporalio
21
21
  raise NotImplementedError
22
22
  end
23
23
 
24
+ # @return [Object, nil] Hint for the result if any.
25
+ def result_hint
26
+ raise NotImplementedError
27
+ end
28
+
24
29
  # Wait for the result.
25
30
  #
31
+ # @param result_hint [Object, nil] Override the result hint, or if nil uses the one on the handle.
26
32
  # @return [Object] Result of the child workflow.
27
33
  #
28
34
  # @raise [Error::ChildWorkflowError] Workflow failed with +cause+ as the cause.
29
- def result
35
+ def result(result_hint: nil)
30
36
  raise NotImplementedError
31
37
  end
32
38
 
@@ -35,7 +41,9 @@ module Temporalio
35
41
  # @param signal [Workflow::Definition::Signal, Symbol, String] Signal definition or name.
36
42
  # @param args [Array<Object>] Signal args.
37
43
  # @param cancellation [Cancellation] Cancellation for canceling the signalling.
38
- def signal(signal, *args, cancellation: Workflow.cancellation)
44
+ # @param arg_hints [Array<Object>, nil] Overrides converter hints for arguments if any. If unset/nil and the
45
+ # signal definition has arg hints, those are used by default.
46
+ def signal(signal, *args, cancellation: Workflow.cancellation, arg_hints: nil)
39
47
  raise NotImplementedError
40
48
  end
41
49
  end