temporalio 1.0.0 → 1.2.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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +767 -692
  3. data/Cargo.toml +15 -6
  4. data/Gemfile +9 -4
  5. data/README.md +2 -2
  6. data/ext/Cargo.toml +8 -9
  7. data/lib/temporalio/activity/definition.rb +6 -1
  8. data/lib/temporalio/api/activity/v1/message.rb +11 -2
  9. data/lib/temporalio/api/cloud/account/v1/message.rb +3 -1
  10. data/lib/temporalio/api/cloud/cloudservice/v1/request_response.rb +5 -1
  11. data/lib/temporalio/api/cloud/cloudservice/v1/service.rb +1 -1
  12. data/lib/temporalio/api/cloud/sink/v1/message.rb +3 -1
  13. data/lib/temporalio/api/command/v1/message.rb +1 -1
  14. data/lib/temporalio/api/common/v1/message.rb +2 -1
  15. data/lib/temporalio/api/deployment/v1/message.rb +2 -1
  16. data/lib/temporalio/api/enums/v1/activity.rb +23 -0
  17. data/lib/temporalio/api/enums/v1/event_type.rb +1 -1
  18. data/lib/temporalio/api/enums/v1/failed_cause.rb +1 -1
  19. data/lib/temporalio/api/enums/v1/task_queue.rb +2 -1
  20. data/lib/temporalio/api/enums/v1/workflow.rb +3 -1
  21. data/lib/temporalio/api/errordetails/v1/message.rb +2 -1
  22. data/lib/temporalio/api/history/v1/message.rb +3 -1
  23. data/lib/temporalio/api/namespace/v1/message.rb +2 -1
  24. data/lib/temporalio/api/nexus/v1/message.rb +1 -1
  25. data/lib/temporalio/api/operatorservice/v1/request_response.rb +1 -1
  26. data/lib/temporalio/api/payload_visitor.rb +70 -0
  27. data/lib/temporalio/api/taskqueue/v1/message.rb +1 -1
  28. data/lib/temporalio/api/worker/v1/message.rb +1 -1
  29. data/lib/temporalio/api/workflow/v1/message.rb +2 -1
  30. data/lib/temporalio/api/workflowservice/v1/request_response.rb +27 -1
  31. data/lib/temporalio/api/workflowservice/v1/service.rb +1 -1
  32. data/lib/temporalio/client/connection/cloud_service.rb +30 -0
  33. data/lib/temporalio/client/connection/workflow_service.rb +180 -0
  34. data/lib/temporalio/client/connection.rb +31 -12
  35. data/lib/temporalio/client/plugin.rb +42 -0
  36. data/lib/temporalio/client.rb +83 -14
  37. data/lib/temporalio/contrib/open_telemetry.rb +78 -25
  38. data/lib/temporalio/converters/payload_converter/binary_protobuf.rb +4 -1
  39. data/lib/temporalio/converters/payload_converter/composite.rb +1 -0
  40. data/lib/temporalio/converters/payload_converter/json_protobuf.rb +5 -2
  41. data/lib/temporalio/env_config.rb +3 -12
  42. data/lib/temporalio/internal/bridge/api/core_interface.rb +3 -1
  43. data/lib/temporalio/internal/bridge/api/nexus/nexus.rb +2 -1
  44. data/lib/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rb +1 -1
  45. data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +1 -1
  46. data/lib/temporalio/internal/bridge/runtime.rb +1 -0
  47. data/lib/temporalio/internal/bridge/worker.rb +5 -3
  48. data/lib/temporalio/internal/worker/workflow_instance/context.rb +4 -0
  49. data/lib/temporalio/internal/worker/workflow_instance/externally_immutable_hash.rb +1 -1
  50. data/lib/temporalio/internal/worker/workflow_instance/handler_hash.rb +1 -1
  51. data/lib/temporalio/internal/worker/workflow_instance/illegal_call_tracer.rb +8 -4
  52. data/lib/temporalio/internal/worker/workflow_instance/outbound_implementation.rb +32 -11
  53. data/lib/temporalio/internal/worker/workflow_instance/replay_safe_logger.rb +2 -1
  54. data/lib/temporalio/internal/worker/workflow_instance/replay_safe_metric.rb +2 -1
  55. data/lib/temporalio/internal/worker/workflow_instance/scheduler.rb +10 -1
  56. data/lib/temporalio/internal/worker/workflow_instance.rb +16 -11
  57. data/lib/temporalio/runtime.rb +16 -3
  58. data/lib/temporalio/simple_plugin.rb +192 -0
  59. data/lib/temporalio/version.rb +1 -1
  60. data/lib/temporalio/worker/plugin.rb +88 -0
  61. data/lib/temporalio/worker/tuner.rb +0 -4
  62. data/lib/temporalio/worker/workflow_replayer.rb +32 -8
  63. data/lib/temporalio/worker.rb +117 -44
  64. data/lib/temporalio/workflow/definition.rb +3 -1
  65. data/lib/temporalio/workflow/info.rb +4 -0
  66. data/lib/temporalio/workflow.rb +8 -1
  67. data/temporalio.gemspec +1 -1
  68. metadata +7 -3
