temporalio 0.2.0-aarch64-linux → 0.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/.yardopts +2 -0
- data/Gemfile +3 -3
- data/Rakefile +10 -296
- data/lib/temporalio/activity/complete_async_error.rb +1 -1
- data/lib/temporalio/activity/context.rb +5 -2
- data/lib/temporalio/activity/definition.rb +163 -65
- data/lib/temporalio/activity/info.rb +22 -21
- data/lib/temporalio/activity.rb +2 -59
- data/lib/temporalio/api/activity/v1/message.rb +25 -0
- data/lib/temporalio/api/cloud/account/v1/message.rb +28 -0
- data/lib/temporalio/api/cloud/cloudservice/v1/request_response.rb +34 -1
- data/lib/temporalio/api/cloud/cloudservice/v1/service.rb +1 -1
- data/lib/temporalio/api/cloud/identity/v1/message.rb +6 -1
- data/lib/temporalio/api/cloud/namespace/v1/message.rb +8 -1
- data/lib/temporalio/api/cloud/nexus/v1/message.rb +31 -0
- data/lib/temporalio/api/cloud/operation/v1/message.rb +2 -1
- data/lib/temporalio/api/cloud/region/v1/message.rb +2 -1
- data/lib/temporalio/api/cloud/resource/v1/message.rb +23 -0
- data/lib/temporalio/api/cloud/sink/v1/message.rb +24 -0
- data/lib/temporalio/api/cloud/usage/v1/message.rb +31 -0
- data/lib/temporalio/api/common/v1/message.rb +7 -1
- 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/reset.rb +1 -1
- data/lib/temporalio/api/history/v1/message.rb +1 -1
- data/lib/temporalio/api/nexus/v1/message.rb +2 -2
- data/lib/temporalio/api/operatorservice/v1/service.rb +1 -1
- data/lib/temporalio/api/payload_visitor.rb +1513 -0
- data/lib/temporalio/api/schedule/v1/message.rb +2 -1
- data/lib/temporalio/api/testservice/v1/request_response.rb +31 -0
- data/lib/temporalio/api/testservice/v1/service.rb +23 -0
- data/lib/temporalio/api/workflow/v1/message.rb +1 -1
- data/lib/temporalio/api/workflowservice/v1/request_response.rb +17 -2
- data/lib/temporalio/api/workflowservice/v1/service.rb +1 -1
- data/lib/temporalio/api.rb +1 -0
- data/lib/temporalio/cancellation.rb +34 -14
- data/lib/temporalio/client/async_activity_handle.rb +12 -37
- data/lib/temporalio/client/connection/cloud_service.rb +309 -231
- data/lib/temporalio/client/connection/operator_service.rb +36 -84
- data/lib/temporalio/client/connection/service.rb +6 -5
- data/lib/temporalio/client/connection/test_service.rb +111 -0
- data/lib/temporalio/client/connection/workflow_service.rb +264 -441
- data/lib/temporalio/client/connection.rb +90 -44
- data/lib/temporalio/client/interceptor.rb +160 -60
- data/lib/temporalio/client/schedule.rb +967 -0
- data/lib/temporalio/client/schedule_handle.rb +126 -0
- data/lib/temporalio/client/workflow_execution.rb +7 -10
- data/lib/temporalio/client/workflow_handle.rb +38 -95
- data/lib/temporalio/client/workflow_update_handle.rb +3 -5
- data/lib/temporalio/client.rb +122 -42
- data/lib/temporalio/common_enums.rb +17 -0
- data/lib/temporalio/converters/data_converter.rb +4 -7
- data/lib/temporalio/converters/failure_converter.rb +5 -3
- data/lib/temporalio/converters/payload_converter/composite.rb +4 -0
- data/lib/temporalio/converters/payload_converter.rb +6 -8
- data/lib/temporalio/converters/raw_value.rb +20 -0
- data/lib/temporalio/error/failure.rb +1 -1
- data/lib/temporalio/error.rb +10 -2
- data/lib/temporalio/internal/bridge/3.2/temporalio_bridge.so +0 -0
- data/lib/temporalio/internal/bridge/3.3/temporalio_bridge.so +0 -0
- data/lib/temporalio/internal/bridge/{3.1 → 3.4}/temporalio_bridge.so +0 -0
- data/lib/temporalio/internal/bridge/api/core_interface.rb +5 -1
- data/lib/temporalio/internal/bridge/api/nexus/nexus.rb +33 -0
- data/lib/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rb +5 -1
- data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +4 -1
- data/lib/temporalio/internal/bridge/client.rb +11 -6
- data/lib/temporalio/internal/bridge/testing.rb +20 -0
- data/lib/temporalio/internal/bridge/worker.rb +2 -0
- data/lib/temporalio/internal/bridge.rb +1 -1
- data/lib/temporalio/internal/client/implementation.rb +245 -70
- data/lib/temporalio/internal/metric.rb +122 -0
- data/lib/temporalio/internal/proto_utils.rb +86 -7
- data/lib/temporalio/internal/worker/activity_worker.rb +52 -24
- data/lib/temporalio/internal/worker/multi_runner.rb +51 -7
- data/lib/temporalio/internal/worker/workflow_instance/child_workflow_handle.rb +54 -0
- data/lib/temporalio/internal/worker/workflow_instance/context.rb +329 -0
- data/lib/temporalio/internal/worker/workflow_instance/details.rb +44 -0
- data/lib/temporalio/internal/worker/workflow_instance/external_workflow_handle.rb +32 -0
- data/lib/temporalio/internal/worker/workflow_instance/externally_immutable_hash.rb +22 -0
- data/lib/temporalio/internal/worker/workflow_instance/handler_execution.rb +25 -0
- data/lib/temporalio/internal/worker/workflow_instance/handler_hash.rb +41 -0
- data/lib/temporalio/internal/worker/workflow_instance/illegal_call_tracer.rb +97 -0
- data/lib/temporalio/internal/worker/workflow_instance/inbound_implementation.rb +62 -0
- data/lib/temporalio/internal/worker/workflow_instance/outbound_implementation.rb +415 -0
- data/lib/temporalio/internal/worker/workflow_instance/replay_safe_logger.rb +37 -0
- data/lib/temporalio/internal/worker/workflow_instance/replay_safe_metric.rb +40 -0
- data/lib/temporalio/internal/worker/workflow_instance/scheduler.rb +163 -0
- data/lib/temporalio/internal/worker/workflow_instance.rb +730 -0
- data/lib/temporalio/internal/worker/workflow_worker.rb +196 -0
- data/lib/temporalio/metric.rb +109 -0
- data/lib/temporalio/retry_policy.rb +37 -14
- data/lib/temporalio/runtime.rb +118 -75
- data/lib/temporalio/search_attributes.rb +80 -37
- data/lib/temporalio/testing/activity_environment.rb +2 -2
- data/lib/temporalio/testing/workflow_environment.rb +251 -5
- data/lib/temporalio/version.rb +1 -1
- data/lib/temporalio/worker/activity_executor/thread_pool.rb +9 -217
- data/lib/temporalio/worker/activity_executor.rb +3 -3
- data/lib/temporalio/worker/interceptor.rb +340 -66
- data/lib/temporalio/worker/thread_pool.rb +237 -0
- data/lib/temporalio/worker/workflow_executor/thread_pool.rb +230 -0
- data/lib/temporalio/worker/workflow_executor.rb +26 -0
- data/lib/temporalio/worker.rb +201 -30
- data/lib/temporalio/workflow/activity_cancellation_type.rb +20 -0
- data/lib/temporalio/workflow/child_workflow_cancellation_type.rb +21 -0
- data/lib/temporalio/workflow/child_workflow_handle.rb +43 -0
- data/lib/temporalio/workflow/definition.rb +566 -0
- data/lib/temporalio/workflow/external_workflow_handle.rb +41 -0
- data/lib/temporalio/workflow/future.rb +151 -0
- data/lib/temporalio/workflow/handler_unfinished_policy.rb +13 -0
- data/lib/temporalio/workflow/info.rb +82 -0
- data/lib/temporalio/workflow/parent_close_policy.rb +19 -0
- data/lib/temporalio/workflow/update_info.rb +20 -0
- data/lib/temporalio/workflow.rb +523 -0
- data/lib/temporalio.rb +4 -0
- data/temporalio.gemspec +2 -2
- metadata +52 -6
@@ -0,0 +1,122 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'singleton'
|
4
|
+
require 'temporalio/internal/bridge'
|
5
|
+
require 'temporalio/metric'
|
6
|
+
|
7
|
+
module Temporalio
|
8
|
+
module Internal
|
9
|
+
class Metric < Temporalio::Metric
|
10
|
+
attr_reader :metric_type, :name, :description, :unit, :value_type
|
11
|
+
|
12
|
+
def initialize(metric_type:, name:, description:, unit:, value_type:, bridge:, bridge_attrs:) # rubocop:disable Lint/MissingSuper
|
13
|
+
@metric_type = metric_type
|
14
|
+
@name = name
|
15
|
+
@description = description
|
16
|
+
@unit = unit
|
17
|
+
@value_type = value_type
|
18
|
+
@bridge = bridge
|
19
|
+
@bridge_attrs = bridge_attrs
|
20
|
+
end
|
21
|
+
|
22
|
+
def record(value, additional_attributes: nil)
|
23
|
+
bridge_attrs = @bridge_attrs
|
24
|
+
bridge_attrs = @bridge_attrs.with_additional(additional_attributes) if additional_attributes
|
25
|
+
@bridge.record_value(value, bridge_attrs)
|
26
|
+
end
|
27
|
+
|
28
|
+
def with_additional_attributes(additional_attributes)
|
29
|
+
Metric.new(
|
30
|
+
metric_type:,
|
31
|
+
name:,
|
32
|
+
description:,
|
33
|
+
unit:,
|
34
|
+
value_type:,
|
35
|
+
bridge: @bridge,
|
36
|
+
bridge_attrs: @bridge_attrs.with_additional(additional_attributes)
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
class Meter < Temporalio::Metric::Meter
|
41
|
+
def self.create_from_runtime(runtime)
|
42
|
+
bridge = Bridge::Metric::Meter.new(runtime._core_runtime)
|
43
|
+
return nil unless bridge
|
44
|
+
|
45
|
+
Meter.new(bridge, bridge.default_attributes)
|
46
|
+
end
|
47
|
+
|
48
|
+
def initialize(bridge, bridge_attrs) # rubocop:disable Lint/MissingSuper
|
49
|
+
@bridge = bridge
|
50
|
+
@bridge_attrs = bridge_attrs
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_metric(
|
54
|
+
metric_type,
|
55
|
+
name,
|
56
|
+
description: nil,
|
57
|
+
unit: nil,
|
58
|
+
value_type: :integer
|
59
|
+
)
|
60
|
+
Metric.new(
|
61
|
+
metric_type:,
|
62
|
+
name:,
|
63
|
+
description:,
|
64
|
+
unit:,
|
65
|
+
value_type:,
|
66
|
+
bridge: Bridge::Metric.new(@bridge, metric_type, name, description, unit, value_type),
|
67
|
+
bridge_attrs: @bridge_attrs
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
71
|
+
def with_additional_attributes(additional_attributes)
|
72
|
+
Meter.new(@bridge, @bridge_attrs.with_additional(additional_attributes))
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class NullMeter < Temporalio::Metric::Meter
|
77
|
+
include Singleton
|
78
|
+
|
79
|
+
def initialize # rubocop:disable Style/RedundantInitialize,Lint/MissingSuper
|
80
|
+
end
|
81
|
+
|
82
|
+
def create_metric(
|
83
|
+
metric_type,
|
84
|
+
name,
|
85
|
+
description: nil,
|
86
|
+
unit: nil,
|
87
|
+
value_type: :integer
|
88
|
+
)
|
89
|
+
NullMetric.new(
|
90
|
+
metric_type:,
|
91
|
+
name:,
|
92
|
+
description:,
|
93
|
+
unit:,
|
94
|
+
value_type:
|
95
|
+
)
|
96
|
+
end
|
97
|
+
|
98
|
+
def with_additional_attributes(_additional_attributes)
|
99
|
+
self
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
class NullMetric < Temporalio::Metric
|
104
|
+
attr_reader :metric_type, :name, :description, :unit, :value_type
|
105
|
+
|
106
|
+
def initialize(metric_type:, name:, description:, unit:, value_type:) # rubocop:disable Lint/MissingSuper
|
107
|
+
@metric_type = metric_type
|
108
|
+
@name = name
|
109
|
+
@description = description
|
110
|
+
@unit = unit
|
111
|
+
@value_type = value_type
|
112
|
+
end
|
113
|
+
|
114
|
+
def record(value, additional_attributes: nil); end
|
115
|
+
|
116
|
+
def with_additional_attributes(_additional_attributes)
|
117
|
+
self
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -5,26 +5,82 @@ require 'temporalio/api'
|
|
5
5
|
module Temporalio
|
6
6
|
module Internal
|
7
7
|
module ProtoUtils
|
8
|
-
def self.seconds_to_duration(
|
9
|
-
return nil if
|
8
|
+
def self.seconds_to_duration(seconds_numeric)
|
9
|
+
return nil if seconds_numeric.nil?
|
10
10
|
|
11
|
-
seconds =
|
12
|
-
nanos = ((
|
11
|
+
seconds = seconds_numeric.to_i
|
12
|
+
nanos = ((seconds_numeric - seconds) * 1_000_000_000).round
|
13
13
|
Google::Protobuf::Duration.new(seconds:, nanos:)
|
14
14
|
end
|
15
15
|
|
16
|
+
def self.duration_to_seconds(duration)
|
17
|
+
return nil if duration.nil?
|
18
|
+
|
19
|
+
# This logic was corrected for timestamp at
|
20
|
+
# https://github.com/protocolbuffers/protobuf/pull/2482 but not for
|
21
|
+
# duration, so 4.56 is not properly represented in to_f, it becomes
|
22
|
+
# 4.5600000000000005.
|
23
|
+
(duration.seconds + duration.nanos.quo(1_000_000_000)).to_f
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.time_to_timestamp(time)
|
27
|
+
return nil if time.nil?
|
28
|
+
|
29
|
+
Google::Protobuf::Timestamp.from_time(time)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.timestamp_to_time(timestamp)
|
33
|
+
return nil if timestamp.nil?
|
34
|
+
|
35
|
+
# The regular to_time on the timestamp converts to local timezone,
|
36
|
+
# and we prefer not to make a separate .utc call (converts to local
|
37
|
+
# then back to UTC unnecessarily)
|
38
|
+
Time.at(timestamp.seconds, timestamp.nanos, :nanosecond, in: 'UTC')
|
39
|
+
end
|
40
|
+
|
16
41
|
def self.memo_to_proto(hash, converter)
|
17
|
-
return nil if hash.nil?
|
42
|
+
return nil if hash.nil? || hash.empty?
|
43
|
+
|
44
|
+
Api::Common::V1::Memo.new(fields: memo_to_proto_hash(hash, converter))
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.memo_to_proto_hash(hash, converter)
|
48
|
+
return nil if hash.nil? || hash.empty?
|
18
49
|
|
19
|
-
|
50
|
+
hash.transform_keys(&:to_s).transform_values { |val| converter.to_payload(val) }
|
20
51
|
end
|
21
52
|
|
22
53
|
def self.memo_from_proto(memo, converter)
|
23
|
-
return nil if memo.nil?
|
54
|
+
return nil if memo.nil? || memo.fields.size.zero? # rubocop:disable Style/ZeroLengthPredicate Google Maps don't have empty
|
24
55
|
|
25
56
|
memo.fields.each_with_object({}) { |(key, val), h| h[key] = converter.from_payload(val) } # rubocop:disable Style/HashTransformValues
|
26
57
|
end
|
27
58
|
|
59
|
+
def self.headers_to_proto(headers, converter)
|
60
|
+
return nil if headers.nil? || headers.empty?
|
61
|
+
|
62
|
+
Api::Common::V1::Header.new(fields: headers_to_proto_hash(headers, converter))
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.headers_to_proto_hash(headers, converter)
|
66
|
+
return nil if headers.nil? || headers.empty?
|
67
|
+
|
68
|
+
headers.transform_values { |val| converter.to_payload(val) }
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.headers_from_proto(headers, converter)
|
72
|
+
headers_from_proto_map(headers&.fields, converter)
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.headers_from_proto_map(headers, converter)
|
76
|
+
return nil if headers.nil? || headers.size.zero? # rubocop:disable Style/ZeroLengthPredicate Google Maps don't have empty
|
77
|
+
|
78
|
+
headers.each_with_object({}) do |(key, val), h| # rubocop:disable Style/HashTransformValues
|
79
|
+
# @type var h: Hash[String, Object?]
|
80
|
+
h[key] = converter.from_payload(val)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
28
84
|
def self.string_or(str, default = nil)
|
29
85
|
str && !str.empty? ? str : default
|
30
86
|
end
|
@@ -49,6 +105,29 @@ module Temporalio
|
|
49
105
|
|
50
106
|
converter.to_payloads(values).payloads.to_ary
|
51
107
|
end
|
108
|
+
|
109
|
+
class LazyMemo
|
110
|
+
def initialize(raw_memo, converter)
|
111
|
+
@raw_memo = raw_memo
|
112
|
+
@converter = converter
|
113
|
+
end
|
114
|
+
|
115
|
+
def get
|
116
|
+
@memo = ProtoUtils.memo_from_proto(@raw_memo, @converter) unless defined?(@memo)
|
117
|
+
@memo
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
class LazySearchAttributes
|
122
|
+
def initialize(raw_search_attributes)
|
123
|
+
@raw_search_attributes = raw_search_attributes
|
124
|
+
end
|
125
|
+
|
126
|
+
def get
|
127
|
+
@search_attributes = SearchAttributes._from_proto(@raw_search_attributes) unless defined?(@search_attributes)
|
128
|
+
@search_attributes
|
129
|
+
end
|
130
|
+
end
|
52
131
|
end
|
53
132
|
end
|
54
133
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'temporalio/activity'
|
4
4
|
require 'temporalio/activity/definition'
|
5
5
|
require 'temporalio/cancellation'
|
6
|
+
require 'temporalio/converters/raw_value'
|
6
7
|
require 'temporalio/internal/bridge/api'
|
7
8
|
require 'temporalio/internal/proto_utils'
|
8
9
|
require 'temporalio/scoped_logger'
|
@@ -11,14 +12,17 @@ require 'temporalio/worker/interceptor'
|
|
11
12
|
module Temporalio
|
12
13
|
module Internal
|
13
14
|
module Worker
|
15
|
+
# Worker for handling activity tasks. Upon overarching worker shutdown, {wait_all_complete} should be used to wait
|
16
|
+
# for the activities to complete.
|
14
17
|
class ActivityWorker
|
15
18
|
LOG_TASKS = false
|
16
19
|
|
17
20
|
attr_reader :worker, :bridge_worker
|
18
21
|
|
19
|
-
def initialize(worker
|
22
|
+
def initialize(worker:, bridge_worker:)
|
20
23
|
@worker = worker
|
21
24
|
@bridge_worker = bridge_worker
|
25
|
+
@runtime_metric_meter = worker.options.client.connection.options.runtime.metric_meter
|
22
26
|
|
23
27
|
# Create shared logger that gives scoped activity details
|
24
28
|
@scoped_logger = ScopedLogger.new(@worker.options.logger)
|
@@ -26,12 +30,13 @@ module Temporalio
|
|
26
30
|
Activity::Context.current_or_nil&._scoped_logger_info
|
27
31
|
}
|
28
32
|
|
29
|
-
# Build up activity hash by name, failing if any fail validation
|
33
|
+
# Build up activity hash by name (can be nil for dynamic), failing if any fail validation
|
30
34
|
@activities = worker.options.activities.each_with_object({}) do |act, hash|
|
31
35
|
# Class means create each time, instance means just call, definition
|
32
36
|
# does nothing special
|
33
|
-
defn = Activity::Definition.from_activity(act)
|
37
|
+
defn = Activity::Definition::Info.from_activity(act)
|
34
38
|
# Confirm name not in use
|
39
|
+
raise ArgumentError, 'Only one dynamic activity allowed' if !defn.name && hash.key?(defn.name)
|
35
40
|
raise ArgumentError, "Multiple activities named #{defn.name}" if hash.key?(defn.name)
|
36
41
|
|
37
42
|
# Confirm executor is a known executor and let it initialize
|
@@ -88,8 +93,8 @@ module Temporalio
|
|
88
93
|
def handle_start_task(task_token, start)
|
89
94
|
set_running_activity(task_token, nil)
|
90
95
|
|
91
|
-
# Find activity definition
|
92
|
-
defn = @activities[start.activity_type]
|
96
|
+
# Find activity definition, falling back to dynamic if present
|
97
|
+
defn = @activities[start.activity_type] || @activities[nil]
|
93
98
|
if defn.nil?
|
94
99
|
raise Error::ApplicationError.new(
|
95
100
|
"Activity #{start.activity_type} for workflow #{start.workflow_execution.workflow_id} " \
|
@@ -158,17 +163,19 @@ module Temporalio
|
|
158
163
|
activity_id: start.activity_id,
|
159
164
|
activity_type: start.activity_type,
|
160
165
|
attempt: start.attempt,
|
161
|
-
current_attempt_scheduled_time:
|
166
|
+
current_attempt_scheduled_time: Internal::ProtoUtils.timestamp_to_time(
|
167
|
+
start.current_attempt_scheduled_time
|
168
|
+
) || raise, # Never nil
|
162
169
|
heartbeat_details: ProtoUtils.convert_from_payload_array(
|
163
170
|
@worker.options.client.data_converter,
|
164
171
|
start.heartbeat_details.to_ary
|
165
172
|
),
|
166
|
-
heartbeat_timeout: start.heartbeat_timeout
|
173
|
+
heartbeat_timeout: Internal::ProtoUtils.duration_to_seconds(start.heartbeat_timeout),
|
167
174
|
local?: start.is_local,
|
168
|
-
schedule_to_close_timeout: start.schedule_to_close_timeout
|
169
|
-
scheduled_time: start.scheduled_time
|
170
|
-
start_to_close_timeout: start.start_to_close_timeout
|
171
|
-
started_time: start.started_time
|
175
|
+
schedule_to_close_timeout: Internal::ProtoUtils.duration_to_seconds(start.schedule_to_close_timeout),
|
176
|
+
scheduled_time: Internal::ProtoUtils.timestamp_to_time(start.scheduled_time) || raise, # Never nil
|
177
|
+
start_to_close_timeout: Internal::ProtoUtils.duration_to_seconds(start.start_to_close_timeout),
|
178
|
+
started_time: Internal::ProtoUtils.timestamp_to_time(start.started_time) || raise, # Never nil
|
172
179
|
task_queue: @worker.options.task_queue,
|
173
180
|
task_token:,
|
174
181
|
workflow_id: start.workflow_execution.workflow_id,
|
@@ -178,13 +185,18 @@ module Temporalio
|
|
178
185
|
).freeze
|
179
186
|
|
180
187
|
# Build input
|
181
|
-
input = Temporalio::Worker::Interceptor::
|
188
|
+
input = Temporalio::Worker::Interceptor::Activity::ExecuteInput.new(
|
182
189
|
proc: defn.proc,
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
190
|
+
# If the activity wants raw_args, we only decode we don't convert
|
191
|
+
args: if defn.raw_args
|
192
|
+
payloads = start.input.to_ary
|
193
|
+
codec = @worker.options.client.data_converter.payload_codec
|
194
|
+
payloads = codec.decode(payloads) if codec
|
195
|
+
payloads.map { |p| Temporalio::Converters::RawValue.new(p) }
|
196
|
+
else
|
197
|
+
ProtoUtils.convert_from_payload_array(@worker.options.client.data_converter, start.input.to_ary)
|
198
|
+
end,
|
199
|
+
headers: ProtoUtils.headers_from_proto_map(start.header_fields, @worker.options.client.data_converter) || {}
|
188
200
|
)
|
189
201
|
|
190
202
|
# Run
|
@@ -193,7 +205,8 @@ module Temporalio
|
|
193
205
|
cancellation: Cancellation.new,
|
194
206
|
worker_shutdown_cancellation: @worker._worker_shutdown_cancellation,
|
195
207
|
payload_converter: @worker.options.client.data_converter.payload_converter,
|
196
|
-
logger: @scoped_logger
|
208
|
+
logger: @scoped_logger,
|
209
|
+
runtime_metric_meter: @runtime_metric_meter
|
197
210
|
)
|
198
211
|
Activity::Context._current_executor&.set_activity_context(defn, activity)
|
199
212
|
set_running_activity(task_token, activity)
|
@@ -226,9 +239,9 @@ module Temporalio
|
|
226
239
|
def run_activity(activity, input)
|
227
240
|
result = begin
|
228
241
|
# Build impl with interceptors
|
229
|
-
# @type var impl: Temporalio::Worker::Interceptor::
|
242
|
+
# @type var impl: Temporalio::Worker::Interceptor::Activity::Inbound
|
230
243
|
impl = InboundImplementation.new(self)
|
231
|
-
impl = @worker.
|
244
|
+
impl = @worker._activity_interceptors.reverse_each.reduce(impl) do |acc, int|
|
232
245
|
int.intercept_activity(acc)
|
233
246
|
end
|
234
247
|
impl.init(OutboundImplementation.new(self))
|
@@ -287,13 +300,15 @@ module Temporalio
|
|
287
300
|
cancellation:,
|
288
301
|
worker_shutdown_cancellation:,
|
289
302
|
payload_converter:,
|
290
|
-
logger
|
303
|
+
logger:,
|
304
|
+
runtime_metric_meter:
|
291
305
|
)
|
292
306
|
@info = info
|
293
307
|
@cancellation = cancellation
|
294
308
|
@worker_shutdown_cancellation = worker_shutdown_cancellation
|
295
309
|
@payload_converter = payload_converter
|
296
310
|
@logger = logger
|
311
|
+
@runtime_metric_meter = runtime_metric_meter
|
297
312
|
@_outbound_impl = nil
|
298
313
|
@_server_requested_cancel = false
|
299
314
|
end
|
@@ -301,11 +316,24 @@ module Temporalio
|
|
301
316
|
def heartbeat(*details)
|
302
317
|
raise 'Implementation not set yet' if _outbound_impl.nil?
|
303
318
|
|
304
|
-
|
319
|
+
# No-op if local
|
320
|
+
return if info.local?
|
321
|
+
|
322
|
+
_outbound_impl.heartbeat(Temporalio::Worker::Interceptor::Activity::HeartbeatInput.new(details:))
|
323
|
+
end
|
324
|
+
|
325
|
+
def metric_meter
|
326
|
+
@metric_meter ||= @runtime_metric_meter.with_additional_attributes(
|
327
|
+
{
|
328
|
+
namespace: info.workflow_namespace,
|
329
|
+
task_queue: info.task_queue,
|
330
|
+
activity_type: info.activity_type
|
331
|
+
}
|
332
|
+
)
|
305
333
|
end
|
306
334
|
end
|
307
335
|
|
308
|
-
class InboundImplementation < Temporalio::Worker::Interceptor::
|
336
|
+
class InboundImplementation < Temporalio::Worker::Interceptor::Activity::Inbound
|
309
337
|
def initialize(worker)
|
310
338
|
super(nil) # steep:ignore
|
311
339
|
@worker = worker
|
@@ -323,7 +351,7 @@ module Temporalio
|
|
323
351
|
end
|
324
352
|
end
|
325
353
|
|
326
|
-
class OutboundImplementation < Temporalio::Worker::Interceptor::
|
354
|
+
class OutboundImplementation < Temporalio::Worker::Interceptor::Activity::Outbound
|
327
355
|
def initialize(worker)
|
328
356
|
super(nil) # steep:ignore
|
329
357
|
@worker = worker
|
@@ -6,6 +6,8 @@ require 'temporalio/internal/bridge/worker'
|
|
6
6
|
module Temporalio
|
7
7
|
module Internal
|
8
8
|
module Worker
|
9
|
+
# Primary worker (re)actor-style event handler. This handles multiple workers, receiving events from the bridge,
|
10
|
+
# and handling a user block.
|
9
11
|
class MultiRunner
|
10
12
|
def initialize(workers:, shutdown_signals:)
|
11
13
|
@workers = workers
|
@@ -47,6 +49,16 @@ module Temporalio
|
|
47
49
|
end
|
48
50
|
end
|
49
51
|
|
52
|
+
def apply_workflow_activation_decoded(workflow_worker:, activation:)
|
53
|
+
@queue.push(Event::WorkflowActivationDecoded.new(workflow_worker:, activation:))
|
54
|
+
end
|
55
|
+
|
56
|
+
def apply_workflow_activation_complete(workflow_worker:, activation_completion:, encoded:)
|
57
|
+
@queue.push(Event::WorkflowActivationComplete.new(
|
58
|
+
workflow_worker:, activation_completion:, encoded:, completion_complete_queue: @queue
|
59
|
+
))
|
60
|
+
end
|
61
|
+
|
50
62
|
def raise_in_thread_or_fiber_block(error)
|
51
63
|
@thread_or_fiber&.raise(error)
|
52
64
|
end
|
@@ -80,22 +92,25 @@ module Temporalio
|
|
80
92
|
# * [worker index, :activity/:workflow, error] - poll fail
|
81
93
|
# * [worker index, :activity/:workflow, nil] - worker shutdown
|
82
94
|
# * [nil, nil, nil] - all pollers done
|
95
|
+
# * [-1, run_id_string, error_or_nil] - workflow activation completion complete
|
83
96
|
result = @queue.pop
|
84
97
|
if result.is_a?(Event)
|
85
98
|
result
|
86
99
|
else
|
87
|
-
|
88
|
-
if
|
100
|
+
first, second, third = result
|
101
|
+
if first.nil? || second.nil?
|
89
102
|
Event::AllPollersShutDown.instance
|
103
|
+
elsif first == -1
|
104
|
+
Event::WorkflowActivationCompletionComplete.new(run_id: second, error: third)
|
90
105
|
else
|
91
|
-
worker = @workers[
|
92
|
-
case
|
106
|
+
worker = @workers[first]
|
107
|
+
case third
|
93
108
|
when nil
|
94
|
-
Event::PollerShutDown.new(worker:, worker_type:)
|
109
|
+
Event::PollerShutDown.new(worker:, worker_type: second)
|
95
110
|
when Exception
|
96
|
-
Event::PollFailure.new(worker:, worker_type
|
111
|
+
Event::PollFailure.new(worker:, worker_type: second, error: third)
|
97
112
|
else
|
98
|
-
Event::PollSuccess.new(worker:, worker_type
|
113
|
+
Event::PollSuccess.new(worker:, worker_type: second, bytes: third)
|
99
114
|
end
|
100
115
|
end
|
101
116
|
end
|
@@ -122,6 +137,35 @@ module Temporalio
|
|
122
137
|
end
|
123
138
|
end
|
124
139
|
|
140
|
+
class WorkflowActivationDecoded < Event
|
141
|
+
attr_reader :workflow_worker, :activation
|
142
|
+
|
143
|
+
def initialize(workflow_worker:, activation:) # rubocop:disable Lint/MissingSuper
|
144
|
+
@workflow_worker = workflow_worker
|
145
|
+
@activation = activation
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
class WorkflowActivationComplete < Event
|
150
|
+
attr_reader :workflow_worker, :activation_completion, :encoded, :completion_complete_queue
|
151
|
+
|
152
|
+
def initialize(workflow_worker:, activation_completion:, encoded:, completion_complete_queue:) # rubocop:disable Lint/MissingSuper
|
153
|
+
@workflow_worker = workflow_worker
|
154
|
+
@activation_completion = activation_completion
|
155
|
+
@encoded = encoded
|
156
|
+
@completion_complete_queue = completion_complete_queue
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
class WorkflowActivationCompletionComplete < Event
|
161
|
+
attr_reader :run_id, :error
|
162
|
+
|
163
|
+
def initialize(run_id:, error:) # rubocop:disable Lint/MissingSuper
|
164
|
+
@run_id = run_id
|
165
|
+
@error = error
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
125
169
|
class PollerShutDown < Event
|
126
170
|
attr_reader :worker, :worker_type
|
127
171
|
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'temporalio/cancellation'
|
4
|
+
require 'temporalio/workflow'
|
5
|
+
require 'temporalio/workflow/child_workflow_handle'
|
6
|
+
|
7
|
+
module Temporalio
|
8
|
+
module Internal
|
9
|
+
module Worker
|
10
|
+
class WorkflowInstance
|
11
|
+
# Implementation of the child workflow handle.
|
12
|
+
class ChildWorkflowHandle < Workflow::ChildWorkflowHandle
|
13
|
+
attr_reader :id, :first_execution_run_id
|
14
|
+
|
15
|
+
def initialize(id:, first_execution_run_id:, instance:, cancellation:, cancel_callback_key:) # rubocop:disable Lint/MissingSuper
|
16
|
+
@id = id
|
17
|
+
@first_execution_run_id = first_execution_run_id
|
18
|
+
@instance = instance
|
19
|
+
@cancellation = cancellation
|
20
|
+
@cancel_callback_key = cancel_callback_key
|
21
|
+
@resolution = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def result
|
25
|
+
# Notice that we actually provide a detached cancellation here instead of defaulting to workflow
|
26
|
+
# cancellation because we don't want workflow cancellation (or a user-provided cancellation to this result
|
27
|
+
# call) to be able to interrupt waiting on a child that may be processing the cancellation.
|
28
|
+
Workflow.wait_condition(cancellation: Cancellation.new) { @resolution }
|
29
|
+
|
30
|
+
case @resolution.status
|
31
|
+
when :completed
|
32
|
+
@instance.payload_converter.from_payload(@resolution.completed.result)
|
33
|
+
when :failed
|
34
|
+
raise @instance.failure_converter.from_failure(@resolution.failed.failure, @instance.payload_converter)
|
35
|
+
when :cancelled
|
36
|
+
raise @instance.failure_converter.from_failure(@resolution.cancelled.failure, @instance.payload_converter)
|
37
|
+
else
|
38
|
+
raise "Unrecognized resolution status: #{@resolution.status}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def _resolve(resolution)
|
43
|
+
@cancellation.remove_cancel_callback(@cancel_callback_key)
|
44
|
+
@resolution = resolution
|
45
|
+
end
|
46
|
+
|
47
|
+
def signal(signal, *args, cancellation: Workflow.cancellation)
|
48
|
+
@instance.context._signal_child_workflow(id:, signal:, args:, cancellation:)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|