temporalio 1.1.0-aarch64-linux → 1.3.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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +6 -4
  3. data/lib/temporalio/activity/definition.rb +6 -1
  4. data/lib/temporalio/api/activity/v1/message.rb +11 -2
  5. data/lib/temporalio/api/command/v1/message.rb +1 -1
  6. data/lib/temporalio/api/common/v1/message.rb +2 -1
  7. data/lib/temporalio/api/deployment/v1/message.rb +2 -1
  8. data/lib/temporalio/api/enums/v1/activity.rb +23 -0
  9. data/lib/temporalio/api/enums/v1/event_type.rb +1 -1
  10. data/lib/temporalio/api/enums/v1/failed_cause.rb +1 -1
  11. data/lib/temporalio/api/enums/v1/task_queue.rb +2 -1
  12. data/lib/temporalio/api/enums/v1/workflow.rb +3 -1
  13. data/lib/temporalio/api/errordetails/v1/message.rb +2 -1
  14. data/lib/temporalio/api/history/v1/message.rb +3 -1
  15. data/lib/temporalio/api/namespace/v1/message.rb +2 -1
  16. data/lib/temporalio/api/nexus/v1/message.rb +1 -1
  17. data/lib/temporalio/api/operatorservice/v1/request_response.rb +1 -1
  18. data/lib/temporalio/api/payload_visitor.rb +64 -0
  19. data/lib/temporalio/api/taskqueue/v1/message.rb +1 -1
  20. data/lib/temporalio/api/worker/v1/message.rb +1 -1
  21. data/lib/temporalio/api/workflow/v1/message.rb +2 -1
  22. data/lib/temporalio/api/workflowservice/v1/request_response.rb +23 -1
  23. data/lib/temporalio/api/workflowservice/v1/service.rb +1 -1
  24. data/lib/temporalio/client/connection/workflow_service.rb +150 -0
  25. data/lib/temporalio/client/connection.rb +17 -3
  26. data/lib/temporalio/client/plugin.rb +42 -0
  27. data/lib/temporalio/client.rb +82 -15
  28. data/lib/temporalio/common_enums.rb +0 -2
  29. data/lib/temporalio/contrib/open_telemetry.rb +21 -0
  30. data/lib/temporalio/converters/failure_converter.rb +30 -0
  31. data/lib/temporalio/converters/payload_converter/binary_protobuf.rb +4 -1
  32. data/lib/temporalio/converters/payload_converter/json_protobuf.rb +4 -1
  33. data/lib/temporalio/env_config.rb +3 -14
  34. data/lib/temporalio/error/failure.rb +66 -0
  35. data/lib/temporalio/internal/bridge/3.3/temporalio_bridge.so +0 -0
  36. data/lib/temporalio/internal/bridge/3.4/temporalio_bridge.so +0 -0
  37. data/lib/temporalio/internal/bridge/{3.2 → 4.0}/temporalio_bridge.so +0 -0
  38. data/lib/temporalio/internal/bridge/api/core_interface.rb +3 -1
  39. data/lib/temporalio/internal/bridge/api/nexus/nexus.rb +2 -1
  40. data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +1 -1
  41. data/lib/temporalio/internal/bridge/worker.rb +1 -0
  42. data/lib/temporalio/internal/worker/workflow_instance/context.rb +9 -0
  43. data/lib/temporalio/internal/worker/workflow_instance/externally_immutable_hash.rb +1 -1
  44. data/lib/temporalio/internal/worker/workflow_instance/handler_hash.rb +1 -1
  45. data/lib/temporalio/internal/worker/workflow_instance/illegal_call_tracer.rb +8 -4
  46. data/lib/temporalio/internal/worker/workflow_instance/nexus_client.rb +42 -0
  47. data/lib/temporalio/internal/worker/workflow_instance/nexus_operation_handle.rb +51 -0
  48. data/lib/temporalio/internal/worker/workflow_instance/outbound_implementation.rb +100 -11
  49. data/lib/temporalio/internal/worker/workflow_instance/replay_safe_logger.rb +2 -1
  50. data/lib/temporalio/internal/worker/workflow_instance/replay_safe_metric.rb +2 -1
  51. data/lib/temporalio/internal/worker/workflow_instance/scheduler.rb +10 -1
  52. data/lib/temporalio/internal/worker/workflow_instance.rb +26 -11
  53. data/lib/temporalio/simple_plugin.rb +192 -0
  54. data/lib/temporalio/testing/workflow_environment.rb +40 -0
  55. data/lib/temporalio/version.rb +1 -1
  56. data/lib/temporalio/versioning_override.rb +0 -2
  57. data/lib/temporalio/worker/deployment_options.rb +0 -2
  58. data/lib/temporalio/worker/interceptor.rb +27 -0
  59. data/lib/temporalio/worker/plugin.rb +88 -0
  60. data/lib/temporalio/worker/workflow_executor/thread_pool.rb +1 -1
  61. data/lib/temporalio/worker/workflow_replayer.rb +28 -5
  62. data/lib/temporalio/worker.rb +116 -43
  63. data/lib/temporalio/worker_deployment_version.rb +0 -2
  64. data/lib/temporalio/workflow/definition.rb +3 -4
  65. data/lib/temporalio/workflow/nexus_client.rb +81 -0
  66. data/lib/temporalio/workflow/nexus_operation_cancellation_type.rb +21 -0
  67. data/lib/temporalio/workflow/nexus_operation_handle.rb +37 -0
  68. data/lib/temporalio/workflow.rb +22 -1
  69. data/temporalio.gemspec +1 -1
  70. metadata +14 -5