@@ -7,6 +7,7 @@ require 'temporalio/internal/bridge/worker'
7
7
  require 'temporalio/internal/worker/multi_runner'
8
8
  require 'temporalio/internal/worker/workflow_worker'
9
9
  require 'temporalio/worker/interceptor'
10
+ require 'temporalio/worker/plugin'
10
11
  require 'temporalio/worker/poller_behavior'
11
12
  require 'temporalio/worker/thread_pool'
12
13
  require 'temporalio/worker/tuner'
@@ -24,6 +25,7 @@ module Temporalio
24
25
  :task_queue,
25
26
  :data_converter,
26
27
  :workflow_executor,
28
+ :plugins,
27
29
  :interceptors,
28
30
  :identity,
29
31
  :logger,
@@ -50,6 +52,8 @@ module Temporalio
50
52
  # payloads.
51
53
  # @param workflow_executor [WorkflowExecutor] Workflow executor that workflow tasks run within. This must be a
52
54
  # {WorkflowExecutor::ThreadPool} currently.
55
+ # @param plugins [Array<Plugin>] Plugins to use for configuring replayer and intercepting replay. WARNING: Plugins
56
+ # are experimental.
53
57
  # @param interceptors [Array<Interceptor::Workflow>] Workflow interceptors.
54
58
  # @param identity [String, nil] Override the identity for this replater.
55
59
  # @param logger [Logger] Logger to use. Defaults to stdout with warn level. Callers setting this logger are
@@ -83,6 +87,7 @@ module Temporalio
83
87
  task_queue: 'ReplayTaskQueue',
84
88
  data_converter: Converters::DataConverter.default,
85
89
  workflow_executor: WorkflowExecutor::ThreadPool.default,
90
+ plugins: [],
86
91
  interceptors: [],
87
92
  identity: nil,
88
93
  logger: Logger.new($stdout, level: Logger::WARN),
@@ -100,6 +105,7 @@ module Temporalio
100
105
  task_queue:,
101
106
  data_converter:,
102
107
  workflow_executor:,
108
+ plugins:,
103
109
  interceptors:,
104
110
  identity:,
105
111
  logger:,
@@ -110,13 +116,18 @@ module Temporalio
110
116
  debug_mode:,
111
117
  runtime:
112
118
  ).freeze
119
+ # Apply plugins
120
+ Worker._validate_plugins!(plugins)
121
+ @options = plugins.reduce(@options) { |options, plugin| plugin.configure_workflow_replayer(options) }
122
+
113
123
  # Preload definitions and other settings
114
124
  @workflow_definitions = Internal::Worker::WorkflowWorker.workflow_definitions(
115
- workflows, should_enforce_versioning_behavior: false
125
+ @options.workflows, should_enforce_versioning_behavior: false
116
126
  )
117
127
  @nondeterminism_as_workflow_fail, @nondeterminism_as_workflow_fail_for_types =
118
128
  Internal::Worker::WorkflowWorker.bridge_workflow_failure_exception_type_options(
119
- workflow_failure_exception_types:, workflow_definitions: @workflow_definitions
129
+ workflow_failure_exception_types: @options.workflow_failure_exception_types,
130
+ workflow_definitions: @workflow_definitions
120
131
  )
121
132
  # If there is a block, we'll go ahead and assume it's for with_replay_worker
122
133
  with_replay_worker(&) if block_given? # steep:ignore
@@ -154,7 +165,18 @@ module Temporalio
154
165
  # @yield Block of code to run with a replay worker.
155
166
  # @yieldparam [ReplayWorker] Worker to run replays on. Note, only one workflow can replay at a time.
