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.
- checksums.yaml +4 -4
- data/Gemfile +6 -4
- data/lib/temporalio/activity/definition.rb +6 -1
- data/lib/temporalio/api/activity/v1/message.rb +11 -2
- data/lib/temporalio/api/command/v1/message.rb +1 -1
- data/lib/temporalio/api/common/v1/message.rb +2 -1
- data/lib/temporalio/api/deployment/v1/message.rb +2 -1
- data/lib/temporalio/api/enums/v1/activity.rb +23 -0
- data/lib/temporalio/api/enums/v1/event_type.rb +1 -1
- data/lib/temporalio/api/enums/v1/failed_cause.rb +1 -1
- data/lib/temporalio/api/enums/v1/task_queue.rb +2 -1
- data/lib/temporalio/api/enums/v1/workflow.rb +3 -1
- data/lib/temporalio/api/errordetails/v1/message.rb +2 -1
- data/lib/temporalio/api/history/v1/message.rb +3 -1
- data/lib/temporalio/api/namespace/v1/message.rb +2 -1
- data/lib/temporalio/api/nexus/v1/message.rb +1 -1
- data/lib/temporalio/api/operatorservice/v1/request_response.rb +1 -1
- data/lib/temporalio/api/payload_visitor.rb +64 -0
- data/lib/temporalio/api/taskqueue/v1/message.rb +1 -1
- data/lib/temporalio/api/worker/v1/message.rb +1 -1
- data/lib/temporalio/api/workflow/v1/message.rb +2 -1
- data/lib/temporalio/api/workflowservice/v1/request_response.rb +23 -1
- data/lib/temporalio/api/workflowservice/v1/service.rb +1 -1
- data/lib/temporalio/client/connection/workflow_service.rb +150 -0
- data/lib/temporalio/client/connection.rb +17 -3
- data/lib/temporalio/client/plugin.rb +42 -0
- data/lib/temporalio/client.rb +82 -15
- data/lib/temporalio/common_enums.rb +0 -2
- data/lib/temporalio/contrib/open_telemetry.rb +21 -0
- data/lib/temporalio/converters/failure_converter.rb +30 -0
- data/lib/temporalio/converters/payload_converter/binary_protobuf.rb +4 -1
- data/lib/temporalio/converters/payload_converter/json_protobuf.rb +4 -1
- data/lib/temporalio/env_config.rb +3 -14
- data/lib/temporalio/error/failure.rb +66 -0
- data/lib/temporalio/internal/bridge/3.3/temporalio_bridge.so +0 -0
- data/lib/temporalio/internal/bridge/3.4/temporalio_bridge.so +0 -0
- data/lib/temporalio/internal/bridge/{3.2 → 4.0}/temporalio_bridge.so +0 -0
- data/lib/temporalio/internal/bridge/api/core_interface.rb +3 -1
- data/lib/temporalio/internal/bridge/api/nexus/nexus.rb +2 -1
- data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +1 -1
- data/lib/temporalio/internal/bridge/worker.rb +1 -0
- data/lib/temporalio/internal/worker/workflow_instance/context.rb +9 -0
- data/lib/temporalio/internal/worker/workflow_instance/externally_immutable_hash.rb +1 -1
- data/lib/temporalio/internal/worker/workflow_instance/handler_hash.rb +1 -1
- data/lib/temporalio/internal/worker/workflow_instance/illegal_call_tracer.rb +8 -4
- data/lib/temporalio/internal/worker/workflow_instance/nexus_client.rb +42 -0
- data/lib/temporalio/internal/worker/workflow_instance/nexus_operation_handle.rb +51 -0
- data/lib/temporalio/internal/worker/workflow_instance/outbound_implementation.rb +100 -11
- data/lib/temporalio/internal/worker/workflow_instance/replay_safe_logger.rb +2 -1
- data/lib/temporalio/internal/worker/workflow_instance/replay_safe_metric.rb +2 -1
- data/lib/temporalio/internal/worker/workflow_instance/scheduler.rb +10 -1
- data/lib/temporalio/internal/worker/workflow_instance.rb +26 -11
- data/lib/temporalio/simple_plugin.rb +192 -0
- data/lib/temporalio/testing/workflow_environment.rb +40 -0
- data/lib/temporalio/version.rb +1 -1
- data/lib/temporalio/versioning_override.rb +0 -2
- data/lib/temporalio/worker/deployment_options.rb +0 -2
- data/lib/temporalio/worker/interceptor.rb +27 -0
- data/lib/temporalio/worker/plugin.rb +88 -0
- data/lib/temporalio/worker/workflow_executor/thread_pool.rb +1 -1
- data/lib/temporalio/worker/workflow_replayer.rb +28 -5
- data/lib/temporalio/worker.rb +116 -43
- data/lib/temporalio/worker_deployment_version.rb +0 -2
- data/lib/temporalio/workflow/definition.rb +3 -4
- data/lib/temporalio/workflow/nexus_client.rb +81 -0
- data/lib/temporalio/workflow/nexus_operation_cancellation_type.rb +21 -0
- data/lib/temporalio/workflow/nexus_operation_handle.rb +37 -0
- data/lib/temporalio/workflow.rb +22 -1
- data/temporalio.gemspec +1 -1
- 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
|
#
|
data/lib/temporalio/version.rb
CHANGED
|
@@ -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 <<
|
|
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
|
|
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
|
-
|
|
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
|
|