@@ -0,0 +1,192 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'temporalio/client'
4
+ require 'temporalio/worker'
5
+
6
+ module Temporalio
7
+ # Plugin that implements both {Client::Plugin} and {Worker::Plugin} and provides a simplified common set of settings
8
+ # for configuring both.
9
+ #
10
+ # WARNING: Plugins are experimental.
11
+ class SimplePlugin
12
+ include Client::Plugin
13
+ include Worker::Plugin
14
+
15
+ Options = Data.define(
16
+ :name,
17
+ :data_converter,
18
+ :client_interceptors,
19
+ :activities,
20
+ :workflows,
21
+ :worker_interceptors,
22
+ :workflow_failure_exception_types,
23
+ :run_context
24
+ )
25
+
26
+ # Options as returned from {options} representing the options passed to the constructor.
27
+ class Options; end # rubocop:disable Lint/EmptyClass
28
+
29
+ # @return [Options] Frozen options for this plugin which has the same attributes as {initialize}.
30
+ attr_reader :options
31
+
32
+ # Create a simple plugin.
33
+ #
34
+ # @param name [String] Required string name for this plugin.
35
+ # @param data_converter [Converters::DataConverter, Proc, nil] Data converter to apply to clients and workflow
36
+ # replayers. This can be a proc that accepts the existing data converter and returns a new one.
37
+ # @param client_interceptors [Array<Client::Integerceptor>, Proc, nil] Client interceptors that are appended to the
38
+ # existing client set (which means if they implement worker interceptors they are applied for the workers too). A
39
+ # proc can be provided that accepts the existing array and returns a new one.
40
+ # @param activities [Array<Activity::Definition, Class<Activity::Definition>, Activity::Definition::Info>, Proc,
41
+ # nil] Activities to append to each worker activity set. A proc can be provided that accepts the existing array
42
+ # and returns a new one.
43
+ # @param workflows [Array<Class<Workflow::Definition>>, Proc, nil] Workflows to append to each worker workflow set.
44
+ # A proc can be provided that accepts the existing array and returns a new one.
45
+ # @param worker_interceptors [Array<Interceptor::Activity, Interceptor::Workflow>, Proc, nil] Worker interceptors
46
+ # that are appended to the existing worker or workflow replayer set. A proc can be provided that accepts the
47
+ # existing array and returns a new one.
48
+ # @param workflow_failure_exception_types [Array<Class<Exception>>] Workflow failure exception types that are
49
+ # appended to the existing worker or workflow replayer set. A proc can be provided that accepts the existing array
50
+ # and returns a new one.
51
+ # @param run_context [Proc, nil] A proc that intercepts both {run_worker} or {with_workflow_replay_worker}. The proc
52
+ # should accept two positional parameters: options and next_call. The options are either
53
+ # {Worker::Plugin::RunWorkerOptions} or {Worker::Plugin::WithWorkflowReplayWorkerOptions}. The next_call is a proc
54
+ # itself that accepts the options and returns a value. This run_context proc should return the result of the
55
+ # next_call.
56
+ def initialize(
57
+ name:,
58
+ data_converter: nil,
59
+ client_interceptors: nil,
60
+ activities: nil,
61
+ workflows: nil,
62
+ worker_interceptors: nil,
63
+ workflow_failure_exception_types: nil,
64
+ run_context: nil
65
+ )
66
+ @options = Options.new(
67
+ name:,
68
+ data_converter:,
69
+ client_interceptors:,
70
+ activities:,
71
+ workflows:,
72
+ worker_interceptors:,
73
+ workflow_failure_exception_types:,
74
+ run_context:
75
+ ).freeze
76
+ end
77
+
78
+ # Implements {Client::Plugin#name} and {Worker::Plugin#name}.
79
+ def name
80
+ @options.name
81
+ end
82
+
83
+ # Implements {Client::Plugin#configure_client}.
84
+ def configure_client(options)
85
+ if (data_converter = _single_option(new: @options.data_converter, existing: options.data_converter,
86
+ type: Converters::DataConverter, name: 'data converter'))
87
+ options = options.with(data_converter:)
88
+ end
89
+ if (interceptors = _array_option(new: @options.client_interceptors, existing: options.interceptors,
90
+ name: 'client interceptor'))
91
+ options = options.with(interceptors:)
92
+ end
93
+ options
94
+ end
95
+
96
+ # Implements {Client::Plugin#connect_client}.
97
+ def connect_client(options, next_call)
98
+ next_call.call(options)
99
+ end
100
+
101
+ # Implements {Worker::Plugin#configure_worker}.
102
+ def configure_worker(options)
103
+ if (activities = _array_option(new: @options.activities, existing: options.activities, name: 'activity'))
104
+ options = options.with(activities:)
105
+ end
106
+ if (workflows = _array_option(new: @options.workflows, existing: options.workflows, name: 'workflow'))
107
+ options = options.with(workflows:)
108
+ end
109
+ if (interceptors = _array_option(new: @options.worker_interceptors, existing: options.interceptors,
110
+ name: 'worker interceptor'))
111
+ options = options.with(interceptors:)
112
+ end
113
+ if (workflow_failure_exception_types = _array_option(new: @options.workflow_failure_exception_types,
114
+ existing: options.workflow_failure_exception_types,
115
+ name: 'workflow failure exception types'))
116
+ options = options.with(workflow_failure_exception_types:)
117
+ end
118
+ options
119
+ end
120
+
121
+ # Implements {Worker::Plugin#run_worker}.
122
+ def run_worker(options, next_call)
123
+ if @options.run_context
124
+ @options.run_context.call(options, next_call) # steep:ignore NoMethod
125
+ else
126
+ next_call.call(options)
127
+ end
128
+ end
129
+
130
+ # Implements {Worker::Plugin#configure_workflow_replayer}.
131
+ def configure_workflow_replayer(options)
132
+ if (data_converter = _single_option(new: @options.data_converter, existing: options.data_converter,
133
+ type: Converters::DataConverter, name: 'data converter'))
134
+ options = options.with(data_converter:)
135
+ end
136
+ if (workflows = _array_option(new: @options.workflows, existing: options.workflows, name: 'workflow'))
137
+ options = options.with(workflows:)
138
+ end
139
+ if (interceptors = _array_option(new: @options.worker_interceptors, existing: options.interceptors,
140
+ name: 'worker interceptor'))
141
+ options = options.with(interceptors:)
142
+ end
143
+ if (workflow_failure_exception_types = _array_option(new: @options.workflow_failure_exception_types,
144
+ existing: options.workflow_failure_exception_types,
145
+ name: 'workflow failure exception types'))
146
+ options = options.with(workflow_failure_exception_types:)
147
+ end
148
+ options
149
+ end
150
+
151
+ # Implements {Worker::Plugin#with_workflow_replay_worker}.
152
+ def with_workflow_replay_worker(options, next_call)
153
+ if @options.run_context
154
+ @options.run_context.call(options, next_call) # steep:ignore NoMethod
155
+ else
156
+ next_call.call(options)
157
+ end
158
+ end
159
+
160
+ # @!visibility private
161
+ def _single_option(new:, existing:, type:, name:)
162
+ case new
163
+ when nil
164
+ nil
165
+ when Proc
166
+ new.call(existing).tap do |val| # steep:ignore NoMethod
167
+ raise "Instance of #{name} required" unless val.is_a?(type)
168
+ end
169
+ when type
170
+ new
171
+ else
172
+ raise "Unrecognized #{name} type #{new.class}"
173
+ end
174
+ end
175
+
176
+ # @!visibility private
177
+ def _array_option(new:, existing:, name:)
178
+ case new
179
+ when nil
180
+ nil
181
+ when Proc
182
+ new.call(existing).tap do |conv| # steep:ignore NoMethod
183
+ raise "Array for #{name} required" unless conv.is_a?(Array)
184
+ end
185
+ when Array
186
+ existing + new # steep:ignore NoMethod
187
+ else
188
+ raise "Unrecognized #{name} type #{new.class}"
189
+ end
190
+ end
191
+ end
192
+ end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'delegate'
4
4
  require 'temporalio/api'