156
167
  # @yieldreturn [Object] Result of the block.
157
- def with_replay_worker(&)
168
+ def with_replay_worker(&block)
169
+ # Apply plugins
170
+ run_block = proc do |options|
171
+ # @type var options: Plugin::WithWorkflowReplayWorkerOptions
172
+ block.call(options.worker)
173
+ end
174
+ run_block = options.plugins.reverse_each.reduce(run_block) do |next_call, plugin|
175
+ proc do |options|
176
+ plugin.with_workflow_replay_worker(options, next_call) # steep:ignore
177
+ end
178
+ end
179
+
158
180
  worker = ReplayWorker.new(
159
181
  options:,
160
182
  workflow_definitions: @workflow_definitions,
@@ -162,7 +184,7 @@ module Temporalio
162
184
  nondeterminism_as_workflow_fail_for_types: @nondeterminism_as_workflow_fail_for_types
163
185
  )
164
186
  begin
165
- yield worker
187
+ run_block.call(Plugin::WithWorkflowReplayWorkerOptions.new(worker:))
166
188
  ensure
167
189
  worker._shutdown
168
190
  end
@@ -197,8 +219,6 @@ module Temporalio
197
219
  @bridge_replayer, @bridge_worker = Internal::Bridge::Worker::WorkflowReplayer.new(
198
220
  options.runtime._core_runtime,
199
221
  Internal::Bridge::Worker::Options.new(
200
- activity: false,
201
- workflow: true,
202
222
  namespace: options.namespace,
203
223
  task_queue: options.task_queue,
204
224
  tuner: Tuner.create_fixed(
@@ -211,7 +231,10 @@ module Temporalio
211
231
  nonsticky_to_sticky_poll_ratio: 1.0,
212
232
  activity_task_poller_behavior:
213
233
  Temporalio::Worker::PollerBehavior::SimpleMaximum.new(1)._to_bridge_options,
214
- no_remote_activities: true,
234
+ enable_workflows: true,
235
+ enable_local_activities: false,
236
+ enable_remote_activities: false,
237
+ enable_nexus: false,
215
238
  sticky_queue_schedule_to_start_timeout: 1.0,
216
239
  max_heartbeat_throttle_interval: 1.0,
217
240
  default_heartbeat_throttle_interval: 1.0,
@@ -220,7 +243,8 @@ module Temporalio
220
243
  graceful_shutdown_period: 0.0,
221
244
  nondeterminism_as_workflow_fail:,
222
245
  nondeterminism_as_workflow_fail_for_types:,
223
- deployment_options: Worker.default_deployment_options._to_bridge_options
246
+ deployment_options: Worker.default_deployment_options._to_bridge_options,
247
+ plugins: options.plugins.map(&:name).uniq.sort
224
248
  )
225
249
  )
226
250
 
@@ -15,6 +15,7 @@ require 'temporalio/worker/activity_executor'
15
15
  require 'temporalio/worker/deployment_options'
16
16
  require 'temporalio/worker/illegal_workflow_call_validator'
17
17
  require 'temporalio/worker/interceptor'
18
+ require 'temporalio/worker/plugin'
18
19
  require 'temporalio/worker/poller_behavior'
19
20
  require 'temporalio/worker/thread_pool'
20
21
  require 'temporalio/worker/tuner'
@@ -35,6 +36,7 @@ module Temporalio
35
36
  :tuner,
36
37
  :activity_executors,
37
38
  :workflow_executor,
39
+ :plugins,
38
40
  :interceptors,
39
41
  :identity,
40
42
  :logger,
@@ -122,6 +124,42 @@ module Temporalio
122
124
  raise_in_block_on_shutdown: Error::CanceledError.new('Workers finished'),
123
125
  wait_block_complete: true,
124
126
  &block
127
+ )
128
+ # We have to apply plugins. However, every plugin has a different worker. So we provide them the worker along with
129
+ # other options, but we disregard any mutation of the worker on the next call.
130
+ run_worker = proc do |options|
131
+ # @type var options: Plugin::RunWorkerOptions
132
+ _run_all_root(*workers,
133
+ cancellation: options.cancellation,
134
+ shutdown_signals: options.shutdown_signals,
135
+ raise_in_block_on_shutdown: options.raise_in_block_on_shutdown,
136
+ wait_block_complete:, &block)
137
+ end
138
+ plugins_with_workers = workers.flat_map { |w| w._plugins.map { |p| [p, w] } }
139
+ run_worker = plugins_with_workers.reverse_each.reduce(run_worker) do |next_call, plugin_with_worker|
140
+ plugin, worker = plugin_with_worker
141
+ proc do |options|
142
+ plugin.run_worker(options.with(worker:), next_call) # steep:ignore
143
+ end
144
+ end
145
+
146
+ run_worker.call(Plugin::RunWorkerOptions.new(
147
+ # Intentionally violating typing here because we set this on each call
148
+ worker: nil, # steep:ignore
149
+ cancellation:,
150
+ shutdown_signals:,
151
+ raise_in_block_on_shutdown:
152
+ ))
153
+ end
154
+
155
+ # @!visibility private
156
+ def self._run_all_root(
157
+ *workers,
158
+ cancellation:,
159
+ shutdown_signals:,
160
+ raise_in_block_on_shutdown:,
161
+ wait_block_complete:,
162
+ &block
125
163
  )
