temporalio 1.10.0 → 1.11.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.
- checksums.yaml +4 -4
- data/Cargo.lock +763 -768
- data/Gemfile +3 -2
- data/ext/Cargo.toml +3 -3
- data/lib/temporalio/api/activity/v1/message.rb +1 -1
- data/lib/temporalio/api/common/v1/message.rb +2 -1
- data/lib/temporalio/api/schedule/v1/message.rb +1 -1
- data/lib/temporalio/api/taskqueue/v1/message.rb +2 -1
- data/lib/temporalio/api/worker/v1/message.rb +1 -1
- data/lib/temporalio/api/workflowservice/v1/request_response.rb +1 -1
- data/lib/temporalio/client/connection.rb +4 -4
- data/lib/temporalio/contrib/aws/s3_driver/aws_sdk_s3_storage_driver_client.rb +52 -0
- data/lib/temporalio/contrib/aws/s3_driver/s3_storage_driver.rb +211 -0
- data/lib/temporalio/contrib/aws/s3_driver/s3_storage_driver_client.rb +56 -0
- data/lib/temporalio/contrib/aws/s3_driver.rb +22 -0
- data/lib/temporalio/contrib/open_telemetry.rb +1 -1
- data/lib/temporalio/converters/external_storage_concurrency.rb +4 -6
- data/lib/temporalio/converters/payload_converter/binary_protobuf.rb +1 -1
- data/lib/temporalio/converters/payload_converter/json_protobuf.rb +1 -1
- data/lib/temporalio/converters/storage_driver_limiter.rb +6 -8
- data/lib/temporalio/converters/storage_driver_retrieve_context.rb +1 -2
- data/lib/temporalio/converters/storage_driver_store_context.rb +1 -2
- data/lib/temporalio/env_config.rb +89 -8
- data/lib/temporalio/internal/bridge/api/activity_result/activity_result.rb +2 -2
- data/lib/temporalio/internal/bridge/api/activity_task/activity_task.rb +3 -1
- data/lib/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rb +2 -1
- data/lib/temporalio/internal/bridge/testing.rb +4 -2
- data/lib/temporalio/internal/worker/workflow_instance/child_workflow_handle.rb +2 -2
- data/lib/temporalio/internal/worker/workflow_instance/context.rb +35 -24
- data/lib/temporalio/internal/worker/workflow_instance/external_workflow_handle.rb +6 -4
- data/lib/temporalio/internal/worker/workflow_instance/nexus_client.rb +3 -2
- data/lib/temporalio/internal/worker/workflow_instance/outbound_implementation.rb +52 -19
- data/lib/temporalio/internal/worker/workflow_instance/scheduler.rb +8 -2
- data/lib/temporalio/internal/worker/workflow_instance.rb +47 -26
- data/lib/temporalio/internal/worker/workflow_worker.rb +1 -2
- data/lib/temporalio/search_attributes.rb +4 -2
- data/lib/temporalio/testing/workflow_environment.rb +10 -2
- data/lib/temporalio/version.rb +1 -1
- data/lib/temporalio/worker/interceptor.rb +16 -8
- data/lib/temporalio/worker/workflow_replayer.rb +1 -1
- data/lib/temporalio/worker.rb +19 -12
- data/lib/temporalio/workflow/child_workflow_handle.rb +4 -1
- data/lib/temporalio/workflow/event_group.rb +157 -0
- data/lib/temporalio/workflow/external_workflow_handle.rb +9 -2
- data/lib/temporalio/workflow/future.rb +1 -1
- data/lib/temporalio/workflow/info.rb +4 -0
- data/lib/temporalio/workflow/nexus_client.rb +11 -3
- data/lib/temporalio/workflow.rb +114 -22
- data/rbi/temporalio/api/activity/v1/message.rbi +71 -2
- data/rbi/temporalio/api/common/v1/message.rbi +95 -0
- data/rbi/temporalio/api/schedule/v1/message.rbi +44 -4
- data/rbi/temporalio/api/taskqueue/v1/message.rbi +67 -0
- data/rbi/temporalio/api/worker/v1/message.rbi +22 -2
- data/rbi/temporalio/api/workflowservice/v1/request_response.rbi +126 -12
- data/rbi/temporalio/contrib/aws/s3_driver/aws_sdk_s3_storage_driver_client.rbi +8 -0
- data/rbi/temporalio/contrib/aws/s3_driver/s3_storage_driver.rbi +27 -0
- data/rbi/temporalio/contrib/aws/s3_driver/s3_storage_driver_client.rbi +17 -0
- data/rbi/temporalio/contrib/aws/s3_driver.rbi +5 -0
- data/rbi/temporalio/env_config.rbi +39 -4
- data/rbi/temporalio/internal/bridge/api/activity_result/activity_result.rbi +0 -19
- data/rbi/temporalio/internal/bridge/api/activity_task/activity_task.rbi +213 -2
- data/rbi/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rbi +50 -4
- data/rbi/temporalio/internal/bridge/testing.rbi +17 -4
- data/rbi/temporalio/internal/bridge/worker.rbi +4 -4
- data/rbi/temporalio/internal/worker/workflow_instance/context.rbi +33 -24
- data/rbi/temporalio/internal/worker/workflow_instance/nexus_client.rbi +4 -2
- data/rbi/temporalio/internal/worker/workflow_instance/outbound_implementation.rbi +17 -6
- data/rbi/temporalio/internal/worker/workflow_instance/scheduler.rbi +1 -1
- data/rbi/temporalio/internal/worker/workflow_instance.rbi +5 -2
- data/rbi/temporalio/testing/workflow_environment.rbi +4 -0
- data/rbi/temporalio/worker/interceptor.rbi +24 -0
- data/rbi/temporalio/worker.rbi +8 -8
- data/rbi/temporalio/workflow/child_workflow_handle.rbi +3 -2
- data/rbi/temporalio/workflow/event_group.rbi +104 -0
- data/rbi/temporalio/workflow/external_workflow_handle.rbi +5 -4
- data/rbi/temporalio/workflow/info.rbi +3 -0
- data/rbi/temporalio/workflow/nexus_client.rbi +8 -4
- data/rbi/temporalio/workflow.rbi +70 -21
- data/sig/temporalio/api/activity/v1/message.rbs +31 -0
- data/sig/temporalio/api/common/v1/message.rbs +35 -0
- data/sig/temporalio/api/schedule/v1/message.rbs +20 -0
- data/sig/temporalio/api/taskqueue/v1/message.rbs +24 -0
- data/sig/temporalio/api/worker/v1/message.rbs +10 -0
- data/sig/temporalio/api/workflowservice/v1/request_response.rbs +58 -0
- data/sig/temporalio/contrib/aws/s3_driver/aws_sdk_s3_storage_driver_client.rbs +13 -0
- data/sig/temporalio/contrib/aws/s3_driver/s3_storage_driver.rbs +68 -0
- data/sig/temporalio/contrib/aws/s3_driver/s3_storage_driver_client.rbs +14 -0
- data/sig/temporalio/contrib/aws/s3_driver.rbs +8 -0
- data/sig/temporalio/env_config.rbs +20 -2
- data/sig/temporalio/internal/bridge/api/activity_result/activity_result.rbs +6 -41
- data/sig/temporalio/internal/bridge/api/activity_task/activity_task.rbs +99 -0
- data/sig/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rbs +22 -0
- data/sig/temporalio/internal/bridge/testing.rbs +7 -3
- data/sig/temporalio/internal/bridge/worker.rbs +4 -4
- data/sig/temporalio/internal/worker/workflow_instance/context.rbs +19 -13
- data/sig/temporalio/internal/worker/workflow_instance/nexus_client.rbs +2 -1
- data/sig/temporalio/internal/worker/workflow_instance/outbound_implementation.rbs +8 -5
- data/sig/temporalio/internal/worker/workflow_instance/scheduler.rbs +1 -1
- data/sig/temporalio/internal/worker/workflow_instance.rbs +2 -1
- data/sig/temporalio/testing/workflow_environment.rbs +8 -4
- data/sig/temporalio/worker/interceptor.rbs +24 -8
- data/sig/temporalio/worker.rbs +12 -12
- data/sig/temporalio/workflow/child_workflow_handle.rbs +2 -1
- data/sig/temporalio/workflow/event_group.rbs +37 -0
- data/sig/temporalio/workflow/external_workflow_handle.rbs +3 -2
- data/sig/temporalio/workflow/info.rbs +2 -0
- data/sig/temporalio/workflow/nexus_client.rbs +4 -2
- data/sig/temporalio/workflow.rbs +27 -11
- metadata +16 -1
|
@@ -61,7 +61,8 @@ module Temporalio
|
|
|
61
61
|
:current_deployment_version,
|
|
62
62
|
:current_history_length, :current_history_size, :replaying, :random,
|
|
63
63
|
:signal_handlers, :query_handlers, :update_handlers, :context_frozen, :assert_valid_local_activity,
|
|
64
|
-
:in_query_or_validator, :random_disabled, :patch_activation_callback
|
|
64
|
+
:in_query_or_validator, :random_disabled, :patch_activation_callback,
|
|
65
|
+
:check_conditions
|
|
65
66
|
attr_accessor :io_enabled, :current_details
|
|
66
67
|
|
|
67
68
|
def initialize(details)
|
|
@@ -102,6 +103,7 @@ module Temporalio
|
|
|
102
103
|
@replaying = false
|
|
103
104
|
@context_frozen = false
|
|
104
105
|
@in_query_or_validator = false
|
|
106
|
+
@check_conditions = false
|
|
105
107
|
@random_disabled = false
|
|
106
108
|
@workflow_failure_exception_types = details.workflow_failure_exception_types
|
|
107
109
|
@signal_handlers = HandlerHash.new(
|
|
@@ -147,6 +149,8 @@ module Temporalio
|
|
|
147
149
|
end,
|
|
148
150
|
has_last_result?: !@init_job.last_completion_result.nil?,
|
|
149
151
|
namespace: details.namespace,
|
|
152
|
+
original_execution_run_id: ProtoUtils.string_or(@init_job.original_execution_run_id) ||
|
|
153
|
+
details.initial_activation.run_id,
|
|
150
154
|
parent: if @init_job.parent_workflow_info
|
|
151
155
|
Workflow::Info::ParentInfo.new(
|
|
152
156
|
namespace: @init_job.parent_workflow_info.namespace,
|
|
@@ -194,6 +198,10 @@ module Temporalio
|
|
|
194
198
|
@current_history_size = activation.history_size_bytes
|
|
195
199
|
@replaying = activation.is_replaying
|
|
196
200
|
@now_timestamp = activation.timestamp
|
|
201
|
+
# Updates can only change state once accepted, which is recorded when that happens
|
|
202
|
+
@check_conditions = activation.jobs.any? do |job|
|
|
203
|
+
!%i[do_update query_workflow].include?(job.variant)
|
|
204
|
+
end
|
|
197
205
|
|
|
198
206
|
# Apply jobs and run event loop
|
|
199
207
|
begin
|
|
@@ -289,7 +297,7 @@ module Temporalio
|
|
|
289
297
|
end
|
|
290
298
|
end
|
|
291
299
|
|
|
292
|
-
def patch(patch_id:, deprecated:)
|
|
300
|
+
def patch(patch_id:, deprecated:, event_groups: nil)
|
|
293
301
|
# Use memoized result if present. If this is being deprecated, we can still use memoized result and skip the
|
|
294
302
|
# command.
|
|
295
303
|
patch_id = patch_id.to_s
|
|
@@ -305,7 +313,8 @@ module Temporalio
|
|
|
305
313
|
if patched
|
|
306
314
|
add_command(
|
|
307
315
|
Bridge::Api::WorkflowCommands::WorkflowCommand.new(
|
|
308
|
-
set_patch_marker: Bridge::Api::WorkflowCommands::SetPatchMarker.new(patch_id:, deprecated:)
|
|
316
|
+
set_patch_marker: Bridge::Api::WorkflowCommands::SetPatchMarker.new(patch_id:, deprecated:),
|
|
317
|
+
event_group_markers: Workflow::EventGroup._markers_for_command(event_groups)
|
|
309
318
|
)
|
|
310
319
|
)
|
|
311
320
|
end
|
|
@@ -426,6 +435,10 @@ module Temporalio
|
|
|
426
435
|
end
|
|
427
436
|
|
|
428
437
|
def apply_signal(job)
|
|
438
|
+
if job.originating_event_id.nil? || job.originating_event_id <= 0
|
|
439
|
+
raise "Signal #{job.signal_name} has invalid originating event ID #{job.originating_event_id}"
|
|
440
|
+
end
|
|
441
|
+
|
|
429
442
|
# Get signal definition, falling back to dynamic if not present and not reserved
|
|
430
443
|
defn = signal_handlers[job.signal_name]
|
|
431
444
|
defn = signal_handlers[nil] if !defn && !Internal::ProtoUtils.reserved_name?(job.signal_name)
|
|
@@ -436,27 +449,29 @@ module Temporalio
|
|
|
436
449
|
end
|
|
437
450
|
# Process as a top level handler so that errors are treated as if in primary workflow method
|
|
438
451
|
schedule(top_level: true, handler_exec:) do
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
452
|
+
Workflow::EventGroup._with_inbound_event(job.originating_event_id) do
|
|
453
|
+
# Send to interceptor if there is a definition, buffer otherwise
|
|
454
|
+
if defn
|
|
455
|
+
@inbound.handle_signal(
|
|
456
|
+
Temporalio::Worker::Interceptor::Workflow::HandleSignalInput.new(
|
|
457
|
+
signal: job.signal_name,
|
|
458
|
+
args: begin
|
|
459
|
+
convert_handler_args(payload_array: job.input, defn:)
|
|
460
|
+
rescue StandardError => e
|
|
461
|
+
# Signals argument conversion failure must not fail task
|
|
462
|
+
@logger.error("Failed converting signal input arguments for #{job.signal_name}, dropping signal")
|
|
463
|
+
@logger.error(e)
|
|
464
|
+
next
|
|
465
|
+
end,
|
|
466
|
+
definition: defn,
|
|
467
|
+
headers: ProtoUtils.headers_from_proto_map(job.headers, @payload_converter) || {}
|
|
468
|
+
)
|
|
454
469
|
)
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
470
|
+
else
|
|
471
|
+
buffered = @buffered_signals[job.signal_name]
|
|
472
|
+
buffered = @buffered_signals[job.signal_name] = [] if buffered.nil?
|
|
473
|
+
buffered << job
|
|
474
|
+
end
|
|
460
475
|
end
|
|
461
476
|
end
|
|
462
477
|
end
|
|
@@ -522,6 +537,8 @@ module Temporalio
|
|
|
522
537
|
end
|
|
523
538
|
|
|
524
539
|
def apply_update(job)
|
|
540
|
+
raise "Update #{job.name} has invalid update ID #{job.id.inspect}" if job.id.nil? || job.id.empty?
|
|
541
|
+
|
|
525
542
|
# Get update definition, falling back to dynamic if not present and not reserved
|
|
526
543
|
defn = update_handlers[job.name]
|
|
527
544
|
defn = update_handlers[nil] if !defn && !Internal::ProtoUtils.reserved_name?(job.name)
|
|
@@ -585,9 +602,12 @@ module Temporalio
|
|
|
585
602
|
)
|
|
586
603
|
)
|
|
587
604
|
accepted = true
|
|
605
|
+
@check_conditions = true
|
|
588
606
|
|
|
589
|
-
# Issue update
|
|
590
|
-
result =
|
|
607
|
+
# Issue update. Validators are intentionally not wrapped in the EG scope
|
|
608
|
+
result = Workflow::EventGroup._with_inbound_update(job.id) do
|
|
609
|
+
@inbound.handle_update(input)
|
|
610
|
+
end
|
|
591
611
|
|
|
592
612
|
add_command(
|
|
593
613
|
Bridge::Api::WorkflowCommands::WorkflowCommand.new(
|
|
@@ -672,7 +692,8 @@ module Temporalio
|
|
|
672
692
|
search_attributes: err.search_attributes&._to_proto,
|
|
673
693
|
retry_policy: err.retry_policy&._to_proto,
|
|
674
694
|
initial_versioning_behavior: err.initial_versioning_behavior || 0
|
|
675
|
-
)
|
|
695
|
+
),
|
|
696
|
+
event_group_markers: err.send(:_event_group_markers) || []
|
|
676
697
|
)
|
|
677
698
|
)
|
|
678
699
|
elsif @cancellation.canceled? && Error.canceled?(err)
|
|
@@ -148,7 +148,7 @@ module Temporalio
|
|
|
148
148
|
end
|
|
149
149
|
|
|
150
150
|
# Returns whether completion was submitted to the bridge
|
|
151
|
-
# rubocop:disable Naming/PredicateMethod
|
|
151
|
+
# rubocop:disable-next Naming/PredicateMethod
|
|
152
152
|
def handle_activation_complete(runner:, activation_completion:, encoded:, completion_complete_queue:)
|
|
153
153
|
if @payload_encoding_visitor && !encoded
|
|
154
154
|
if Fiber.current_scheduler
|
|
@@ -166,7 +166,6 @@ module Temporalio
|
|
|
166
166
|
true
|
|
167
167
|
end
|
|
168
168
|
end
|
|
169
|
-
# rubocop:enable Naming/PredicateMethod
|
|
170
169
|
|
|
171
170
|
def on_shutdown_complete
|
|
172
171
|
@state.evict_all
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'temporalio/api'
|
|
4
|
+
require 'time'
|
|
4
5
|
|
|
5
6
|
module Temporalio
|
|
6
7
|
# Collection of typed search attributes.
|
|
@@ -142,8 +143,9 @@ module Temporalio
|
|
|
142
143
|
|
|
143
144
|
# @!visibility private
|
|
144
145
|
def self._to_proto_pair(key, value)
|
|
145
|
-
# We use a default converter, but if type is a time, we need ISO format
|
|
146
|
-
|
|
146
|
+
# We use a default converter, but if type is a time, we need ISO format with nanoseconds since the server keeps
|
|
147
|
+
# sub-second precision
|
|
148
|
+
value = value.iso8601(9) if key.type == IndexedValueType::TIME && value.is_a?(Time)
|
|
147
149
|
|
|
148
150
|
# Convert to payload
|
|
149
151
|
payload = Converters::PayloadConverter.default.to_payload(value)
|
|
@@ -52,6 +52,8 @@ module Temporalio
|
|
|
52
52
|
# @param dev_server_extra_args [Array<String>] Any extra arguments for the CLI dev server.
|
|
53
53
|
# @param dev_server_download_ttl [Float, nil] How long the automatic download should be cached for. If nil, cached
|
|
54
54
|
# indefinitely.
|
|
55
|
+
# @param dev_server_startup_timeout [Float, nil] Seconds to wait for startup, excluding download time.
|
|
56
|
+
# Defaults to 5.
|
|
55
57
|
#
|
|
56
58
|
# @yield [environment] If a block is given, it is called with the environment and upon complete the environment is
|
|
57
59
|
# shutdown.
|
|
@@ -79,6 +81,7 @@ module Temporalio
|
|
|
79
81
|
dev_server_download_dest_dir: nil,
|
|
80
82
|
dev_server_extra_args: [],
|
|
81
83
|
dev_server_download_ttl: nil,
|
|
84
|
+
dev_server_startup_timeout: nil,
|
|
82
85
|
&
|
|
83
86
|
)
|
|
84
87
|
# Add search attribute args
|
|
@@ -105,7 +108,8 @@ module Temporalio
|
|
|
105
108
|
log_format: dev_server_log_format,
|
|
106
109
|
log_level: dev_server_log_level,
|
|
107
110
|
extra_args: dev_server_extra_args,
|
|
108
|
-
download_ttl: dev_server_download_ttl
|
|
111
|
+
download_ttl: dev_server_download_ttl,
|
|
112
|
+
startup_timeout: dev_server_startup_timeout
|
|
109
113
|
)
|
|
110
114
|
_with_core_server(
|
|
111
115
|
core_server: Internal::Bridge::Testing::EphemeralServer.start_dev_server(
|
|
@@ -144,6 +148,8 @@ module Temporalio
|
|
|
144
148
|
# @param test_server_extra_args [Array<String>] Any extra arguments for the test server.
|
|
145
149
|
# @param test_server_download_ttl [Float, nil] How long the automatic download should be cached for. If nil,
|
|
146
150
|
# cached indefinitely.
|
|
151
|
+
# @param test_server_startup_timeout [Float, nil] Seconds to wait for startup, excluding download time.
|
|
152
|
+
# Defaults to 5.
|
|
147
153
|
#
|
|
148
154
|
# @yield [environment] If a block is given, it is called with the environment and upon complete the environment is
|
|
149
155
|
# shutdown.
|
|
@@ -163,6 +169,7 @@ module Temporalio
|
|
|
163
169
|
test_server_download_dest_dir: nil,
|
|
164
170
|
test_server_extra_args: [],
|
|
165
171
|
test_server_download_ttl: nil,
|
|
172
|
+
test_server_startup_timeout: nil,
|
|
166
173
|
&
|
|
167
174
|
)
|
|
168
175
|
server_options = Internal::Bridge::Testing::EphemeralServer::StartTestServerOptions.new(
|
|
@@ -173,7 +180,8 @@ module Temporalio
|
|
|
173
180
|
download_dest_dir: test_server_download_dest_dir,
|
|
174
181
|
port:,
|
|
175
182
|
extra_args: test_server_extra_args,
|
|
176
|
-
download_ttl: test_server_download_ttl
|
|
183
|
+
download_ttl: test_server_download_ttl,
|
|
184
|
+
startup_timeout: test_server_startup_timeout
|
|
177
185
|
)
|
|
178
186
|
_with_core_server(
|
|
179
187
|
core_server: Internal::Bridge::Testing::EphemeralServer.start_test_server(
|
data/lib/temporalio/version.rb
CHANGED
|
@@ -200,7 +200,8 @@ module Temporalio
|
|
|
200
200
|
# Input for {Outbound.cancel_external_workflow}.
|
|
201
201
|
CancelExternalWorkflowInput = Data.define(
|
|
202
202
|
:id,
|
|
203
|
-
:run_id
|
|
203
|
+
:run_id,
|
|
204
|
+
:event_groups
|
|
204
205
|
)
|
|
205
206
|
|
|
206
207
|
# Input for {Outbound.execute_activity}.
|
|
@@ -221,7 +222,8 @@ module Temporalio
|
|
|
221
222
|
:priority,
|
|
222
223
|
:arg_hints,
|
|
223
224
|
:result_hint,
|
|
224
|
-
:headers
|
|
225
|
+
:headers,
|
|
226
|
+
:event_groups
|
|
225
227
|
)
|
|
226
228
|
|
|
227
229
|
# Input for {Outbound.execute_local_activity}.
|
|
@@ -239,7 +241,8 @@ module Temporalio
|
|
|
239
241
|
:activity_id,
|
|
240
242
|
:arg_hints,
|
|
241
243
|
:result_hint,
|
|
242
|
-
:headers
|
|
244
|
+
:headers,
|
|
245
|
+
:event_groups
|
|
243
246
|
)
|
|
244
247
|
|
|
245
248
|
# Input for {Outbound.initialize_continue_as_new_error}.
|
|
@@ -254,7 +257,8 @@ module Temporalio
|
|
|
254
257
|
:args,
|
|
255
258
|
:cancellation,
|
|
256
259
|
:arg_hints,
|
|
257
|
-
:headers
|
|
260
|
+
:headers,
|
|
261
|
+
:event_groups
|
|
258
262
|
)
|
|
259
263
|
|
|
260
264
|
# Input for {Outbound.signal_external_workflow}.
|
|
@@ -265,14 +269,16 @@ module Temporalio
|
|
|
265
269
|
:args,
|
|
266
270
|
:cancellation,
|
|
267
271
|
:arg_hints,
|
|
268
|
-
:headers
|
|
272
|
+
:headers,
|
|
273
|
+
:event_groups
|
|
269
274
|
)
|
|
270
275
|
|
|
271
276
|
# Input for {Outbound.sleep}.
|
|
272
277
|
SleepInput = Data.define(
|
|
273
278
|
:duration,
|
|
274
279
|
:summary,
|
|
275
|
-
:cancellation
|
|
280
|
+
:cancellation,
|
|
281
|
+
:event_groups
|
|
276
282
|
)
|
|
277
283
|
|
|
278
284
|
# Input for {Outbound.start_child_workflow}.
|
|
@@ -298,7 +304,8 @@ module Temporalio
|
|
|
298
304
|
:versioning_override,
|
|
299
305
|
:arg_hints,
|
|
300
306
|
:result_hint,
|
|
301
|
-
:headers
|
|
307
|
+
:headers,
|
|
308
|
+
:event_groups
|
|
302
309
|
)
|
|
303
310
|
|
|
304
311
|
# Input for {Outbound.start_nexus_operation}.
|
|
@@ -317,7 +324,8 @@ module Temporalio
|
|
|
317
324
|
:cancellation,
|
|
318
325
|
:arg_hint,
|
|
319
326
|
:result_hint,
|
|
320
|
-
:headers
|
|
327
|
+
:headers,
|
|
328
|
+
:event_groups
|
|
321
329
|
)
|
|
322
330
|
|
|
323
331
|
# Outbound interceptor for intercepting outbound workflow calls. This should be extended by users needing to
|
|
@@ -130,7 +130,7 @@ module Temporalio
|
|
|
130
130
|
workflow_definitions: @workflow_definitions
|
|
131
131
|
)
|
|
132
132
|
# If there is a block, we'll go ahead and assume it's for with_replay_worker
|
|
133
|
-
with_replay_worker(&) if block_given?
|
|
133
|
+
with_replay_worker(&) if block_given?
|
|
134
134
|
end
|
|
135
135
|
|
|
136
136
|
# Replay a workflow history.
|
data/lib/temporalio/worker.rb
CHANGED
|
@@ -395,15 +395,15 @@ module Temporalio
|
|
|
395
395
|
# @param logger [Logger] Logger to override client logger with. Default is the client logger.
|
|
396
396
|
# @param max_cached_workflows [Integer] Number of workflows held in cache for use by sticky task queue. If set to 0,
|
|
397
397
|
# workflow caching and sticky queuing are disabled.
|
|
398
|
-
# @param max_concurrent_workflow_task_polls [Integer] Maximum number of concurrent poll workflow task requests
|
|
399
|
-
# will perform at a time on this worker's task queue.
|
|
398
|
+
# @param max_concurrent_workflow_task_polls [Integer, nil] Maximum number of concurrent poll workflow task requests
|
|
399
|
+
# we will perform at a time on this worker's task queue.
|
|
400
400
|
# @param nonsticky_to_sticky_poll_ratio [Float] `max_concurrent_workflow_task_polls` * this number = the number of
|
|
401
401
|
# max pollers that will be allowed for the nonsticky queue when sticky tasks are enabled. If both defaults are
|
|
402
402
|
# used, the sticky queue will allow 4 max pollers while the nonsticky queue will allow one. The minimum for either
|
|
403
403
|
# poller is 1, so if `max_concurrent_workflow_task_polls` is 1 and sticky queues are enabled, there will be 2
|
|
404
404
|
# concurrent polls.
|
|
405
|
-
# @param max_concurrent_activity_task_polls [Integer] Maximum number of concurrent poll activity task requests
|
|
406
|
-
# will perform at a time on this worker's task queue.
|
|
405
|
+
# @param max_concurrent_activity_task_polls [Integer, nil] Maximum number of concurrent poll activity task requests
|
|
406
|
+
# we will perform at a time on this worker's task queue.
|
|
407
407
|
# @param no_remote_activities [Boolean] If true, this worker will only handle workflow tasks and local activities,
|
|
408
408
|
# it will not poll for activity tasks.
|
|
409
409
|
# @param sticky_queue_schedule_to_start_timeout [Float] How long a workflow task is allowed to sit on the sticky
|
|
@@ -450,9 +450,9 @@ module Temporalio
|
|
|
450
450
|
# @param patch_activation_callback [Proc, nil] Experimental callback to decide whether the first non-replay call to
|
|
451
451
|
# {Workflow.patched} for a patch ID should activate that patch. The callback receives a {PatchActivationInput} and
|
|
452
452
|
# must return `true` to activate the patch or `false` to leave it inactive.
|
|
453
|
-
# @param workflow_task_poller_behavior [PollerBehavior] Specify the behavior of workflow task
|
|
453
|
+
# @param workflow_task_poller_behavior [PollerBehavior, nil] Specify the behavior of workflow task
|
|
454
454
|
# polling. Defaults to a 5-poller maximum.
|
|
455
|
-
# @param activity_task_poller_behavior [PollerBehavior] Specify the behavior of activity task
|
|
455
|
+
# @param activity_task_poller_behavior [PollerBehavior, nil] Specify the behavior of activity task
|
|
456
456
|
# polling. Defaults to a 5-poller maximum.
|
|
457
457
|
# @param debug_mode [Boolean] If true, deadlock detection is disabled. Deadlock detection will fail workflow tasks
|
|
458
458
|
# if they block the thread for too long. This defaults to true if the `TEMPORAL_DEBUG` environment variable is
|
|
@@ -473,9 +473,9 @@ module Temporalio
|
|
|
473
473
|
identity: nil,
|
|
474
474
|
logger: client.options.logger,
|
|
475
475
|
max_cached_workflows: 1000,
|
|
476
|
-
max_concurrent_workflow_task_polls:
|
|
476
|
+
max_concurrent_workflow_task_polls: nil,
|
|
477
477
|
nonsticky_to_sticky_poll_ratio: 0.2,
|
|
478
|
-
max_concurrent_activity_task_polls:
|
|
478
|
+
max_concurrent_activity_task_polls: nil,
|
|
479
479
|
no_remote_activities: false,
|
|
480
480
|
sticky_queue_schedule_to_start_timeout: 10,
|
|
481
481
|
max_heartbeat_throttle_interval: 60,
|
|
@@ -491,13 +491,20 @@ module Temporalio
|
|
|
491
491
|
unsafe_workflow_io_enabled: false,
|
|
492
492
|
deployment_options: Worker.default_deployment_options,
|
|
493
493
|
patch_activation_callback: nil,
|
|
494
|
-
workflow_task_poller_behavior:
|
|
495
|
-
activity_task_poller_behavior:
|
|
494
|
+
workflow_task_poller_behavior: nil,
|
|
495
|
+
activity_task_poller_behavior: nil,
|
|
496
496
|
debug_mode: %w[true 1].include?(ENV['TEMPORAL_DEBUG'].to_s.downcase),
|
|
497
497
|
disable_payload_error_limit: false
|
|
498
498
|
)
|
|
499
499
|
Internal::ProtoUtils.assert_non_reserved_name(task_queue)
|
|
500
500
|
|
|
501
|
+
if max_concurrent_workflow_task_polls
|
|
502
|
+
workflow_task_poller_behavior ||= PollerBehavior::SimpleMaximum.new(max_concurrent_workflow_task_polls)
|
|
503
|
+
end
|
|
504
|
+
if max_concurrent_activity_task_polls
|
|
505
|
+
activity_task_poller_behavior ||= PollerBehavior::SimpleMaximum.new(max_concurrent_activity_task_polls)
|
|
506
|
+
end
|
|
507
|
+
|
|
501
508
|
@options = Options.new(
|
|
502
509
|
client:,
|
|
503
510
|
task_queue:,
|
|
@@ -582,9 +589,9 @@ module Temporalio
|
|
|
582
589
|
tuner: @options.tuner._to_bridge_options,
|
|
583
590
|
identity_override: @options.identity,
|
|
584
591
|
max_cached_workflows: @options.max_cached_workflows,
|
|
585
|
-
workflow_task_poller_behavior: @options.workflow_task_poller_behavior
|
|
592
|
+
workflow_task_poller_behavior: @options.workflow_task_poller_behavior&._to_bridge_options,
|
|
586
593
|
nonsticky_to_sticky_poll_ratio: @options.nonsticky_to_sticky_poll_ratio,
|
|
587
|
-
activity_task_poller_behavior: @options.activity_task_poller_behavior
|
|
594
|
+
activity_task_poller_behavior: @options.activity_task_poller_behavior&._to_bridge_options,
|
|
588
595
|
enable_workflows: !@options.workflows.empty?,
|
|
589
596
|
enable_local_activities: !@options.workflows.empty? && !@options.activities.empty?,
|
|
590
597
|
enable_remote_activities: !@options.activities.empty? && !@options.no_remote_activities,
|
|
@@ -43,7 +43,10 @@ module Temporalio
|
|
|
43
43
|
# @param cancellation [Cancellation] Cancellation for canceling the signalling.
|
|
44
44
|
# @param arg_hints [Array<Object>, nil] Overrides converter hints for arguments if any. If unset/nil and the
|
|
45
45
|
# signal definition has arg hints, those are used by default.
|
|
46
|
-
|
|
46
|
+
# @param event_groups [Array<EventGroup>, nil] Event Groups to attach to the signal command, in
|
|
47
|
+
# addition to any groups from enclosing {Workflow.with_event_groups} scopes.
|
|
48
|
+
# WARNING: This option is experimental.
|
|
49
|
+
def signal(signal, *args, cancellation: Workflow.cancellation, arg_hints: nil, event_groups: nil)
|
|
47
50
|
raise NotImplementedError
|
|
48
51
|
end
|
|
49
52
|
end
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'temporalio/api/sdk/v1/event_group_marker'
|
|
4
|
+
require 'temporalio/converters/payload_converter'
|
|
5
|
+
|
|
6
|
+
module Temporalio
|
|
7
|
+
module Workflow
|
|
8
|
+
# A discrete token associating workflow commands, and the history events they produce, with a logical group for UI
|
|
9
|
+
# and observability purposes.
|
|
10
|
+
#
|
|
11
|
+
# Multiple Event Groups may be attached to a single command, and a single Event Group may be attached to multiple
|
|
12
|
+
# commands. Instances are created with {Workflow.create_event_group}. Attach them to specific commands via the
|
|
13
|
+
# `event_groups:` option, or to every command produced within a block via {Workflow.with_event_groups}.
|
|
14
|
+
#
|
|
15
|
+
# WARNING: Event Groups support is experimental.
|
|
16
|
+
class EventGroup
|
|
17
|
+
# @!visibility private
|
|
18
|
+
Active = Struct.new(:implicit, :explicit, keyword_init: true)
|
|
19
|
+
|
|
20
|
+
# @!visibility private
|
|
21
|
+
EMPTY_ACTIVE = Active.new(implicit: nil, explicit: {}.freeze).freeze
|
|
22
|
+
|
|
23
|
+
# @!visibility private
|
|
24
|
+
STORAGE_KEY = :__temporal_event_groups
|
|
25
|
+
|
|
26
|
+
class << self
|
|
27
|
+
# @!visibility private
|
|
28
|
+
def _active
|
|
29
|
+
Fiber[STORAGE_KEY] || EMPTY_ACTIVE
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# @!visibility private
|
|
33
|
+
def _with_active(active)
|
|
34
|
+
prev = Fiber[STORAGE_KEY]
|
|
35
|
+
Fiber[STORAGE_KEY] = active
|
|
36
|
+
yield
|
|
37
|
+
ensure
|
|
38
|
+
Fiber[STORAGE_KEY] = prev
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @!visibility private
|
|
42
|
+
def _with_event_groups(*groups, &)
|
|
43
|
+
active = _active
|
|
44
|
+
explicit = active.explicit.dup
|
|
45
|
+
groups.each do |group|
|
|
46
|
+
unless group.is_a?(Label)
|
|
47
|
+
raise TypeError, 'Event groups must be created with Temporalio::Workflow.create_event_group'
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
explicit[group.id] = group
|
|
51
|
+
end
|
|
52
|
+
_with_active(Active.new(implicit: active.implicit, explicit:), &)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @!visibility private
|
|
56
|
+
def _with_inbound_event(event_id, &)
|
|
57
|
+
group = Implicit.new(
|
|
58
|
+
Api::Sdk::V1::EventGroupMarker.new(
|
|
59
|
+
inbound_event: Api::Sdk::V1::EventGroupMarker::InboundEvent.new(inbound_event_id: event_id)
|
|
60
|
+
)
|
|
61
|
+
)
|
|
62
|
+
_with_active(group._applied_over(_active), &)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# @!visibility private
|
|
66
|
+
def _with_inbound_update(update_id, &)
|
|
67
|
+
group = Implicit.new(
|
|
68
|
+
Api::Sdk::V1::EventGroupMarker.new(
|
|
69
|
+
inbound_update: Api::Sdk::V1::EventGroupMarker::InboundUpdate.new(inbound_update_id: update_id)
|
|
70
|
+
)
|
|
71
|
+
)
|
|
72
|
+
_with_active(group._applied_over(_active), &)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# @!visibility private
|
|
76
|
+
def _markers_for_command(directs)
|
|
77
|
+
active = _active
|
|
78
|
+
explicit = active.explicit
|
|
79
|
+
if directs
|
|
80
|
+
explicit = explicit.dup
|
|
81
|
+
directs.each do |group|
|
|
82
|
+
unless group.is_a?(Label)
|
|
83
|
+
raise TypeError, 'Event groups must be created with Temporalio::Workflow.create_event_group'
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
explicit[group.id] = group
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
groups = explicit.values
|
|
90
|
+
groups.unshift(active.implicit) if active.implicit
|
|
91
|
+
groups.map(&:_to_proto)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# @!visibility private
|
|
96
|
+
def initialize
|
|
97
|
+
raise NotImplementedError, 'Cannot instantiate EventGroup directly, use Temporalio::Workflow.create_event_group'
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# @!visibility private
|
|
101
|
+
def _applied_over(_active)
|
|
102
|
+
raise NotImplementedError
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# @!visibility private
|
|
106
|
+
def _to_proto
|
|
107
|
+
raise NotImplementedError
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# An Event Group explicitly created by workflow code.
|
|
111
|
+
#
|
|
112
|
+
# @!visibility private
|
|
113
|
+
class Label < EventGroup
|
|
114
|
+
attr_reader :id, :label
|
|
115
|
+
|
|
116
|
+
def initialize(id, label) # rubocop:disable Lint/MissingSuper
|
|
117
|
+
@id = id
|
|
118
|
+
@label = label
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# @!visibility private
|
|
122
|
+
def _applied_over(active)
|
|
123
|
+
Active.new(implicit: active.implicit, explicit: active.explicit.merge(id => self))
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# @!visibility private
|
|
127
|
+
def _to_proto
|
|
128
|
+
marker_label = Api::Sdk::V1::EventGroupMarker::Label.new(id:)
|
|
129
|
+
# Deliberately the SDK's default converter, not the user-provided one.
|
|
130
|
+
marker_label.label = Converters::PayloadConverter.default.to_payload(label) if label
|
|
131
|
+
Api::Sdk::V1::EventGroupMarker.new(label: marker_label)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# An Event Group created by the SDK around an inbound signal or update.
|
|
136
|
+
#
|
|
137
|
+
# @!visibility private
|
|
138
|
+
class Implicit < EventGroup
|
|
139
|
+
def initialize(marker) # rubocop:disable Lint/MissingSuper
|
|
140
|
+
@marker = marker
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# @!visibility private
|
|
144
|
+
def _applied_over(_active)
|
|
145
|
+
# Implicit groups do not inherit enclosing explicit scopes: a handler registered
|
|
146
|
+
# inside an explicit scope must not attribute its commands to that scope.
|
|
147
|
+
Active.new(implicit: self, explicit: {})
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# @!visibility private
|
|
151
|
+
def _to_proto
|
|
152
|
+
@marker
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
@@ -30,12 +30,19 @@ module Temporalio
|
|
|
30
30
|
# @param cancellation [Cancellation] Cancellation for canceling the signalling.
|
|
31
31
|
# @param arg_hints [Array<Object>, nil] Overrides converter hints for arguments if any. If unset/nil and the
|
|
32
32
|
# signal definition has arg hints, those are used by default.
|
|
33
|
-
|
|
33
|
+
# @param event_groups [Array<EventGroup>, nil] Event Groups to attach to the signal command, in
|
|
34
|
+
# addition to any groups from enclosing {Workflow.with_event_groups} scopes.
|
|
35
|
+
# WARNING: This option is experimental.
|
|
36
|
+
def signal(signal, *args, cancellation: Workflow.cancellation, arg_hints: nil, event_groups: nil)
|
|
34
37
|
raise NotImplementedError
|
|
35
38
|
end
|
|
36
39
|
|
|
37
40
|
# Cancel the external workflow.
|
|
38
|
-
|
|
41
|
+
#
|
|
42
|
+
# @param event_groups [Array<EventGroup>, nil] Event Groups to attach to the cancel command, in
|
|
43
|
+
# addition to any groups from enclosing {Workflow.with_event_groups} scopes.
|
|
44
|
+
# WARNING: This option is experimental.
|
|
45
|
+
def cancel(event_groups: nil)
|
|
39
46
|
raise NotImplementedError
|
|
40
47
|
end
|
|
41
48
|
end
|
|
@@ -80,7 +80,7 @@ module Temporalio
|
|
|
80
80
|
return unless block_given?
|
|
81
81
|
|
|
82
82
|
@fiber = Fiber.schedule do
|
|
83
|
-
@result = block.call
|
|
83
|
+
@result = block.call
|
|
84
84
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
|
85
85
|
# These errors invalidate the whole workflow task. If stored and only raised on wait, the activation may
|
|
86
86
|
# complete successfully with commands that were emitted before the error.
|
|
@@ -13,6 +13,7 @@ module Temporalio
|
|
|
13
13
|
:last_result,
|
|
14
14
|
:has_last_result?,
|
|
15
15
|
:namespace,
|
|
16
|
+
:original_execution_run_id,
|
|
16
17
|
:parent,
|
|
17
18
|
:priority,
|
|
18
19
|
:retry_policy,
|
|
@@ -49,6 +50,9 @@ module Temporalio
|
|
|
49
50
|
|
|
50
51
|
# @!attribute namespace
|
|
51
52
|
# @return [String] Namespace for the workflow.
|
|
53
|
+
# @!attribute original_execution_run_id
|
|
54
|
+
# @return [String] Run ID recorded on the workflow execution started event. Unlike {#run_id},
|
|
55
|
+
# this value is preserved across workflow resets.
|
|
52
56
|
# @!attribute parent
|
|
53
57
|
# @return [ParentInfo, nil] Parent information for the workflow if this is a child.
|
|
54
58
|
# @!attribute priority
|