5
+ require 'temporalio/api/operatorservice/v1/request_response'
5
6
  require 'temporalio/api/testservice/v1/request_response'
6
7
  require 'temporalio/client'
7
8
  require 'temporalio/client/connection/test_service'
@@ -264,6 +265,45 @@ module Temporalio
264
265
  Time.now
265
266
  end
266
267
 
268
+ # Create Nexus endpoint on this test environment.
269
+ #
270
+ # WARNING: Nexus support is experimental.
271
+ #
272
+ # @param name [String] Endpoint name.
273
+ # @param task_queue [String] Task queue for the endpoint.
274
+ # @return [Temporalio::Api::Nexus::V1::Endpoint] Created endpoint.
275
+ def create_nexus_endpoint(name:, task_queue:)
276
+ resp = client.connection.operator_service.create_nexus_endpoint(
277
+ Temporalio::Api::OperatorService::V1::CreateNexusEndpointRequest.new(
278
+ spec: Temporalio::Api::Nexus::V1::EndpointSpec.new(
279
+ name:,
280
+ target: Temporalio::Api::Nexus::V1::EndpointTarget.new(
281
+ worker: Temporalio::Api::Nexus::V1::EndpointTarget::Worker.new(
282
+ namespace: client.namespace,
283
+ task_queue:
284
+ )
285
+ )
286
+ )
287
+ )
288
+ )
289
+ resp.endpoint
290
+ end
291
+
292
+ # Delete Nexus endpoint on this test environment.
293
+ #
294
+ # WARNING: Nexus support is experimental.
295
+ #
296
+ # @param endpoint [Temporalio::Api::Nexus::V1::Endpoint] Endpoint to delete.
297
+ def delete_nexus_endpoint(endpoint)
298
+ client.connection.operator_service.delete_nexus_endpoint(
299
+ Temporalio::Api::OperatorService::V1::DeleteNexusEndpointRequest.new(
300
+ id: endpoint.id,
301
+ version: endpoint.version
302
+ )
303
+ )
304
+ nil
305
+ end
306
+
267
307
  # Run a block with automatic time skipping disabled. This just runs the block for environments that don't support