126
164
  # Confirm there is at least one and they are all workers
127
165
  raise ArgumentError, 'At least one worker required' if workers.empty?
@@ -301,6 +339,19 @@ module Temporalio
301
339
  end
302
340
  end
303
341
 
342
+ # @!visibility private
343
+ def self._validate_plugins!(plugins)
344
+ plugins.each do |plugin|
345
+ raise ArgumentError, "#{plugin.class} does not implement Worker::Plugin" unless plugin.is_a?(Plugin)
346
+
347
+ # Validate plugin has implemented expected methods
348
+ missing = Plugin.instance_methods(false).select { |m| plugin.method(m).owner == Plugin }
349
+ unless missing.empty?
350
+ raise ArgumentError, "#{plugin.class} missing the following worker plugin method(s): #{missing.join(', ')}"
351
+ end
352
+ end
353
+ end
354
+
304
355
  # @return [Options] Options for this worker which has the same attributes as {initialize}.
305
356
  attr_reader :options
306
357
 
@@ -315,6 +366,9 @@ module Temporalio
315
366
  # @param activity_executors [Hash<Symbol, Worker::ActivityExecutor>] Executors that activities can run within.
316
367
  # @param workflow_executor [WorkflowExecutor] Workflow executor that workflow tasks run within. This must be a
317
368
  # {WorkflowExecutor::ThreadPool} currently.
369
+ # @param plugins [Array<Plugin>] Plugins to use for configuring workers and intercepting the running of workers. Any
370
+ # plugins that were set on the client that include {Plugin} will automatically be applied to the worker and
371
+ # should not be configured explicitly via this option. WARNING: Plugins are experimental.
318
372
  # @param interceptors [Array<Interceptor::Activity, Interceptor::Workflow>] Interceptors specific to this worker.
319
373
  # Note, interceptors set on the client that include the {Interceptor::Activity} or {Interceptor::Workflow} module
320
374
  # are automatically included here, so no need to specify them again.
@@ -387,6 +441,7 @@ module Temporalio
387
441
  tuner: Tuner.create_fixed,
388
442
  activity_executors: ActivityExecutor.defaults,
389
443
  workflow_executor: WorkflowExecutor::ThreadPool.default,
444
+ plugins: [],
390
445
  interceptors: [],
391
446
  identity: nil,
392
447
  logger: client.options.logger,
@@ -411,8 +466,6 @@ module Temporalio
411
466
  activity_task_poller_behavior: PollerBehavior::SimpleMaximum.new(max_concurrent_activity_task_polls),
412
467
  debug_mode: %w[true 1].include?(ENV['TEMPORAL_DEBUG'].to_s.downcase)
413
468
  )
414
- raise ArgumentError, 'Must have at least one activity or workflow' if activities.empty? && workflows.empty?
415
-
416
469
  Internal::ProtoUtils.assert_non_reserved_name(task_queue)
417
470
 
418
471
  @options = Options.new(
@@ -423,6 +476,7 @@ module Temporalio
423
476
  tuner:,
424
477
  activity_executors:,
425
478
  workflow_executor:,
479
+ plugins:,
426
480
  interceptors:,
427
481
  identity:,
428
482
  logger:,
@@ -447,54 +501,68 @@ module Temporalio
447
501
  activity_task_poller_behavior:,
448
502
  debug_mode:
449
503
  ).freeze
