amit-temporalio 0.3.1
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/Cargo.lock +4325 -0
- data/Cargo.toml +25 -0
- data/Gemfile +23 -0
- data/LICENSE +21 -0
- data/README.md +1148 -0
- data/Rakefile +101 -0
- data/ext/Cargo.toml +27 -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/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 +234 -0
@@ -0,0 +1,529 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'random/formatter'
|
4
|
+
require 'temporalio/error'
|
5
|
+
require 'temporalio/workflow/activity_cancellation_type'
|
6
|
+
require 'temporalio/workflow/child_workflow_cancellation_type'
|
7
|
+
require 'temporalio/workflow/child_workflow_handle'
|
8
|
+
require 'temporalio/workflow/definition'
|
9
|
+
require 'temporalio/workflow/external_workflow_handle'
|
10
|
+
require 'temporalio/workflow/future'
|
11
|
+
require 'temporalio/workflow/handler_unfinished_policy'
|
12
|
+
require 'temporalio/workflow/info'
|
13
|
+
require 'temporalio/workflow/parent_close_policy'
|
14
|
+
require 'temporalio/workflow/update_info'
|
15
|
+
require 'timeout'
|
16
|
+
|
17
|
+
module Temporalio
|
18
|
+
# Module with all class-methods that can be made from a workflow. Methods on this module cannot be used outside of a
|
19
|
+
# workflow with the obvious exception of {in_workflow?}. This module is not meant to be included or mixed in.
|
20
|
+
module Workflow
|
21
|
+
# @return [Boolean] Whether all update and signal handlers have finished executing. Consider waiting on this
|
22
|
+
# condition before workflow return or continue-as-new, to prevent interruption of in-progress handlers by workflow
|
23
|
+
# return: `Temporalio::Workflow.wait_condition { Temporalio::Workflow.all_handlers_finished? }``
|
24
|
+
def self.all_handlers_finished?
|
25
|
+
_current.all_handlers_finished?
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [Cancellation] Cancellation for the workflow. This is canceled when a workflow cancellation request is
|
29
|
+
# received. This is the default cancellation for most workflow calls.
|
30
|
+
def self.cancellation
|
31
|
+
_current.cancellation
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [Boolean] Whether continue as new is suggested. This value is the current continue-as-new suggestion up
|
35
|
+
# until the current task. Note, this value may not be up to date when accessed in a query. When continue as new is
|
36
|
+
# suggested is based on server-side configuration.
|
37
|
+
def self.continue_as_new_suggested
|
38
|
+
_current.continue_as_new_suggested
|
39
|
+
end
|
40
|
+
|
41
|
+
# @return [Integer] Current number of events in history. This value is the current history event count up until the
|
42
|
+
# current task. Note, this value may not be up to date when accessed in a query.
|
43
|
+
def self.current_history_length
|
44
|
+
_current.current_history_length
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [Integer] Current history size in bytes. This value is the current history size up until the current task.
|
48
|
+
# Note, this value may not be up to date when accessed in a query.
|
49
|
+
def self.current_history_size
|
50
|
+
_current.current_history_size
|
51
|
+
end
|
52
|
+
|
53
|
+
# @return [UpdateInfo] Current update info if this code is running inside an update. This is set via a Fiber-local
|
54
|
+
# storage so it is only visible to the current handler fiber.
|
55
|
+
def self.current_update_info
|
56
|
+
_current.current_update_info
|
57
|
+
end
|
58
|
+
|
59
|
+
# Mark a patch as deprecated.
|
60
|
+
#
|
61
|
+
# This marks a workflow that had {patched} in a previous version of the code as no longer applicable because all
|
62
|
+
# workflows that use the old code path are done and will never be queried again. Therefore the old code path is
|
63
|
+
# removed as well.
|
64
|
+
#
|
65
|
+
# @param patch_id [Symbol, String] Patch ID.
|
66
|
+
def self.deprecate_patch(patch_id)
|
67
|
+
_current.deprecate_patch(patch_id)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Execute an activity and return its result. Either `start_to_close_timeout` or `schedule_to_close_timeout` _must_
|
71
|
+
# be set. The `heartbeat_timeout` should be set for any non-immediately-completing activity so it can receive
|
72
|
+
# cancellation. To run an activity in the background, use a {Future}.
|
73
|
+
#
|
74
|
+
# @note Using an already-canceled cancellation may give a different exception than canceling after started. Use
|
75
|
+
# {Error.canceled?} to check if the exception is a cancellation either way.
|
76
|
+
#
|
77
|
+
# @param activity [Class<Activity::Definition>, Symbol, String] Activity definition class or activity name.
|
78
|
+
# @param args [Array<Object>] Arguments to the activity.
|
79
|
+
# @param task_queue [String] Task queue to run the activity on. Defaults to the current workflow's task queue.
|
80
|
+
# @param schedule_to_close_timeout [Float, nil] Max amount of time the activity can take from first being scheduled
|
81
|
+
# to being completed before it times out. This is inclusive of all retries.
|
82
|
+
# @param schedule_to_start_timeout [Float, nil] Max amount of time the activity can take to be started from first
|
83
|
+
# being scheduled.
|
84
|
+
# @param start_to_close_timeout [Float, nil] Max amount of time a single activity run can take from when it starts
|
85
|
+
# to when it completes. This is per retry.
|
86
|
+
# @param heartbeat_timeout [Float, nil] How frequently an activity must invoke heartbeat while running before it is
|
87
|
+
# considered timed out. This also affects how heartbeats are throttled, see general heartbeating documentation.
|
88
|
+
# @param retry_policy [RetryPolicy] How an activity is retried on failure. If unset, a server-defined default is
|
89
|
+
# used. Set maximum attempts to 1 to disable retries.
|
90
|
+
# @param cancellation [Cancellation] Cancellation to apply to the activity. How cancellation is treated is based on
|
91
|
+
# `cancellation_type`. This defaults to the workflow's cancellation, but may need to be overridden with a
|
92
|
+
# new/detached one if an activity is being run in an `ensure` after workflow cancellation.
|
93
|
+
# @param cancellation_type [ActivityCancellationType] How the activity is treated when it is canceled from the
|
94
|
+
# workflow.
|
95
|
+
# @param activity_id [String, nil] Optional unique identifier for the activity. This is an advanced setting that
|
96
|
+
# should not be set unless users are sure they need to. Contact Temporal before setting this value.
|
97
|
+
# @param disable_eager_execution [Boolean] Whether eager execution is disabled. Eager activity execution is an
|
98
|
+
# optimization on some servers that sends activities back to the same worker as the calling workflow if they can
|
99
|
+
# run there. If `false` (the default), eager execution may still be disabled at the worker level or may not be
|
100
|
+
# requested due to lack of available slots.
|
101
|
+
#
|
102
|
+
# @return [Object] Result of the activity.
|
103
|
+
# @raise [Error::ActivityError] Activity failed (and retry was disabled or exhausted).
|
104
|
+
# @raise [Error::CanceledError] Activity was canceled before started. When canceled after started (and not
|
105
|
+
# waited-then-swallowed), instead this canceled error is the cause of a {Error::ActivityError}.
|
106
|
+
def self.execute_activity(
|
107
|
+
activity,
|
108
|
+
*args,
|
109
|
+
task_queue: info.task_queue,
|
110
|
+
schedule_to_close_timeout: nil,
|
111
|
+
schedule_to_start_timeout: nil,
|
112
|
+
start_to_close_timeout: nil,
|
113
|
+
heartbeat_timeout: nil,
|
114
|
+
retry_policy: nil,
|
115
|
+
cancellation: Workflow.cancellation,
|
116
|
+
cancellation_type: ActivityCancellationType::TRY_CANCEL,
|
117
|
+
activity_id: nil,
|
118
|
+
disable_eager_execution: false
|
119
|
+
)
|
120
|
+
_current.execute_activity(
|
121
|
+
activity, *args,
|
122
|
+
task_queue:, schedule_to_close_timeout:, schedule_to_start_timeout:, start_to_close_timeout:,
|
123
|
+
heartbeat_timeout:, retry_policy:, cancellation:, cancellation_type:, activity_id:, disable_eager_execution:
|
124
|
+
)
|
125
|
+
end
|
126
|
+
|
127
|
+
# Shortcut for {start_child_workflow} + {ChildWorkflowHandle.result}. See those two calls for more details.
|
128
|
+
def self.execute_child_workflow(
|
129
|
+
workflow,
|
130
|
+
*args,
|
131
|
+
id: random.uuid,
|
132
|
+
task_queue: info.task_queue,
|
133
|
+
cancellation: Workflow.cancellation,
|
134
|
+
cancellation_type: ChildWorkflowCancellationType::WAIT_CANCELLATION_COMPLETED,
|
135
|
+
parent_close_policy: ParentClosePolicy::TERMINATE,
|
136
|
+
execution_timeout: nil,
|
137
|
+
run_timeout: nil,
|
138
|
+
task_timeout: nil,
|
139
|
+
id_reuse_policy: WorkflowIDReusePolicy::ALLOW_DUPLICATE,
|
140
|
+
retry_policy: nil,
|
141
|
+
cron_schedule: nil,
|
142
|
+
memo: nil,
|
143
|
+
search_attributes: nil
|
144
|
+
)
|
145
|
+
start_child_workflow(
|
146
|
+
workflow, *args,
|
147
|
+
id:, task_queue:, cancellation:, cancellation_type:, parent_close_policy:, execution_timeout:, run_timeout:,
|
148
|
+
task_timeout:, id_reuse_policy:, retry_policy:, cron_schedule:, memo:, search_attributes:
|
149
|
+
).result
|
150
|
+
end
|
151
|
+
|
152
|
+
# Execute an activity locally in this same workflow task and return its result. This should usually only be used for
|
153
|
+
# short/simple activities where the result performance matters. Either `start_to_close_timeout` or
|
154
|
+
# `schedule_to_close_timeout` _must_ be set. To run an activity in the background, use a {Future}.
|
155
|
+
#
|
156
|
+
# @note Using an already-canceled cancellation may give a different exception than canceling after started. Use
|
157
|
+
# {Error.canceled?} to check if the exception is a cancellation either way.
|
158
|
+
#
|
159
|
+
# @param activity [Class<Activity::Definition>, Symbol, String] Activity definition class or name.
|
160
|
+
# @param args [Array<Object>] Arguments to the activity.
|
161
|
+
# @param schedule_to_close_timeout [Float, nil] Max amount of time the activity can take from first being scheduled
|
162
|
+
# to being completed before it times out. This is inclusive of all retries.
|
163
|
+
# @param schedule_to_start_timeout [Float, nil] Max amount of time the activity can take to be started from first
|
164
|
+
# being scheduled.
|
165
|
+
# @param start_to_close_timeout [Float, nil] Max amount of time a single activity run can take from when it starts
|
166
|
+
# to when it completes. This is per retry.
|
167
|
+
# @param retry_policy [RetryPolicy] How an activity is retried on failure. If unset, a server-defined default is
|
168
|
+
# used. Set maximum attempts to 1 to disable retries.
|
169
|
+
# @param local_retry_threshold [Float, nil] If the activity is retrying and backoff would exceed this value, a timer
|
170
|
+
# is scheduled and the activity is retried after. Otherwise, backoff will happen internally within the task.
|
171
|
+
# Defaults to 1 minute.
|
172
|
+
# @param cancellation [Cancellation] Cancellation to apply to the activity. How cancellation is treated is based on
|
173
|
+
# `cancellation_type`. This defaults to the workflow's cancellation, but may need to be overridden with a
|
174
|
+
# new/detached one if an activity is being run in an `ensure` after workflow cancellation.
|
175
|
+
# @param cancellation_type [ActivityCancellationType] How the activity is treated when it is canceled from the
|
176
|
+
# workflow.
|
177
|
+
# @param activity_id [String, nil] Optional unique identifier for the activity. This is an advanced setting that
|
178
|
+
# should not be set unless users are sure they need to. Contact Temporal before setting this value.
|
179
|
+
#
|
180
|
+
# @return [Object] Result of the activity.
|
181
|
+
# @raise [Error::ActivityError] Activity failed (and retry was disabled or exhausted).
|
182
|
+
# @raise [Error::CanceledError] Activity was canceled before started. When canceled after started (and not
|
183
|
+
# waited-then-swallowed), instead this canceled error is the cause of a {Error::ActivityError}.
|
184
|
+
def self.execute_local_activity(
|
185
|
+
activity,
|
186
|
+
*args,
|
187
|
+
schedule_to_close_timeout: nil,
|
188
|
+
schedule_to_start_timeout: nil,
|
189
|
+
start_to_close_timeout: nil,
|
190
|
+
retry_policy: nil,
|
191
|
+
local_retry_threshold: nil,
|
192
|
+
cancellation: Workflow.cancellation,
|
193
|
+
cancellation_type: ActivityCancellationType::TRY_CANCEL,
|
194
|
+
activity_id: nil
|
195
|
+
)
|
196
|
+
_current.execute_local_activity(
|
197
|
+
activity, *args,
|
198
|
+
schedule_to_close_timeout:, schedule_to_start_timeout:, start_to_close_timeout:,
|
199
|
+
retry_policy:, local_retry_threshold:, cancellation:, cancellation_type:, activity_id:
|
200
|
+
)
|
201
|
+
end
|
202
|
+
|
203
|
+
# Get a handle to an external workflow for canceling and issuing signals.
|
204
|
+
#
|
205
|
+
# @param workflow_id [String] Workflow ID.
|
206
|
+
# @param run_id [String, nil] Optional, specific run ID.
|
207
|
+
#
|
208
|
+
# @return [ExternalWorkflowHandle] External workflow handle.
|
209
|
+
def self.external_workflow_handle(workflow_id, run_id: nil)
|
210
|
+
_current.external_workflow_handle(workflow_id, run_id:)
|
211
|
+
end
|
212
|
+
|
213
|
+
# @return [Boolean] Whether the current code is executing in a workflow.
|
214
|
+
def self.in_workflow?
|
215
|
+
_current_or_nil != nil
|
216
|
+
end
|
217
|
+
|
218
|
+
# @return [Info] Information about the current workflow.
|
219
|
+
def self.info
|
220
|
+
_current.info
|
221
|
+
end
|
222
|
+
|
223
|
+
# @return [Definition, nil] Workflow class instance. This should always be present except in
|
224
|
+
# {Worker::Interceptor::Workflow::Inbound.init} where it will be nil.
|
225
|
+
def self.instance
|
226
|
+
_current.instance
|
227
|
+
end
|
228
|
+
|
229
|
+
# @return [Logger] Logger for the workflow. This is a scoped logger that automatically appends workflow details to
|
230
|
+
# every log and takes care not to log during replay.
|
231
|
+
def self.logger
|
232
|
+
_current.logger
|
233
|
+
end
|
234
|
+
|
235
|
+
# @return [Hash{String, Symbol => Object}] Memo for the workflow. This is a read-only view of the memo. To update
|
236
|
+
# the memo, use {upsert_memo}. This always returns the same instance and updates are reflected on the returned
|
237
|
+
# instance, so it is not technically frozen.
|
238
|
+
def self.memo
|
239
|
+
_current.memo
|
240
|
+
end
|
241
|
+
|
242
|
+
# @return [Metric::Meter] Metric meter to create metrics on. This metric meter already contains some
|
243
|
+
# workflow-specific attributes and takes care not to apply metrics during replay.
|
244
|
+
def self.metric_meter
|
245
|
+
_current.metric_meter
|
246
|
+
end
|
247
|
+
|
248
|
+
# @return [Time] Current UTC time for this workflow. This creates and returns a new {::Time} instance every time it
|
249
|
+
# is invoked, it is not the same instance continually mutated.
|
250
|
+
def self.now
|
251
|
+
_current.now
|
252
|
+
end
|
253
|
+
|
254
|
+
# Patch a workflow.
|
255
|
+
#
|
256
|
+
# When called, this will only return true if code should take the newer path which means this is either not
|
257
|
+
# replaying or is replaying and has seen this patch before. Results for successive calls to this function for the
|
258
|
+
# same ID and workflow are memoized. Use {deprecate_patch} when all workflows are done and will never be queried
|
259
|
+
# again. The old code path can be removed at that time too.
|
260
|
+
#
|
261
|
+
# @param patch_id [Symbol, String] Patch ID.
|
262
|
+
# @return [Boolean] True if this should take the newer patch, false if it should take the old path.
|
263
|
+
def self.patched(patch_id)
|
264
|
+
_current.patched(patch_id)
|
265
|
+
end
|
266
|
+
|
267
|
+
# @return [Converters::PayloadConverter] Payload converter for the workflow.
|
268
|
+
def self.payload_converter
|
269
|
+
_current.payload_converter
|
270
|
+
end
|
271
|
+
|
272
|
+
# @return [Hash<String, Definition::Query>] Query handlers for this workflow. This hash is mostly immutable except
|
273
|
+
# for `[]=` (and `store`) which can be used to set a new handler, or can be set with `nil` to remove a handler.
|
274
|
+
# For most use cases, defining a handler as a `workflow_query` method is best.
|
275
|
+
def self.query_handlers
|
276
|
+
_current.query_handlers
|
277
|
+
end
|
278
|
+
|
279
|
+
# @return [Random] Deterministic instance of {::Random} for use in a workflow. This instance should be accessed each
|
280
|
+
# time needed, not stored. This instance may be recreated with a different seed in special cases (e.g. workflow
|
281
|
+
# reset). Do not use any other randomization inside workflow code.
|
282
|
+
def self.random
|
283
|
+
_current.random
|
284
|
+
end
|
285
|
+
|
286
|
+
# @return [SearchAttributes] Search attributes for the workflow. This is a read-only view of the attributes. To
|
287
|
+
# update the attributes, use {upsert_search_attributes}. This always returns the same instance and updates are
|
288
|
+
# reflected on the returned instance, so it is not technically frozen.
|
289
|
+
def self.search_attributes
|
290
|
+
_current.search_attributes
|
291
|
+
end
|
292
|
+
|
293
|
+
# @return [Hash<String, Definition::Signal>] Signal handlers for this workflow. This hash is mostly immutable except
|
294
|
+
# for `[]=` (and `store`) which can be used to set a new handler, or can be set with `nil` to remove a handler.
|
295
|
+
# For most use cases, defining a handler as a `workflow_signal` method is best.
|
296
|
+
def self.signal_handlers
|
297
|
+
_current.signal_handlers
|
298
|
+
end
|
299
|
+
|
300
|
+
# Sleep in a workflow for the given time.
|
301
|
+
#
|
302
|
+
# @param duration [Float, nil] Time to sleep in seconds. `nil` represents infinite, which does not start a timer and
|
303
|
+
# just waits for cancellation. `0` is assumed to be 1 millisecond and still results in a server-side timer. This
|
304
|
+
# value cannot be negative. Since Temporal timers are server-side, timer resolution may not end up as precise as
|
305
|
+
# system timers.
|
306
|
+
# @param summary [String, nil] A simple string identifying this timer that may be visible in UI/CLI. While it can be
|
307
|
+
# normal text, it is best to treat as a timer ID.
|
308
|
+
# @param cancellation [Cancellation] Cancellation for this timer.
|
309
|
+
# @raise [Error::CanceledError] Sleep canceled.
|
310
|
+
def self.sleep(duration, summary: nil, cancellation: Workflow.cancellation)
|
311
|
+
_current.sleep(duration, summary:, cancellation:)
|
312
|
+
end
|
313
|
+
|
314
|
+
# Start a child workflow and return the handle.
|
315
|
+
#
|
316
|
+
# @param workflow [Class<Workflow::Definition>, Symbol, String] Workflow definition class or workflow name.
|
317
|
+
# @param args [Array<Object>] Arguments to the workflow.
|
318
|
+
# @param id [String] Unique identifier for the workflow execution. Defaults to a new UUID from {random}.
|
319
|
+
# @param task_queue [String] Task queue to run the workflow on. Defaults to the current workflow's task queue.
|
320
|
+
# @param cancellation [Cancellation] Cancellation to apply to the child workflow. How cancellation is treated is
|
321
|
+
# based on `cancellation_type`. This defaults to the workflow's cancellation.
|
322
|
+
# @param cancellation_type [ChildWorkflowCancellationType] How the child workflow will react to cancellation.
|
323
|
+
# @param parent_close_policy [ParentClosePolicy] How to handle the child workflow when the parent workflow closes.
|
324
|
+
# @param execution_timeout [Float, nil] Total workflow execution timeout in seconds including retries and continue
|
325
|
+
# as new.
|
326
|
+
# @param run_timeout [Float, nil] Timeout of a single workflow run inseconds.
|
327
|
+
# @param task_timeout [Float, nil] Timeout of a single workflow task in seconds.
|
328
|
+
# @param id_reuse_policy [WorkflowIDReusePolicy] How already-existing IDs are treated.
|
329
|
+
# @param retry_policy [RetryPolicy, nil] Retry policy for the workflow.
|
330
|
+
# @param cron_schedule [String, nil] Cron schedule. Users should use schedules instead of this.
|
331
|
+
# @param memo [Hash{String, Symbol => Object}, nil] Memo for the workflow.
|
332
|
+
# @param search_attributes [SearchAttributes, nil] Search attributes for the workflow.
|
333
|
+
#
|
334
|
+
# @return [ChildWorkflowHandle] Workflow handle to the started workflow.
|
335
|
+
# @raise [Error::WorkflowAlreadyStartedError] Workflow already exists for the ID.
|
336
|
+
# @raise [Error::CanceledError] Starting of the child was canceled.
|
337
|
+
def self.start_child_workflow(
|
338
|
+
workflow,
|
339
|
+
*args,
|
340
|
+
id: random.uuid,
|
341
|
+
task_queue: info.task_queue,
|
342
|
+
cancellation: Workflow.cancellation,
|
343
|
+
cancellation_type: ChildWorkflowCancellationType::WAIT_CANCELLATION_COMPLETED,
|
344
|
+
parent_close_policy: ParentClosePolicy::TERMINATE,
|
345
|
+
execution_timeout: nil,
|
346
|
+
run_timeout: nil,
|
347
|
+
task_timeout: nil,
|
348
|
+
id_reuse_policy: WorkflowIDReusePolicy::ALLOW_DUPLICATE,
|
349
|
+
retry_policy: nil,
|
350
|
+
cron_schedule: nil,
|
351
|
+
memo: nil,
|
352
|
+
search_attributes: nil
|
353
|
+
)
|
354
|
+
_current.start_child_workflow(
|
355
|
+
workflow, *args,
|
356
|
+
id:, task_queue:, cancellation:, cancellation_type:, parent_close_policy:, execution_timeout:, run_timeout:,
|
357
|
+
task_timeout:, id_reuse_policy:, retry_policy:, cron_schedule:, memo:, search_attributes:
|
358
|
+
)
|
359
|
+
end
|
360
|
+
|
361
|
+
# Run the block until the timeout is reached. This is backed by {sleep}. This does not accept cancellation because
|
362
|
+
# it is expected the block within will properly handle/bubble cancellation.
|
363
|
+
#
|
364
|
+
# @param duration [Float, nil] Duration for the timeout. This is backed by {sleep} so see that method for details.
|
365
|
+
# @param exception_class [Class<Exception>] Exception to raise on timeout. Defaults to {::Timeout::Error} like
|
366
|
+
# {::Timeout.timeout}. Note that {::Timeout::Error} is considered a workflow failure exception, not a task failure
|
367
|
+
# exception.
|
368
|
+
# @param message [String] Message to use for timeout exception. Defaults to "execution expired" like
|
369
|
+
# {::Timeout.timeout}.
|
370
|
+
# @param summary [String] Timer summer for the timer created by this timeout. This is backed by {sleep} so see that
|
371
|
+
# method for details.
|
372
|
+
#
|
373
|
+
# @yield Block to run with a timeout.
|
374
|
+
# @return [Object] The result of the block.
|
375
|
+
# @raise [Exception] Upon timeout, raises whichever class is set in `exception_class` with the message of `message`.
|
376
|
+
def self.timeout(
|
377
|
+
duration,
|
378
|
+
exception_class = Timeout::Error,
|
379
|
+
message = 'execution expired',
|
380
|
+
summary: 'Timeout timer',
|
381
|
+
&
|
382
|
+
)
|
383
|
+
_current.timeout(duration, exception_class, message, summary:, &)
|
384
|
+
end
|
385
|
+
|
386
|
+
# @return [Hash<String, Definition::Update>] Update handlers for this workflow. This hash is mostly immutable except
|
387
|
+
# for `[]=` (and `store`) which can be used to set a new handler, or can be set with `nil` to remove a handler.
|
388
|
+
# For most use cases, defining a handler as a `workflow_update` method is best.
|
389
|
+
def self.update_handlers
|
390
|
+
_current.update_handlers
|
391
|
+
end
|
392
|
+
|
393
|
+
# Issue updates to the workflow memo.
|
394
|
+
#
|
395
|
+
# @param hash [Hash{String, Symbol => Object, nil}] Updates to apply. Value can be `nil` to effectively remove the
|
396
|
+
# memo value.
|
397
|
+
def self.upsert_memo(hash)
|
398
|
+
_current.upsert_memo(hash)
|
399
|
+
end
|
400
|
+
|
401
|
+
# Issue updates to the workflow search attributes.
|
402
|
+
#
|
403
|
+
# @param updates [Array<SearchAttributes::Update>] Updates to apply. Note these are {SearchAttributes::Update}
|
404
|
+
# objects which are created via {SearchAttributes::Key.value_set} and {SearchAttributes::Key.value_unset} methods.
|
405
|
+
def self.upsert_search_attributes(*updates)
|
406
|
+
_current.upsert_search_attributes(*updates)
|
407
|
+
end
|
408
|
+
|
409
|
+
# Wait for the given block to return a "truthy" value (i.e. any value other than `false` or `nil`). The block must
|
410
|
+
# be side-effect free since it may be invoked frequently during event loop iteration. To timeout a wait, {timeout}
|
411
|
+
# can be used. This cannot be used in side-effect-free contexts such as `initialize`, queries, or update validators.
|
412
|
+
#
|
413
|
+
# This is very commonly used to wait on a value to be set by a handler, e.g.
|
414
|
+
# `Temporalio::Workflow.wait_condition { @some_value }`. Special care was taken to only wake up a single wait
|
415
|
+
# condition when it evaluates to true. Therefore if multiple wait conditions are waiting on the same thing, only one
|
416
|
+
# is awoken at a time, which means the code immediately following that wait condition can change the variable before
|
417
|
+
# other wait conditions are evaluated. This is a useful property for building mutexes/semaphores.
|
418
|
+
#
|
419
|
+
# @param cancellation [Cancellation, nil] Cancellation to cancel the wait. This defaults to the workflow's
|
420
|
+
# cancellation.
|
421
|
+
# @yield Block that is run many times to test for truthiness.
|
422
|
+
# @yieldreturn [Object] Value to check whether truthy or falsy.
|
423
|
+
#
|
424
|
+
# @return [Object] Truthy value returned from the block.
|
425
|
+
# @raise [Error::CanceledError] Wait was canceled.
|
426
|
+
def self.wait_condition(cancellation: Workflow.cancellation, &)
|
427
|
+
raise 'Block required' unless block_given?
|
428
|
+
|
429
|
+
_current.wait_condition(cancellation:, &)
|
430
|
+
end
|
431
|
+
|
432
|
+
# @!visibility private
|
433
|
+
def self._current
|
434
|
+
current = _current_or_nil
|
435
|
+
raise Error, 'Not in workflow environment' if current.nil?
|
436
|
+
|
437
|
+
current
|
438
|
+
end
|
439
|
+
|
440
|
+
# @!visibility private
|
441
|
+
def self._current_or_nil
|
442
|
+
# We choose to use Fiber.scheduler instead of Fiber.current_scheduler here because the constructor of the class is
|
443
|
+
# not scheduled on this scheduler and so current_scheduler is nil during class construction.
|
444
|
+
sched = Fiber.scheduler
|
445
|
+
return sched.context if sched.is_a?(Internal::Worker::WorkflowInstance::Scheduler)
|
446
|
+
|
447
|
+
nil
|
448
|
+
end
|
449
|
+
|
450
|
+
# Unsafe module contains only-in-workflow methods that are considered unsafe. These should not be used unless the
|
451
|
+
# consequences are understood.
|
452
|
+
module Unsafe
|
453
|
+
# @return [Boolean] True if the workflow is replaying, false otherwise. Most code should not check this value.
|
454
|
+
def self.replaying?
|
455
|
+
Workflow._current.replaying?
|
456
|
+
end
|
457
|
+
|
458
|
+
# Run a block of code with illegal call tracing disabled. Users should be cautious about using this as it can
|
459
|
+
# often signify unsafe code.
|
460
|
+
#
|
461
|
+
# @yield Block to run with call tracing disabled
|
462
|
+
#
|
463
|
+
# @return [Object] Result of the block.
|
464
|
+
def self.illegal_call_tracing_disabled(&)
|
465
|
+
Workflow._current.illegal_call_tracing_disabled(&)
|
466
|
+
end
|
467
|
+
end
|
468
|
+
|
469
|
+
# Error that is raised by a workflow out of the primary workflow method to issue a continue-as-new.
|
470
|
+
class ContinueAsNewError < Error
|
471
|
+
attr_accessor :args, :workflow, :task_queue, :run_timeout, :task_timeout,
|
472
|
+
:retry_policy, :memo, :search_attributes, :headers
|
473
|
+
|
474
|
+
# Create a continue as new error.
|
475
|
+
#
|
476
|
+
# @param args [Array<Object>] Arguments for the new workflow.
|
477
|
+
# @param workflow [Class<Workflow::Definition>, String, Symbol, nil] Workflow definition class or workflow name.
|
478
|
+
# If unset/nil, the current workflow is used.
|
479
|
+
# @param task_queue [String, nil] Task queue for the workflow. If unset/nil, the current workflow task queue is
|
480
|
+
# used.
|
481
|
+
# @param run_timeout [Float, nil] Timeout of a single workflow run in seconds. The default is _not_ carried over
|
482
|
+
# from the current workflow.
|
483
|
+
# @param task_timeout [Float, nil] Timeout of a single workflow task in seconds. The default is _not_ carried over
|
484
|
+
# from the current workflow.
|
485
|
+
# @param retry_policy [RetryPolicy, nil] Retry policy for the workflow. If unset/nil, the current workflow retry
|
486
|
+
# policy is used.
|
487
|
+
# @param memo [Hash{String, Symbol => Object}, nil] Memo for the workflow. If unset/nil, the current workflow memo
|
488
|
+
# is used.
|
489
|
+
# @param search_attributes [SearchAttributes, nil] Search attributes for the workflow. If unset/nil, the current
|
490
|
+
# workflow search attributes are used.
|
491
|
+
# @param headers [Hash<String, Object>] Headers for the workflow. The default is _not_ carried over from the
|
492
|
+
# current workflow.
|
493
|
+
def initialize(
|
494
|
+
*args,
|
495
|
+
workflow: nil,
|
496
|
+
task_queue: nil,
|
497
|
+
run_timeout: nil,
|
498
|
+
task_timeout: nil,
|
499
|
+
retry_policy: nil,
|
500
|
+
memo: nil,
|
501
|
+
search_attributes: nil,
|
502
|
+
headers: {}
|
503
|
+
)
|
504
|
+
super('Continue as new')
|
505
|
+
@args = args
|
506
|
+
@workflow = workflow
|
507
|
+
@task_queue = task_queue
|
508
|
+
@run_timeout = run_timeout
|
509
|
+
@task_timeout = task_timeout
|
510
|
+
@retry_policy = retry_policy
|
511
|
+
@memo = memo
|
512
|
+
@search_attributes = search_attributes
|
513
|
+
@headers = headers
|
514
|
+
Workflow._current.initialize_continue_as_new_error(self)
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
# Error raised when a workflow does something with a side effect in an improper context. In `initialize`, query
|
519
|
+
# handlers, and update validators, a workflow cannot do anything that would generate a command (e.g. starting an
|
520
|
+
# activity) or anything that could wait (e.g. scheduling a fiber, running a future, or using a wait condition).
|
521
|
+
class InvalidWorkflowStateError < Error; end
|
522
|
+
|
523
|
+
# Error raised when a workflow does something potentially non-deterministic such as making an illegal call. Note,
|
524
|
+
# non-deterministic errors during replay do not raise an error that can be caught, those happen internally. But this
|
525
|
+
# error can still be used with configuring workflow failure exception types to change non-deterministic errors from
|
526
|
+
# task failures to workflow failures.
|
527
|
+
class NondeterminismError < Error; end
|
528
|
+
end
|
529
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'temporalio/api'
|
4
|
+
|
5
|
+
module Temporalio
|
6
|
+
# Representation of a workflow's history.
|
7
|
+
class WorkflowHistory
|
8
|
+
# Convert a JSON string to workflow history. This supports the JSON format exported by Temporal UI and CLI.
|
9
|
+
#
|
10
|
+
# @param json [String] JSON string.
|
11
|
+
# @return [WorkflowHistory] Converted history.
|
12
|
+
def self.from_history_json(json)
|
13
|
+
WorkflowHistory.new(Api::History::V1::History.decode_json(json).events.to_a)
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [Array<Api::History::V1::HistoryEvent>] History events for the workflow.
|
17
|
+
attr_reader :events
|
18
|
+
|
19
|
+
# @!visibility private
|
20
|
+
def initialize(events)
|
21
|
+
@events = events
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [String] ID of the workflow, extracted from the first event.
|
25
|
+
def workflow_id
|
26
|
+
start = events.first&.workflow_execution_started_event_attributes
|
27
|
+
raise 'First event not a start event' if start.nil?
|
28
|
+
|
29
|
+
start.workflow_id
|
30
|
+
end
|
31
|
+
|
32
|
+
# Convert to history JSON.
|
33
|
+
#
|
34
|
+
# @return [String] JSON string.
|
35
|
+
def to_history_json
|
36
|
+
Api::History::V1::History.encode_json(Api::History::V1::History.new(events:))
|
37
|
+
end
|
38
|
+
|
39
|
+
# Compare history.
|
40
|
+
#
|
41
|
+
# @param other [WorkflowHistory] Other history.
|
42
|
+
# @return [Boolean] True if equal.
|
43
|
+
def ==(other)
|
44
|
+
other.is_a?(WorkflowHistory) && events == other.events
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/temporalio.rb
ADDED
data/temporalio.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/temporalio/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'amit-temporalio'
|
7
|
+
spec.version = '0.3.1'
|
8
|
+
spec.authors = ['Temporal Technologies Inc']
|
9
|
+
spec.email = ['amitlin.dev@gmail.com']
|
10
|
+
|
11
|
+
spec.summary = 'Temporal.io Ruby SDK'
|
12
|
+
spec.homepage = 'https://github.com/temporalio/sdk-ruby'
|
13
|
+
spec.license = 'MIT'
|
14
|
+
|
15
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
16
|
+
spec.metadata['source_code_uri'] = 'https://github.com/temporalio/sdk-ruby'
|
17
|
+
|
18
|
+
spec.files = Dir['lib/**/*.rb', 'LICENSE', 'README.md', 'Cargo.*',
|
19
|
+
'temporalio.gemspec', 'Gemfile', 'Rakefile', '.yardopts']
|
20
|
+
|
21
|
+
spec.bindir = 'exe'
|
22
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
23
|
+
spec.require_paths = ['lib']
|
24
|
+
spec.extensions = ['ext/Cargo.toml']
|
25
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
26
|
+
|
27
|
+
spec.add_dependency 'google-protobuf', '>= 3.27.0'
|
28
|
+
end
|