268
308
  # time skipping.
269
309
  #
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Temporalio
4
- VERSION = '1.1.0'
4
+ VERSION = '1.3.0'
5
5
  end
@@ -5,8 +5,6 @@ require 'temporalio/worker_deployment_version'
5
5
  module Temporalio
6
6
  # Base class for version overrides that can be provided in start workflow options.
7
7
  # Used to control the versioning behavior of workflows started with this override.
8
- #
9
- # WARNING: Experimental API.
10
8
  class VersioningOverride
11
9
  # @!visibility private
12
10
  def _to_proto
@@ -13,8 +13,6 @@ module Temporalio
13
13
 
14
14
  # Options for configuring the Worker Versioning feature.
15
15
  #
16
- # WARNING: Deployment-based versioning is experimental and APIs may change.
17
- #
18
16
  # @!attribute version
19
17
  # @return [WorkerDeploymentVersion] The worker deployment version.
20
18
  # @!attribute use_worker_versioning
@@ -300,6 +300,23 @@ module Temporalio
300
300
  :headers
301
301
  )
302
302
 
303
+ # Input for {Outbound.start_nexus_operation}.
304
+ #
305
+ # WARNING: Nexus support is experimental.
306
+ StartNexusOperationInput = Data.define(
307
+ :endpoint,
308
+ :service,
309
+ :operation,
310
+ :arg,
311
+ :schedule_to_close_timeout,
312
+ :cancellation_type,
313
+ :summary,
314
+ :cancellation,
315
+ :arg_hint,
316
+ :result_hint,
317
+ :headers
318
+ )
319
+
303
320
  # Outbound interceptor for intercepting outbound workflow calls. This should be extended by users needing to
304
321
  # intercept workflow calls.
305
322
  class Outbound
@@ -371,6 +388,16 @@ module Temporalio
371
388
  def start_child_workflow(input)
372
389
  @next_interceptor.start_child_workflow(input)
373
390
  end