504
+ # Collect applicable client plugins and worker plugins, then validate and apply to options
505
+ @plugins = client.options.plugins.grep(Plugin) + plugins
506
+ Worker._validate_plugins!(@plugins)
507
+ @options = @plugins.reduce(@options) { |options, plugin| plugin.configure_worker(options) }
508
+ # Initialize the worker for the given options
509
+ _initialize_from_options
510
+ end
511
+
512
+ # @!visibility private
513
+ def _initialize_from_options
514
+ if @options.activities.empty? && @options.workflows.empty?
515
+ raise ArgumentError, 'Must have at least one activity or workflow'
516
+ end
450
517
 
451
518
  should_enforce_versioning_behavior =
452
- deployment_options.use_worker_versioning &&
453
- deployment_options.default_versioning_behavior == VersioningBehavior::UNSPECIFIED
519
+ @options.deployment_options.use_worker_versioning &&
520
+ @options.deployment_options.default_versioning_behavior == VersioningBehavior::UNSPECIFIED
454
521
  # Preload workflow definitions and some workflow settings for the bridge
455
522
  workflow_definitions = Internal::Worker::WorkflowWorker.workflow_definitions(
456
- workflows,
457
- should_enforce_versioning_behavior: should_enforce_versioning_behavior
523
+ @options.workflows,
524
+ should_enforce_versioning_behavior:
458
525
  )
459
526
  nondeterminism_as_workflow_fail, nondeterminism_as_workflow_fail_for_types =
460
527
  Internal::Worker::WorkflowWorker.bridge_workflow_failure_exception_type_options(
461
- workflow_failure_exception_types:, workflow_definitions:
528
+ workflow_failure_exception_types: @options.workflow_failure_exception_types,
529
+ workflow_definitions:
462
530
  )
463
531
 
464
532
  # Create the bridge worker
465
533
  @bridge_worker = Internal::Bridge::Worker.new(
466
- client.connection._core_client,
534
+ @options.client.connection._core_client,
467
535
  Internal::Bridge::Worker::Options.new(
468
- activity: !activities.empty?,
469
- workflow: !workflows.empty?,
470
- namespace: client.namespace,
471
- task_queue:,
472
- tuner: tuner._to_bridge_options,
473
- identity_override: identity,
474
- max_cached_workflows:,
475
- workflow_task_poller_behavior: workflow_task_poller_behavior._to_bridge_options,
476
- nonsticky_to_sticky_poll_ratio:,
477
- activity_task_poller_behavior: activity_task_poller_behavior._to_bridge_options,
478
- # For shutdown to work properly, we must disable remote activities
479
- # ourselves if there are no activities
480
- no_remote_activities: no_remote_activities || activities.empty?,
481
- sticky_queue_schedule_to_start_timeout:,
482
- max_heartbeat_throttle_interval:,
483
- default_heartbeat_throttle_interval:,
484
- max_worker_activities_per_second: max_activities_per_second,
485
- max_task_queue_activities_per_second:,
486
- graceful_shutdown_period:,
536
+ namespace: @options.client.namespace,
537
+ task_queue: @options.task_queue,
538
+ tuner: @options.tuner._to_bridge_options,
539
+ identity_override: @options.identity,
540
+ max_cached_workflows: @options.max_cached_workflows,
541
+ workflow_task_poller_behavior: @options.workflow_task_poller_behavior._to_bridge_options,
542
+ nonsticky_to_sticky_poll_ratio: @options.nonsticky_to_sticky_poll_ratio,
543
+ activity_task_poller_behavior: @options.activity_task_poller_behavior._to_bridge_options,
544
+ enable_workflows: !@options.workflows.empty?,
545
+ enable_local_activities: !@options.workflows.empty? && !@options.activities.empty?,
546
+ enable_remote_activities: !@options.activities.empty? && !@options.no_remote_activities,
547
+ enable_nexus: false,
548
+ sticky_queue_schedule_to_start_timeout: @options.sticky_queue_schedule_to_start_timeout,
549
+ max_heartbeat_throttle_interval: @options.max_heartbeat_throttle_interval,
550
+ default_heartbeat_throttle_interval: @options.default_heartbeat_throttle_interval,
551
+ max_worker_activities_per_second: @options.max_activities_per_second,
552
+ max_task_queue_activities_per_second: @options.max_task_queue_activities_per_second,
553
+ graceful_shutdown_period: @options.graceful_shutdown_period,
487
554
  nondeterminism_as_workflow_fail:,
488
555
  nondeterminism_as_workflow_fail_for_types:,
489
- deployment_options: deployment_options._to_bridge_options
556
+ deployment_options: @options.deployment_options._to_bridge_options,
557
+ plugins: (@options.client.options.plugins + @options.plugins).map(&:name).uniq.sort
490
558
  )
491
559
  )
