amit-temporalio 0.3.0-aarch64-linux-musl
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 +7 -0
- data/.yardopts +2 -0
- data/Gemfile +23 -0
- data/Rakefile +101 -0
- data/lib/temporalio/activity/complete_async_error.rb +11 -0
- data/lib/temporalio/activity/context.rb +116 -0
- data/lib/temporalio/activity/definition.rb +189 -0
- data/lib/temporalio/activity/info.rb +64 -0
- data/lib/temporalio/activity.rb +12 -0
- data/lib/temporalio/api/activity/v1/message.rb +25 -0
- data/lib/temporalio/api/batch/v1/message.rb +31 -0
- data/lib/temporalio/api/cloud/account/v1/message.rb +28 -0
- data/lib/temporalio/api/cloud/cloudservice/v1/request_response.rb +126 -0
- data/lib/temporalio/api/cloud/cloudservice/v1/service.rb +25 -0
- data/lib/temporalio/api/cloud/cloudservice.rb +3 -0
- data/lib/temporalio/api/cloud/identity/v1/message.rb +41 -0
- data/lib/temporalio/api/cloud/namespace/v1/message.rb +42 -0
- data/lib/temporalio/api/cloud/nexus/v1/message.rb +31 -0
- data/lib/temporalio/api/cloud/operation/v1/message.rb +28 -0
- data/lib/temporalio/api/cloud/region/v1/message.rb +24 -0
- 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/command/v1/message.rb +46 -0
- data/lib/temporalio/api/common/v1/grpc_status.rb +23 -0
- data/lib/temporalio/api/common/v1/message.rb +47 -0
- data/lib/temporalio/api/enums/v1/batch_operation.rb +22 -0
- data/lib/temporalio/api/enums/v1/command_type.rb +21 -0
- data/lib/temporalio/api/enums/v1/common.rb +26 -0
- data/lib/temporalio/api/enums/v1/event_type.rb +21 -0
- data/lib/temporalio/api/enums/v1/failed_cause.rb +26 -0
- data/lib/temporalio/api/enums/v1/namespace.rb +23 -0
- data/lib/temporalio/api/enums/v1/query.rb +22 -0
- data/lib/temporalio/api/enums/v1/reset.rb +23 -0
- data/lib/temporalio/api/enums/v1/schedule.rb +21 -0
- data/lib/temporalio/api/enums/v1/task_queue.rb +25 -0
- data/lib/temporalio/api/enums/v1/update.rb +22 -0
- data/lib/temporalio/api/enums/v1/workflow.rb +30 -0
- data/lib/temporalio/api/errordetails/v1/message.rb +42 -0
- data/lib/temporalio/api/export/v1/message.rb +24 -0
- data/lib/temporalio/api/failure/v1/message.rb +35 -0
- data/lib/temporalio/api/filter/v1/message.rb +27 -0
- data/lib/temporalio/api/history/v1/message.rb +90 -0
- data/lib/temporalio/api/namespace/v1/message.rb +31 -0
- data/lib/temporalio/api/nexus/v1/message.rb +40 -0
- data/lib/temporalio/api/operatorservice/v1/request_response.rb +49 -0
- data/lib/temporalio/api/operatorservice/v1/service.rb +23 -0
- data/lib/temporalio/api/operatorservice.rb +3 -0
- data/lib/temporalio/api/payload_visitor.rb +1513 -0
- data/lib/temporalio/api/protocol/v1/message.rb +23 -0
- data/lib/temporalio/api/query/v1/message.rb +27 -0
- data/lib/temporalio/api/replication/v1/message.rb +26 -0
- data/lib/temporalio/api/schedule/v1/message.rb +43 -0
- data/lib/temporalio/api/sdk/v1/enhanced_stack_trace.rb +25 -0
- data/lib/temporalio/api/sdk/v1/task_complete_metadata.rb +21 -0
- data/lib/temporalio/api/sdk/v1/user_metadata.rb +23 -0
- data/lib/temporalio/api/sdk/v1/workflow_metadata.rb +23 -0
- data/lib/temporalio/api/taskqueue/v1/message.rb +45 -0
- 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/update/v1/message.rb +33 -0
- data/lib/temporalio/api/version/v1/message.rb +26 -0
- data/lib/temporalio/api/workflow/v1/message.rb +43 -0
- data/lib/temporalio/api/workflowservice/v1/request_response.rb +204 -0
- data/lib/temporalio/api/workflowservice/v1/service.rb +23 -0
- data/lib/temporalio/api/workflowservice.rb +3 -0
- data/lib/temporalio/api.rb +14 -0
- data/lib/temporalio/cancellation.rb +170 -0
- data/lib/temporalio/client/activity_id_reference.rb +32 -0
- data/lib/temporalio/client/async_activity_handle.rb +85 -0
- data/lib/temporalio/client/connection/cloud_service.rb +726 -0
- data/lib/temporalio/client/connection/operator_service.rb +201 -0
- data/lib/temporalio/client/connection/service.rb +42 -0
- data/lib/temporalio/client/connection/test_service.rb +111 -0
- data/lib/temporalio/client/connection/workflow_service.rb +1041 -0
- data/lib/temporalio/client/connection.rb +316 -0
- data/lib/temporalio/client/interceptor.rb +416 -0
- data/lib/temporalio/client/schedule.rb +967 -0
- data/lib/temporalio/client/schedule_handle.rb +126 -0
- data/lib/temporalio/client/workflow_execution.rb +100 -0
- data/lib/temporalio/client/workflow_execution_count.rb +36 -0
- data/lib/temporalio/client/workflow_execution_status.rb +18 -0
- data/lib/temporalio/client/workflow_handle.rb +389 -0
- data/lib/temporalio/client/workflow_query_reject_condition.rb +14 -0
- data/lib/temporalio/client/workflow_update_handle.rb +65 -0
- data/lib/temporalio/client/workflow_update_wait_stage.rb +17 -0
- data/lib/temporalio/client.rb +484 -0
- data/lib/temporalio/common_enums.rb +41 -0
- data/lib/temporalio/converters/data_converter.rb +99 -0
- data/lib/temporalio/converters/failure_converter.rb +202 -0
- data/lib/temporalio/converters/payload_codec.rb +26 -0
- data/lib/temporalio/converters/payload_converter/binary_null.rb +34 -0
- data/lib/temporalio/converters/payload_converter/binary_plain.rb +35 -0
- data/lib/temporalio/converters/payload_converter/binary_protobuf.rb +42 -0
- data/lib/temporalio/converters/payload_converter/composite.rb +66 -0
- data/lib/temporalio/converters/payload_converter/encoding.rb +35 -0
- data/lib/temporalio/converters/payload_converter/json_plain.rb +44 -0
- data/lib/temporalio/converters/payload_converter/json_protobuf.rb +41 -0
- data/lib/temporalio/converters/payload_converter.rb +71 -0
- data/lib/temporalio/converters/raw_value.rb +20 -0
- data/lib/temporalio/converters.rb +9 -0
- data/lib/temporalio/error/failure.rb +219 -0
- data/lib/temporalio/error.rb +155 -0
- data/lib/temporalio/internal/bridge/api/activity_result/activity_result.rb +34 -0
- data/lib/temporalio/internal/bridge/api/activity_task/activity_task.rb +31 -0
- data/lib/temporalio/internal/bridge/api/child_workflow/child_workflow.rb +33 -0
- data/lib/temporalio/internal/bridge/api/common/common.rb +26 -0
- data/lib/temporalio/internal/bridge/api/core_interface.rb +40 -0
- data/lib/temporalio/internal/bridge/api/external_data/external_data.rb +27 -0
- data/lib/temporalio/internal/bridge/api/nexus/nexus.rb +33 -0
- data/lib/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rb +56 -0
- data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +57 -0
- data/lib/temporalio/internal/bridge/api/workflow_completion/workflow_completion.rb +30 -0
- data/lib/temporalio/internal/bridge/api.rb +3 -0
- data/lib/temporalio/internal/bridge/client.rb +95 -0
- data/lib/temporalio/internal/bridge/runtime.rb +53 -0
- data/lib/temporalio/internal/bridge/temporalio_bridge.so +0 -0
- data/lib/temporalio/internal/bridge/testing.rb +66 -0
- data/lib/temporalio/internal/bridge/worker.rb +85 -0
- data/lib/temporalio/internal/bridge.rb +36 -0
- data/lib/temporalio/internal/client/implementation.rb +700 -0
- data/lib/temporalio/internal/metric.rb +122 -0
- data/lib/temporalio/internal/proto_utils.rb +133 -0
- data/lib/temporalio/internal/worker/activity_worker.rb +376 -0
- data/lib/temporalio/internal/worker/multi_runner.rb +213 -0
- data/lib/temporalio/internal/worker/workflow_instance/child_workflow_handle.rb +54 -0
- data/lib/temporalio/internal/worker/workflow_instance/context.rb +333 -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 +236 -0
- data/lib/temporalio/internal.rb +7 -0
- data/lib/temporalio/metric.rb +109 -0
- data/lib/temporalio/retry_policy.rb +74 -0
- data/lib/temporalio/runtime.rb +314 -0
- data/lib/temporalio/scoped_logger.rb +96 -0
- data/lib/temporalio/search_attributes.rb +343 -0
- data/lib/temporalio/testing/activity_environment.rb +136 -0
- data/lib/temporalio/testing/workflow_environment.rb +383 -0
- data/lib/temporalio/testing.rb +10 -0
- data/lib/temporalio/version.rb +5 -0
- data/lib/temporalio/worker/activity_executor/fiber.rb +49 -0
- data/lib/temporalio/worker/activity_executor/thread_pool.rb +46 -0
- data/lib/temporalio/worker/activity_executor.rb +55 -0
- data/lib/temporalio/worker/interceptor.rb +362 -0
- data/lib/temporalio/worker/thread_pool.rb +237 -0
- data/lib/temporalio/worker/tuner.rb +189 -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/workflow_replayer.rb +343 -0
- data/lib/temporalio/worker.rb +569 -0
- 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 +529 -0
- data/lib/temporalio/workflow_history.rb +47 -0
- data/lib/temporalio.rb +11 -0
- data/temporalio.gemspec +28 -0
- metadata +236 -0
@@ -0,0 +1,236 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'temporalio/api/payload_visitor'
|
4
|
+
require 'temporalio/error'
|
5
|
+
require 'temporalio/internal/worker/workflow_instance'
|
6
|
+
require 'temporalio/scoped_logger'
|
7
|
+
require 'temporalio/workflow'
|
8
|
+
require 'temporalio/workflow/definition'
|
9
|
+
require 'timeout'
|
10
|
+
|
11
|
+
module Temporalio
|
12
|
+
module Internal
|
13
|
+
module Worker
|
14
|
+
# Worker for handling workflow activations. Most activation work is delegated to the workflow executor.
|
15
|
+
class WorkflowWorker
|
16
|
+
def self.workflow_definitions(workflows)
|
17
|
+
workflows.each_with_object({}) do |workflow, hash|
|
18
|
+
# Load definition
|
19
|
+
defn = begin
|
20
|
+
if workflow.is_a?(Workflow::Definition::Info)
|
21
|
+
workflow
|
22
|
+
else
|
23
|
+
Workflow::Definition::Info.from_class(workflow)
|
24
|
+
end
|
25
|
+
rescue StandardError
|
26
|
+
raise ArgumentError, "Failed loading workflow #{workflow}"
|
27
|
+
end
|
28
|
+
|
29
|
+
# Confirm name not in use
|
30
|
+
raise ArgumentError, "Multiple workflows named #{defn.name || '<dynamic>'}" if hash.key?(defn.name)
|
31
|
+
|
32
|
+
hash[defn.name] = defn
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.bridge_workflow_failure_exception_type_options(
|
37
|
+
workflow_failure_exception_types:,
|
38
|
+
workflow_definitions:
|
39
|
+
)
|
40
|
+
as_fail = workflow_failure_exception_types.any? do |t|
|
41
|
+
t.is_a?(Class) && t >= Workflow::NondeterminismError
|
42
|
+
end
|
43
|
+
as_fail_for_types = workflow_definitions.values.map do |defn|
|
44
|
+
next unless defn.failure_exception_types.any? { |t| t.is_a?(Class) && t >= Workflow::NondeterminismError }
|
45
|
+
|
46
|
+
# If they tried to do this on a dynamic workflow and haven't already set worker-level option, warn
|
47
|
+
unless defn.name || as_fail
|
48
|
+
warn('Note, dynamic workflows cannot trap non-determinism errors, so worker-level ' \
|
49
|
+
'workflow_failure_exception_types should be set to capture that if that is the intention')
|
50
|
+
end
|
51
|
+
defn.name
|
52
|
+
end.compact
|
53
|
+
[as_fail, as_fail_for_types]
|
54
|
+
end
|
55
|
+
|
56
|
+
def initialize(
|
57
|
+
bridge_worker:,
|
58
|
+
namespace:,
|
59
|
+
task_queue:,
|
60
|
+
workflow_definitions:,
|
61
|
+
workflow_executor:,
|
62
|
+
logger:,
|
63
|
+
data_converter:,
|
64
|
+
metric_meter:,
|
65
|
+
workflow_interceptors:,
|
66
|
+
disable_eager_activity_execution:,
|
67
|
+
illegal_workflow_calls:,
|
68
|
+
workflow_failure_exception_types:,
|
69
|
+
workflow_payload_codec_thread_pool:,
|
70
|
+
debug_mode:,
|
71
|
+
on_eviction: nil
|
72
|
+
)
|
73
|
+
@executor = workflow_executor
|
74
|
+
|
75
|
+
payload_codec = data_converter.payload_codec
|
76
|
+
@workflow_payload_codec_thread_pool = workflow_payload_codec_thread_pool
|
77
|
+
if !Fiber.current_scheduler && payload_codec && !@workflow_payload_codec_thread_pool
|
78
|
+
raise ArgumentError, 'Must have workflow payload codec thread pool if providing codec and not using fibers'
|
79
|
+
end
|
80
|
+
|
81
|
+
# If there is a payload codec, we need to build encoding and decoding visitors
|
82
|
+
if payload_codec
|
83
|
+
@payload_encoding_visitor = Api::PayloadVisitor.new(skip_search_attributes: true) do |payload_or_payloads|
|
84
|
+
apply_codec_on_payload_visit(payload_or_payloads) { |payloads| payload_codec.encode(payloads) }
|
85
|
+
end
|
86
|
+
@payload_decoding_visitor = Api::PayloadVisitor.new(skip_search_attributes: true) do |payload_or_payloads|
|
87
|
+
apply_codec_on_payload_visit(payload_or_payloads) { |payloads| payload_codec.decode(payloads) }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
@state = State.new(
|
92
|
+
workflow_definitions:,
|
93
|
+
bridge_worker:,
|
94
|
+
logger:,
|
95
|
+
metric_meter:,
|
96
|
+
data_converter:,
|
97
|
+
deadlock_timeout: debug_mode ? nil : 2.0,
|
98
|
+
# TODO(cretz): Make this more performant for the default set?
|
99
|
+
illegal_calls: WorkflowInstance::IllegalCallTracer.frozen_validated_illegal_calls(
|
100
|
+
illegal_workflow_calls || {}
|
101
|
+
),
|
102
|
+
namespace:,
|
103
|
+
task_queue:,
|
104
|
+
disable_eager_activity_execution:,
|
105
|
+
workflow_interceptors:,
|
106
|
+
workflow_failure_exception_types: workflow_failure_exception_types.map do |t|
|
107
|
+
unless t.is_a?(Class) && t < Exception
|
108
|
+
raise ArgumentError, 'All failure types must classes inheriting Exception'
|
109
|
+
end
|
110
|
+
|
111
|
+
t
|
112
|
+
end.freeze
|
113
|
+
)
|
114
|
+
@state.on_eviction = on_eviction if on_eviction
|
115
|
+
|
116
|
+
# Validate worker
|
117
|
+
@executor._validate_worker(self, @state)
|
118
|
+
end
|
119
|
+
|
120
|
+
def handle_activation(runner:, activation:, decoded:)
|
121
|
+
# Encode in background if not encoded but it needs to be
|
122
|
+
if @payload_encoding_visitor && !decoded
|
123
|
+
if Fiber.current_scheduler
|
124
|
+
Fiber.schedule { decode_activation(runner, activation) }
|
125
|
+
else
|
126
|
+
@workflow_payload_codec_thread_pool.execute { decode_activation(runner, activation) }
|
127
|
+
end
|
128
|
+
else
|
129
|
+
@executor._activate(activation, @state) do |activation_completion|
|
130
|
+
runner.apply_workflow_activation_complete(workflow_worker: self, activation_completion:, encoded: false)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
134
|
+
# Should never happen, executors are expected to trap things
|
135
|
+
@state.logger.error("Failed issuing activation on workflow run ID: #{activation.run_id}")
|
136
|
+
@state.logger.error(e)
|
137
|
+
end
|
138
|
+
|
139
|
+
def handle_activation_complete(runner:, activation_completion:, encoded:, completion_complete_queue:)
|
140
|
+
if @payload_encoding_visitor && !encoded
|
141
|
+
if Fiber.current_scheduler
|
142
|
+
Fiber.schedule { encode_activation_completion(runner, activation_completion) }
|
143
|
+
else
|
144
|
+
@workflow_payload_codec_thread_pool.execute do
|
145
|
+
encode_activation_completion(runner, activation_completion)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
else
|
149
|
+
@state.bridge_worker.async_complete_workflow_activation(
|
150
|
+
activation_completion.run_id, activation_completion.to_proto, completion_complete_queue
|
151
|
+
)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def on_shutdown_complete
|
156
|
+
@state.evict_all
|
157
|
+
end
|
158
|
+
|
159
|
+
private
|
160
|
+
|
161
|
+
def decode_activation(runner, activation)
|
162
|
+
@payload_decoding_visitor.run(activation)
|
163
|
+
runner.apply_workflow_activation_decoded(workflow_worker: self, activation:)
|
164
|
+
end
|
165
|
+
|
166
|
+
def encode_activation_completion(runner, activation_completion)
|
167
|
+
@payload_encoding_visitor.run(activation_completion)
|
168
|
+
runner.apply_workflow_activation_complete(workflow_worker: self, activation_completion:, encoded: true)
|
169
|
+
end
|
170
|
+
|
171
|
+
def apply_codec_on_payload_visit(payload_or_payloads, &)
|
172
|
+
case payload_or_payloads
|
173
|
+
when Temporalio::Api::Common::V1::Payload
|
174
|
+
new_payloads = yield [payload_or_payloads]
|
175
|
+
payload_or_payloads.metadata = new_payloads.first.metadata
|
176
|
+
payload_or_payloads.data = new_payloads.first.data
|
177
|
+
when Enumerable
|
178
|
+
payload_or_payloads.replace(yield payload_or_payloads) # steep:ignore
|
179
|
+
else
|
180
|
+
raise 'Unrecognized visitor type'
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
class State
|
185
|
+
attr_reader :workflow_definitions, :bridge_worker, :logger, :metric_meter, :data_converter, :deadlock_timeout,
|
186
|
+
:illegal_calls, :namespace, :task_queue, :disable_eager_activity_execution,
|
187
|
+
:workflow_interceptors, :workflow_failure_exception_types
|
188
|
+
|
189
|
+
attr_writer :on_eviction
|
190
|
+
|
191
|
+
def initialize(
|
192
|
+
workflow_definitions:, bridge_worker:, logger:, metric_meter:, data_converter:, deadlock_timeout:,
|
193
|
+
illegal_calls:, namespace:, task_queue:, disable_eager_activity_execution:,
|
194
|
+
workflow_interceptors:, workflow_failure_exception_types:
|
195
|
+
)
|
196
|
+
@workflow_definitions = workflow_definitions
|
197
|
+
@bridge_worker = bridge_worker
|
198
|
+
@logger = logger
|
199
|
+
@metric_meter = metric_meter
|
200
|
+
@data_converter = data_converter
|
201
|
+
@deadlock_timeout = deadlock_timeout
|
202
|
+
@illegal_calls = illegal_calls
|
203
|
+
@namespace = namespace
|
204
|
+
@task_queue = task_queue
|
205
|
+
@disable_eager_activity_execution = disable_eager_activity_execution
|
206
|
+
@workflow_interceptors = workflow_interceptors
|
207
|
+
@workflow_failure_exception_types = workflow_failure_exception_types
|
208
|
+
|
209
|
+
@running_workflows = {}
|
210
|
+
@running_workflows_mutex = Mutex.new
|
211
|
+
end
|
212
|
+
|
213
|
+
# This can never be called at the same time for the same run ID on the same state object
|
214
|
+
def get_or_create_running_workflow(run_id, &)
|
215
|
+
instance = @running_workflows_mutex.synchronize { @running_workflows[run_id] }
|
216
|
+
# If instance is not there, we create it out of lock then store it under lock
|
217
|
+
unless instance
|
218
|
+
instance = yield
|
219
|
+
@running_workflows_mutex.synchronize { @running_workflows[run_id] = instance }
|
220
|
+
end
|
221
|
+
instance
|
222
|
+
end
|
223
|
+
|
224
|
+
def evict_running_workflow(run_id, cache_remove_job)
|
225
|
+
@running_workflows_mutex.synchronize { @running_workflows.delete(run_id) }
|
226
|
+
@on_eviction&.call(run_id, cache_remove_job)
|
227
|
+
end
|
228
|
+
|
229
|
+
def evict_all
|
230
|
+
@running_workflows_mutex.synchronize { @running_workflows.clear }
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'temporalio/internal/metric'
|
4
|
+
|
5
|
+
module Temporalio
|
6
|
+
# Metric that can be recorded from a metric meter. This is obtained via {Meter.create_metric}. The metric meter is
|
7
|
+
# obtained via workflow environment, activity context, or from the {Runtime} if in neither of those. This class is
|
8
|
+
# effectively abstract and will fail if `initialize` is attempted.
|
9
|
+
class Metric
|
10
|
+
# @!visibility private
|
11
|
+
def initialize
|
12
|
+
raise NotImplementedError, 'Metric is abstract, implementations override initialize'
|
13
|
+
end
|
14
|
+
|
15
|
+
# Record a value for the metric. For counters, this adds to any existing. For histograms, this records into proper
|
16
|
+
# buckets. For gauges, this sets the value. The value type must match the expectation.
|
17
|
+
#
|
18
|
+
# @param value [Numeric] Value to record. For counters and duration-based histograms, this value cannot be negative.
|
19
|
+
# @param additional_attributes [Hash{String, Symbol => String, Integer, Float, Boolean}, nil] Additional attributes
|
20
|
+
# on this specific record. For better performance for attribute reuse, users are encouraged to use
|
21
|
+
# {with_additional_attributes} to make a copy of this metric with those attributes.
|
22
|
+
def record(value, additional_attributes: nil)
|
23
|
+
raise NotImplementedError
|
24
|
+
end
|
25
|
+
|
26
|
+
# Create a copy of this metric but with the given additional attributes. This is more performant than providing
|
27
|
+
# attributes on each {record} call.
|
28
|
+
#
|
29
|
+
# @param additional_attributes [Hash{String, Symbol => String, Integer, Float, Boolean}] Attributes to set on the
|
30
|
+
# resulting metric.
|
31
|
+
# @return [Metric] Copy of this metric with the additional attributes.
|
32
|
+
def with_additional_attributes(additional_attributes)
|
33
|
+
raise NotImplementedError
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [:counter, :histogram, :gauge] Metric type.
|
37
|
+
def metric_type
|
38
|
+
raise NotImplementedError
|
39
|
+
end
|
40
|
+
|
41
|
+
# @return [String] Metric name.
|
42
|
+
def name
|
43
|
+
raise NotImplementedError
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return [String, nil] Metric description.
|
47
|
+
def description
|
48
|
+
raise NotImplementedError
|
49
|
+
end
|
50
|
+
|
51
|
+
# @return [String, nil] Metric unit.
|
52
|
+
def unit
|
53
|
+
raise NotImplementedError
|
54
|
+
end
|
55
|
+
|
56
|
+
# @return [:integer, :float, :duration] Metric value type.
|
57
|
+
def value_type
|
58
|
+
raise NotImplementedError
|
59
|
+
end
|
60
|
+
|
61
|
+
# Meter for creating metrics to record values on. This is obtained via workflow environment, activity context, or
|
62
|
+
# from the {Runtime} if in neither of those. This class is effectively abstract and will fail if `initialize` is
|
63
|
+
# attempted.
|
64
|
+
class Meter
|
65
|
+
# @return [Meter] A no-op instance of {Meter}.
|
66
|
+
def self.null
|
67
|
+
Internal::Metric::NullMeter.instance
|
68
|
+
end
|
69
|
+
|
70
|
+
# @!visibility private
|
71
|
+
def initialize
|
72
|
+
raise NotImplementedError, 'Meter is abstract, implementations override initialize'
|
73
|
+
end
|
74
|
+
|
75
|
+
# Create a new metric. Only certain metric types are accepted and only value types can work with certain metric
|
76
|
+
# types.
|
77
|
+
#
|
78
|
+
# @param metric_type [:counter, :histogram, :gauge] Metric type. Counters can only have `:integer` value types,
|
79
|
+
# histograms can have `:integer`, `:float`, or :duration` value types, and gauges can have `:integer` or
|
80
|
+
# `:float` value types.
|
81
|
+
# @param name [String] Metric name.
|
82
|
+
# @param description [String, nil] Metric description.
|
83
|
+
# @param unit [String, nil] Metric unit.
|
84
|
+
# @param value_type [:integer, :float, :duration] Metric value type. `:integer` works for all metric types,
|
85
|
+
# `:float` works for `:histogram` and `:gauge` metric types, and `:duration` only works for `:histogram` metric
|
86
|
+
# types.
|
87
|
+
# @return [Metric] Created metric.
|
88
|
+
def create_metric(
|
89
|
+
metric_type,
|
90
|
+
name,
|
91
|
+
description: nil,
|
92
|
+
unit: nil,
|
93
|
+
value_type: :integer
|
94
|
+
)
|
95
|
+
raise NotImplementedError
|
96
|
+
end
|
97
|
+
|
98
|
+
# Create a copy of this meter but with the given additional attributes. This is more performant than providing
|
99
|
+
# attributes on each {record} call.
|
100
|
+
#
|
101
|
+
# @param additional_attributes [Hash{String, Symbol => String, Integer, Float, Boolean}] Attributes to set on the
|
102
|
+
# resulting meter.
|
103
|
+
# @return [Meter] Copy of this meter with the additional attributes.
|
104
|
+
def with_additional_attributes(additional_attributes)
|
105
|
+
raise NotImplementedError
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'temporalio/internal/proto_utils'
|
4
|
+
|
5
|
+
module Temporalio
|
6
|
+
RetryPolicy = Data.define(
|
7
|
+
:initial_interval,
|
8
|
+
:backoff_coefficient,
|
9
|
+
:max_interval,
|
10
|
+
:max_attempts,
|
11
|
+
:non_retryable_error_types
|
12
|
+
)
|
13
|
+
|
14
|
+
# Options for retrying workflows and activities.
|
15
|
+
#
|
16
|
+
# @!attribute initial_interval
|
17
|
+
# @return [Float] Backoff interval in seconds for the first retry. Default 1.0.
|
18
|
+
# @!attribute backoff_coefficient
|
19
|
+
# @return [Float] Coefficient to multiply previous backoff interval by to get new interval. Default 2.0.
|
20
|
+
# @!attribute max_interval
|
21
|
+
# @return [Float, nil] Maximum backoff interval in seconds between retries. Default 100x `initial_interval`.
|
22
|
+
# @!attribute max_attempts
|
23
|
+
# @return [Integer] Maximum number of attempts. If `0`, the default, there is no maximum.
|
24
|
+
# @!attribute non_retryable_error_types
|
25
|
+
# @return [Array<String>, nil] List of error types that are not retryable.
|
26
|
+
class RetryPolicy
|
27
|
+
# @!visibility private
|
28
|
+
def self._from_proto(raw_policy)
|
29
|
+
RetryPolicy.new(
|
30
|
+
initial_interval: Internal::ProtoUtils.duration_to_seconds(raw_policy.initial_interval) || raise, # Never nil
|
31
|
+
backoff_coefficient: raw_policy.backoff_coefficient,
|
32
|
+
max_interval: Internal::ProtoUtils.duration_to_seconds(raw_policy.maximum_interval),
|
33
|
+
max_attempts: raw_policy.maximum_attempts,
|
34
|
+
non_retryable_error_types: raw_policy.non_retryable_error_types&.to_a
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Create retry policy.
|
39
|
+
#
|
40
|
+
# @param initial_interval [Float] Backoff interval in seconds for the first retry. Default 1.0.
|
41
|
+
# @param backoff_coefficient [Float] Coefficient to multiply previous backoff interval by to get new interval.
|
42
|
+
# Default 2.0.
|
43
|
+
# @param max_interval [Float, nil] Maximum backoff interval in seconds between retries. Default 100x
|
44
|
+
# `initial_interval`.
|
45
|
+
# @param max_attempts [Integer] Maximum number of attempts. If `0`, the default, there is no maximum.
|
46
|
+
# @param non_retryable_error_types [Array<String>, nil] List of error types that are not retryable.
|
47
|
+
def initialize(
|
48
|
+
initial_interval: 1.0,
|
49
|
+
backoff_coefficient: 2.0,
|
50
|
+
max_interval: nil,
|
51
|
+
max_attempts: 0,
|
52
|
+
non_retryable_error_types: nil
|
53
|
+
)
|
54
|
+
super
|
55
|
+
end
|
56
|
+
|
57
|
+
# @!visibility private
|
58
|
+
def _to_proto
|
59
|
+
raise 'Initial interval cannot be negative' if initial_interval.negative?
|
60
|
+
raise 'Backoff coefficient cannot be less than 1' if backoff_coefficient < 1
|
61
|
+
raise 'Max interval cannot be negative' if max_interval&.negative?
|
62
|
+
raise 'Max interval cannot be less than initial interval' if max_interval && max_interval < initial_interval
|
63
|
+
raise 'Max attempts cannot be negative' if max_attempts.negative?
|
64
|
+
|
65
|
+
Api::Common::V1::RetryPolicy.new(
|
66
|
+
initial_interval: Internal::ProtoUtils.seconds_to_duration(initial_interval),
|
67
|
+
backoff_coefficient:,
|
68
|
+
maximum_interval: Internal::ProtoUtils.seconds_to_duration(max_interval),
|
69
|
+
maximum_attempts: max_attempts,
|
70
|
+
non_retryable_error_types:
|
71
|
+
)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|