391
+
392
+ # Start Nexus operation.
393
+ #
394
+ # WARNING: Nexus support is experimental.
395
+ #
396
+ # @param input [StartNexusOperationInput] Input.
397
+ # @return [Workflow::NexusOperationHandle] Nexus operation handle.
398
+ def start_nexus_operation(input)
399
+ @next_interceptor.start_nexus_operation(input)
400
+ end
374
401
  end
375
402
  end
376
403
  end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Temporalio
4
+ class Worker
5
+ # Plugin mixin to include for configuring workers and workflow replayers, and intercepting the running of them.
6
+ #
7
+ # This is a low-level implementation that requires abstract methods herein to be implemented. Many implementers may
8
+ # prefer {SimplePlugin} which includes this.
9
+ #
10
+ # WARNING: Plugins are experimental.
11
+ module Plugin
12
+ RunWorkerOptions = Data.define(
13
+ :worker,
14
+ :cancellation,
15
+ :shutdown_signals,
16
+ :raise_in_block_on_shutdown
17
+ )
18
+
19
+ # Options for {run_worker}.
20
+ #
21
+ # The options contain the worker and some other options from {Worker#run}/{Worker.run_all}. Unlike other memebers
22
+ # in this class, mutating the worker member before invoking the next call in the chain has no effect.
23
+ #
24
+ # @note Additional required attributes of this class may be added in the future. Users should never instantiate
25
+ # this class, but instead use `with` on it in {run_worker}.
26
+ class RunWorkerOptions; end # rubocop:disable Lint/EmptyClass
27
+
28
+ WithWorkflowReplayWorkerOptions = Data.define(
29
+ :worker
30
+ )
31
+
32
+ # Options for {with_workflow_replay_worker}.
33
+ #
34
+ # @note Additional required attributes of this class may be added in the future. Users should never instantiate
35
+ # this class, but instead use `with` on it in {with_workflow_replay_worker}.
36
+ #
37
+ # @!attribute worker
38
+ # @return [WorkflowReplayer::ReplayWorker] Replay worker.
39
+ class WithWorkflowReplayWorkerOptions; end # rubocop:disable Lint/EmptyClass
40
+
41
+ # @abstract
42
+ # @return [String] Name of the plugin.
43
+ def name
44
+ raise NotImplementedError
45
+ end
46
+
47
+ # Configure a worker.
48
+ #
49
+ # @abstract
50
+ # @param options [Options] Current immutable options set.
51
+ # @return [Options] Options to use, possibly updated from original.
52
+ def configure_worker(options)
53
+ raise NotImplementedError
54
+ end
55
+
56
+ # Run a worker.
57
+ #
58
+ # @abstract
59
+ # @param options [RunWorkerOptions] Current immutable options set.
60
+ # @param next_call [Proc] Proc for the next plugin in the chain to call. It accepts the options and returns an
61
+ # arbitrary object that should also be returned from this method.
62
+ # @return [Object] Result of next_call.
63
+ def run_worker(options, next_call)
64
+ raise NotImplementedError
65
+ end
66
+
67
+ # Configure a workflow replayer.
68
+ #
69
+ # @abstract
70
+ # @param options [WorkflowReplayer::Options] Current immutable options set.
71
+ # @return [WorkflowReplayer::Options] Options to use, possibly updated from original.
72
+ def configure_workflow_replayer(options)
73
+ raise NotImplementedError
74
+ end
75
+
76
+ # Run a replay worker.
77
+ #
78
+ # @abstract
79
+ # @param options [WithWorkflowReplayWorkerOptions] Current immutable options set.
80
+ # @param next_call [Proc] Proc for the next plugin in the chain to call. It accepts the options and returns an
81
+ # arbitrary object that should also be returned from this method.
82
+ # @return [Object] Result of next_call.
83
+ def with_workflow_replay_worker(options, next_call)
84
+ raise NotImplementedError
85
+ end
86
+ end
87
+ end
88
+ end
@@ -49,7 +49,7 @@ module Temporalio
49
49
  # If not found, get a new one either by creating if not enough or find the one with the fewest.
50
50
  new_worker = if @workers.size < @max_threads
51
51
  created_worker = Worker.new(self)
52
- @workers << Worker.new(self)
52
+ @workers << created_worker
53
53
  created_worker
54
54
  else
55
55
  @workers.min_by(&:workflow_count)
@@ -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
@@ -221,7 +243,8 @@ module Temporalio
221
243
  graceful_shutdown_period: 0.0,
222
244
  nondeterminism_as_workflow_fail:,
223
245
  nondeterminism_as_workflow_fail_for_types:,
224
- 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
225
248
  )
226
249
  )
227
250