492
560
 
493
561
  # Collect interceptors from client and params
494
- @activity_interceptors = (client.options.interceptors + interceptors).select do |i|
562
+ @activity_interceptors = (@options.client.options.interceptors + @options.interceptors).select do |i|
495
563
  i.is_a?(Interceptor::Activity)
496
564
  end
497
- @workflow_interceptors = (client.options.interceptors + interceptors).select do |i|
565
+ @workflow_interceptors = (@options.client.options.interceptors + @options.interceptors).select do |i|
498
566
  i.is_a?(Interceptor::Workflow)
499
567
  end
500
568
 
@@ -502,27 +570,27 @@ module Temporalio
502
570
  @worker_shutdown_cancellation = Cancellation.new
503
571
 
504
572
  # Create workers
505
- unless activities.empty?
573
+ unless @options.activities.empty?
506
574
  @activity_worker = Internal::Worker::ActivityWorker.new(worker: self,
507
575
  bridge_worker: @bridge_worker)
508
576
  end
509
- unless workflows.empty?
577
+ unless @options.workflows.empty?
510
578
  @workflow_worker = Internal::Worker::WorkflowWorker.new(
511
579
  bridge_worker: @bridge_worker,
512
- namespace: client.namespace,
513
- task_queue:,
580
+ namespace: @options.client.namespace,
581
+ task_queue: @options.task_queue,
514
582
  workflow_definitions:,
515
- workflow_executor:,
516
- logger:,
517
- data_converter: client.data_converter,
518
- metric_meter: client.connection.options.runtime.metric_meter,
583
+ workflow_executor: @options.workflow_executor,
584
+ logger: @options.logger,
585
+ data_converter: @options.client.data_converter,
586
+ metric_meter: @options.client.connection.options.runtime.metric_meter,
519
587
  workflow_interceptors: @workflow_interceptors,
520
- disable_eager_activity_execution:,
521
- illegal_workflow_calls:,
522
- workflow_failure_exception_types:,
523
- workflow_payload_codec_thread_pool:,
524
- unsafe_workflow_io_enabled:,
525
- debug_mode:,
588
+ disable_eager_activity_execution: @options.disable_eager_activity_execution,
589
+ illegal_workflow_calls: @options.illegal_workflow_calls,
590
+ workflow_failure_exception_types: @options.workflow_failure_exception_types,
591
+ workflow_payload_codec_thread_pool: @options.workflow_payload_codec_thread_pool,
592
+ unsafe_workflow_io_enabled: @options.unsafe_workflow_io_enabled,
593
+ debug_mode: @options.debug_mode,
526
594
  assert_valid_local_activity: ->(activity) { _assert_valid_local_activity(activity) }
527
595
  )
528
596
  end
@@ -644,5 +712,10 @@ module Temporalio
644
712
  "Activity #{activity} " \
645
713
  'is not registered on this worker, no available activities.'
646
714
  end
715
+
716
+ # @!visibility private
717
+ def _plugins
718
+ @plugins
719
+ end
647
720
  end
648
721
  end
@@ -102,7 +102,9 @@ module Temporalio
102
102
 
103
103
  # Just run this as if done manually
104
104
  workflow_query(description:)
105
- define_method(attr_name) { instance_variable_get("@#{attr_name}") }
105
+ define_method(attr_name) do
106
+ instance_variable_get("@#{attr_name}") # steep:ignore NoMethod
107
+ end
106
108
  end
107
109
  end
108
110
 
@@ -11,6 +11,7 @@ module Temporalio
11
11
  :headers,
12
12
  :last_failure,
13
13
  :last_result,
14
+ :has_last_result?,
14
15
  :namespace,
15
16
  :parent,
16
17
  :priority,
@@ -44,6 +45,9 @@ module Temporalio
44
45
  # @return [Exception, nil] Failure if this workflow run is a continuation of a failure.
45
46
  # @!attribute last_result
46
47
  # @return [Object, nil] Successful result if this workflow is a continuation of a success.
48
+ # @!attribute has_last_result?
49
+ # @return [Boolean] Successful result if this workflow is a continuation of a success.
50
+
47
51
  # @!attribute namespace
48
52
  # @return [String] Namespace for the workflow.
49
53
  # @!attribute parent
@@ -533,11 +533,18 @@ module Temporalio
533
533
  # Unsafe module contains only-in-workflow methods that are considered unsafe. These should not be used unless the
534
534
  # consequences are understood.
535
535
  module Unsafe
536
- # @return [Boolean] True if the workflow is replaying, false otherwise. Most code should not check this value.
536
+ # @return [Boolean] True if the workflow is replaying (including during queries and update validators), false
537
+ # otherwise. Most code should not check this value.
537
538
  def self.replaying?
538
539
  Workflow._current.replaying?
539
540
  end
540
541
 
542
+ # @return [Boolean] True if the workflow is replaying history events (excluding queries and update validators),
543
+ # false otherwise. Most code should not check this value.
544
+ def self.replaying_history_events?
545
+ Workflow._current.replaying_history_events?
546
+ end
547
+
541
548
  # Run a block of code with illegal call tracing disabled. Users should be cautious about using this as it can
542
549
  # often signify unsafe code.
543
550
  #
data/temporalio.gemspec CHANGED
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
23
23
  spec.require_paths = ['lib']
24
24
  spec.extensions = ['ext/Cargo.toml']
25
25
  spec.metadata['rubygems_mfa_required'] = 'true'
26
- spec.required_ruby_version = '>= 3.2.0'
26
+ spec.required_ruby_version = '>= 3.3.0'
27
27
 
28
28
  spec.add_dependency 'google-protobuf', '>= 3.25.0'
29
29
  spec.add_dependency 'logger'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: temporalio
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Temporal Technologies Inc
@@ -79,6 +79,7 @@ files:
79
79
  - lib/temporalio/api/common/v1/grpc_status.rb
80
80
  - lib/temporalio/api/common/v1/message.rb
81
81
  - lib/temporalio/api/deployment/v1/message.rb
82
+ - lib/temporalio/api/enums/v1/activity.rb
82
83
  - lib/temporalio/api/enums/v1/batch_operation.rb
83
84
  - lib/temporalio/api/enums/v1/command_type.rb
84
85
  - lib/temporalio/api/enums/v1/common.rb
@@ -135,6 +136,7 @@ files:
135
136
  - lib/temporalio/client/connection/test_service.rb
136
137
  - lib/temporalio/client/connection/workflow_service.rb
137
138
  - lib/temporalio/client/interceptor.rb
139
+ - lib/temporalio/client/plugin.rb
138
140
  - lib/temporalio/client/schedule.rb
139
141
  - lib/temporalio/client/schedule_handle.rb
140
142
  - lib/temporalio/client/with_start_workflow_operation.rb
@@ -207,6 +209,7 @@ files:
207
209
  - lib/temporalio/runtime/metric_buffer.rb
208
210
  - lib/temporalio/scoped_logger.rb
209
211
  - lib/temporalio/search_attributes.rb
212
+ - lib/temporalio/simple_plugin.rb
210
213
  - lib/temporalio/testing.rb
211
214
  - lib/temporalio/testing/activity_environment.rb
212
215
  - lib/temporalio/testing/workflow_environment.rb
@@ -219,6 +222,7 @@ files:
219
222
  - lib/temporalio/worker/deployment_options.rb
220
223
  - lib/temporalio/worker/illegal_workflow_call_validator.rb
221
224
  - lib/temporalio/worker/interceptor.rb
225
+ - lib/temporalio/worker/plugin.rb
222
226
  - lib/temporalio/worker/poller_behavior.rb
223
227
  - lib/temporalio/worker/thread_pool.rb
224
228
  - lib/temporalio/worker/tuner.rb
@@ -253,14 +257,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
253
257
  requirements:
254
258
  - - ">="
255
259
  - !ruby/object:Gem::Version
256
- version: 3.2.0
260
+ version: 3.3.0
257
261
  required_rubygems_version: !ruby/object:Gem::Requirement
258
262
  requirements:
259
263
  - - ">="
260
264
  - !ruby/object:Gem::Version
261
265
  version: '0'
262
266
  requirements: []
263
- rubygems_version: 3.6.9
267
+ rubygems_version: 4.0.3
264
268
  specification_version: 4
265
269
  summary: Temporal.io Ruby SDK
266
270
  test_files: []