amit-temporalio 0.3.1-x86_64-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.
Files changed (177) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +2 -0
  3. data/Gemfile +23 -0
  4. data/Rakefile +101 -0
  5. data/lib/temporalio/activity/complete_async_error.rb +11 -0
  6. data/lib/temporalio/activity/context.rb +116 -0
  7. data/lib/temporalio/activity/definition.rb +189 -0
  8. data/lib/temporalio/activity/info.rb +64 -0
  9. data/lib/temporalio/activity.rb +12 -0
  10. data/lib/temporalio/api/activity/v1/message.rb +25 -0
  11. data/lib/temporalio/api/batch/v1/message.rb +31 -0
  12. data/lib/temporalio/api/cloud/account/v1/message.rb +28 -0
  13. data/lib/temporalio/api/cloud/cloudservice/v1/request_response.rb +126 -0
  14. data/lib/temporalio/api/cloud/cloudservice/v1/service.rb +25 -0
  15. data/lib/temporalio/api/cloud/cloudservice.rb +3 -0
  16. data/lib/temporalio/api/cloud/identity/v1/message.rb +41 -0
  17. data/lib/temporalio/api/cloud/namespace/v1/message.rb +42 -0
  18. data/lib/temporalio/api/cloud/nexus/v1/message.rb +31 -0
  19. data/lib/temporalio/api/cloud/operation/v1/message.rb +28 -0
  20. data/lib/temporalio/api/cloud/region/v1/message.rb +24 -0
  21. data/lib/temporalio/api/cloud/resource/v1/message.rb +23 -0
  22. data/lib/temporalio/api/cloud/sink/v1/message.rb +24 -0
  23. data/lib/temporalio/api/cloud/usage/v1/message.rb +31 -0
  24. data/lib/temporalio/api/command/v1/message.rb +46 -0
  25. data/lib/temporalio/api/common/v1/grpc_status.rb +23 -0
  26. data/lib/temporalio/api/common/v1/message.rb +47 -0
  27. data/lib/temporalio/api/enums/v1/batch_operation.rb +22 -0
  28. data/lib/temporalio/api/enums/v1/command_type.rb +21 -0
  29. data/lib/temporalio/api/enums/v1/common.rb +26 -0
  30. data/lib/temporalio/api/enums/v1/event_type.rb +21 -0
  31. data/lib/temporalio/api/enums/v1/failed_cause.rb +26 -0
  32. data/lib/temporalio/api/enums/v1/namespace.rb +23 -0
  33. data/lib/temporalio/api/enums/v1/query.rb +22 -0
  34. data/lib/temporalio/api/enums/v1/reset.rb +23 -0
  35. data/lib/temporalio/api/enums/v1/schedule.rb +21 -0
  36. data/lib/temporalio/api/enums/v1/task_queue.rb +25 -0
  37. data/lib/temporalio/api/enums/v1/update.rb +22 -0
  38. data/lib/temporalio/api/enums/v1/workflow.rb +30 -0
  39. data/lib/temporalio/api/errordetails/v1/message.rb +42 -0
  40. data/lib/temporalio/api/export/v1/message.rb +24 -0
  41. data/lib/temporalio/api/failure/v1/message.rb +35 -0
  42. data/lib/temporalio/api/filter/v1/message.rb +27 -0
  43. data/lib/temporalio/api/history/v1/message.rb +90 -0
  44. data/lib/temporalio/api/namespace/v1/message.rb +31 -0
  45. data/lib/temporalio/api/nexus/v1/message.rb +40 -0
  46. data/lib/temporalio/api/operatorservice/v1/request_response.rb +49 -0
  47. data/lib/temporalio/api/operatorservice/v1/service.rb +23 -0
  48. data/lib/temporalio/api/operatorservice.rb +3 -0
  49. data/lib/temporalio/api/payload_visitor.rb +1513 -0
  50. data/lib/temporalio/api/protocol/v1/message.rb +23 -0
  51. data/lib/temporalio/api/query/v1/message.rb +27 -0
  52. data/lib/temporalio/api/replication/v1/message.rb +26 -0
  53. data/lib/temporalio/api/schedule/v1/message.rb +43 -0
  54. data/lib/temporalio/api/sdk/v1/enhanced_stack_trace.rb +25 -0
  55. data/lib/temporalio/api/sdk/v1/task_complete_metadata.rb +21 -0
  56. data/lib/temporalio/api/sdk/v1/user_metadata.rb +23 -0
  57. data/lib/temporalio/api/sdk/v1/workflow_metadata.rb +23 -0
  58. data/lib/temporalio/api/taskqueue/v1/message.rb +45 -0
  59. data/lib/temporalio/api/testservice/v1/request_response.rb +31 -0
  60. data/lib/temporalio/api/testservice/v1/service.rb +23 -0
  61. data/lib/temporalio/api/update/v1/message.rb +33 -0
  62. data/lib/temporalio/api/version/v1/message.rb +26 -0
  63. data/lib/temporalio/api/workflow/v1/message.rb +43 -0
  64. data/lib/temporalio/api/workflowservice/v1/request_response.rb +204 -0
  65. data/lib/temporalio/api/workflowservice/v1/service.rb +23 -0
  66. data/lib/temporalio/api/workflowservice.rb +3 -0
  67. data/lib/temporalio/api.rb +14 -0
  68. data/lib/temporalio/cancellation.rb +170 -0
  69. data/lib/temporalio/client/activity_id_reference.rb +32 -0
  70. data/lib/temporalio/client/async_activity_handle.rb +85 -0
  71. data/lib/temporalio/client/connection/cloud_service.rb +726 -0
  72. data/lib/temporalio/client/connection/operator_service.rb +201 -0
  73. data/lib/temporalio/client/connection/service.rb +42 -0
  74. data/lib/temporalio/client/connection/test_service.rb +111 -0
  75. data/lib/temporalio/client/connection/workflow_service.rb +1041 -0
  76. data/lib/temporalio/client/connection.rb +316 -0
  77. data/lib/temporalio/client/interceptor.rb +416 -0
  78. data/lib/temporalio/client/schedule.rb +967 -0
  79. data/lib/temporalio/client/schedule_handle.rb +126 -0
  80. data/lib/temporalio/client/workflow_execution.rb +100 -0
  81. data/lib/temporalio/client/workflow_execution_count.rb +36 -0
  82. data/lib/temporalio/client/workflow_execution_status.rb +18 -0
  83. data/lib/temporalio/client/workflow_handle.rb +389 -0
  84. data/lib/temporalio/client/workflow_query_reject_condition.rb +14 -0
  85. data/lib/temporalio/client/workflow_update_handle.rb +65 -0
  86. data/lib/temporalio/client/workflow_update_wait_stage.rb +17 -0
  87. data/lib/temporalio/client.rb +484 -0
  88. data/lib/temporalio/common_enums.rb +41 -0
  89. data/lib/temporalio/converters/data_converter.rb +99 -0
  90. data/lib/temporalio/converters/failure_converter.rb +202 -0
  91. data/lib/temporalio/converters/payload_codec.rb +26 -0
  92. data/lib/temporalio/converters/payload_converter/binary_null.rb +34 -0
  93. data/lib/temporalio/converters/payload_converter/binary_plain.rb +35 -0
  94. data/lib/temporalio/converters/payload_converter/binary_protobuf.rb +42 -0
  95. data/lib/temporalio/converters/payload_converter/composite.rb +66 -0
  96. data/lib/temporalio/converters/payload_converter/encoding.rb +35 -0
  97. data/lib/temporalio/converters/payload_converter/json_plain.rb +44 -0
  98. data/lib/temporalio/converters/payload_converter/json_protobuf.rb +41 -0
  99. data/lib/temporalio/converters/payload_converter.rb +71 -0
  100. data/lib/temporalio/converters/raw_value.rb +20 -0
  101. data/lib/temporalio/converters.rb +9 -0
  102. data/lib/temporalio/error/failure.rb +219 -0
  103. data/lib/temporalio/error.rb +155 -0
  104. data/lib/temporalio/internal/bridge/3.2/temporalio_bridge.so +0 -0
  105. data/lib/temporalio/internal/bridge/3.3/temporalio_bridge.so +0 -0
  106. data/lib/temporalio/internal/bridge/3.4/temporalio_bridge.so +0 -0
  107. data/lib/temporalio/internal/bridge/api/activity_result/activity_result.rb +34 -0
  108. data/lib/temporalio/internal/bridge/api/activity_task/activity_task.rb +31 -0
  109. data/lib/temporalio/internal/bridge/api/child_workflow/child_workflow.rb +33 -0
  110. data/lib/temporalio/internal/bridge/api/common/common.rb +26 -0
  111. data/lib/temporalio/internal/bridge/api/core_interface.rb +40 -0
  112. data/lib/temporalio/internal/bridge/api/external_data/external_data.rb +27 -0
  113. data/lib/temporalio/internal/bridge/api/nexus/nexus.rb +33 -0
  114. data/lib/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rb +56 -0
  115. data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +57 -0
  116. data/lib/temporalio/internal/bridge/api/workflow_completion/workflow_completion.rb +30 -0
  117. data/lib/temporalio/internal/bridge/api.rb +3 -0
  118. data/lib/temporalio/internal/bridge/client.rb +95 -0
  119. data/lib/temporalio/internal/bridge/runtime.rb +53 -0
  120. data/lib/temporalio/internal/bridge/testing.rb +66 -0
  121. data/lib/temporalio/internal/bridge/worker.rb +85 -0
  122. data/lib/temporalio/internal/bridge.rb +36 -0
  123. data/lib/temporalio/internal/client/implementation.rb +700 -0
  124. data/lib/temporalio/internal/metric.rb +122 -0
  125. data/lib/temporalio/internal/proto_utils.rb +133 -0
  126. data/lib/temporalio/internal/worker/activity_worker.rb +376 -0
  127. data/lib/temporalio/internal/worker/multi_runner.rb +213 -0
  128. data/lib/temporalio/internal/worker/workflow_instance/child_workflow_handle.rb +54 -0
  129. data/lib/temporalio/internal/worker/workflow_instance/context.rb +333 -0
  130. data/lib/temporalio/internal/worker/workflow_instance/details.rb +44 -0
  131. data/lib/temporalio/internal/worker/workflow_instance/external_workflow_handle.rb +32 -0
  132. data/lib/temporalio/internal/worker/workflow_instance/externally_immutable_hash.rb +22 -0
  133. data/lib/temporalio/internal/worker/workflow_instance/handler_execution.rb +25 -0
  134. data/lib/temporalio/internal/worker/workflow_instance/handler_hash.rb +41 -0
  135. data/lib/temporalio/internal/worker/workflow_instance/illegal_call_tracer.rb +97 -0
  136. data/lib/temporalio/internal/worker/workflow_instance/inbound_implementation.rb +62 -0
  137. data/lib/temporalio/internal/worker/workflow_instance/outbound_implementation.rb +415 -0
  138. data/lib/temporalio/internal/worker/workflow_instance/replay_safe_logger.rb +37 -0
  139. data/lib/temporalio/internal/worker/workflow_instance/replay_safe_metric.rb +40 -0
  140. data/lib/temporalio/internal/worker/workflow_instance/scheduler.rb +163 -0
  141. data/lib/temporalio/internal/worker/workflow_instance.rb +730 -0
  142. data/lib/temporalio/internal/worker/workflow_worker.rb +236 -0
  143. data/lib/temporalio/internal.rb +7 -0
  144. data/lib/temporalio/metric.rb +109 -0
  145. data/lib/temporalio/retry_policy.rb +74 -0
  146. data/lib/temporalio/runtime.rb +314 -0
  147. data/lib/temporalio/scoped_logger.rb +96 -0
  148. data/lib/temporalio/search_attributes.rb +343 -0
  149. data/lib/temporalio/testing/activity_environment.rb +136 -0
  150. data/lib/temporalio/testing/workflow_environment.rb +383 -0
  151. data/lib/temporalio/testing.rb +10 -0
  152. data/lib/temporalio/version.rb +5 -0
  153. data/lib/temporalio/worker/activity_executor/fiber.rb +49 -0
  154. data/lib/temporalio/worker/activity_executor/thread_pool.rb +46 -0
  155. data/lib/temporalio/worker/activity_executor.rb +55 -0
  156. data/lib/temporalio/worker/interceptor.rb +362 -0
  157. data/lib/temporalio/worker/thread_pool.rb +237 -0
  158. data/lib/temporalio/worker/tuner.rb +189 -0
  159. data/lib/temporalio/worker/workflow_executor/thread_pool.rb +230 -0
  160. data/lib/temporalio/worker/workflow_executor.rb +26 -0
  161. data/lib/temporalio/worker/workflow_replayer.rb +343 -0
  162. data/lib/temporalio/worker.rb +569 -0
  163. data/lib/temporalio/workflow/activity_cancellation_type.rb +20 -0
  164. data/lib/temporalio/workflow/child_workflow_cancellation_type.rb +21 -0
  165. data/lib/temporalio/workflow/child_workflow_handle.rb +43 -0
  166. data/lib/temporalio/workflow/definition.rb +566 -0
  167. data/lib/temporalio/workflow/external_workflow_handle.rb +41 -0
  168. data/lib/temporalio/workflow/future.rb +151 -0
  169. data/lib/temporalio/workflow/handler_unfinished_policy.rb +13 -0
  170. data/lib/temporalio/workflow/info.rb +82 -0
  171. data/lib/temporalio/workflow/parent_close_policy.rb +19 -0
  172. data/lib/temporalio/workflow/update_info.rb +20 -0
  173. data/lib/temporalio/workflow.rb +529 -0
  174. data/lib/temporalio/workflow_history.rb +47 -0
  175. data/lib/temporalio.rb +11 -0
  176. data/temporalio.gemspec +28 -0
  177. metadata +238 -0
@@ -0,0 +1,343 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'temporalio/api'
4
+ require 'temporalio/converters'
5
+ require 'temporalio/internal/bridge'
6
+ require 'temporalio/internal/bridge/worker'
7
+ require 'temporalio/internal/worker/multi_runner'
8
+ require 'temporalio/internal/worker/workflow_worker'
9
+ require 'temporalio/worker/interceptor'
10
+ require 'temporalio/worker/thread_pool'
11
+ require 'temporalio/worker/tuner'
12
+ require 'temporalio/worker/workflow_executor'
13
+ require 'temporalio/workflow'
14
+ require 'temporalio/workflow_history'
15
+
16
+ module Temporalio
17
+ class Worker
18
+ # Replayer to replay workflows from existing history.
19
+ class WorkflowReplayer
20
+ Options = Data.define(
21
+ :workflows,
22
+ :namespace,
23
+ :task_queue,
24
+ :data_converter,
25
+ :workflow_executor,
26
+ :interceptors,
27
+ :build_id,
28
+ :identity,
29
+ :logger,
30
+ :illegal_workflow_calls,
31
+ :workflow_failure_exception_types,
32
+ :workflow_payload_codec_thread_pool,
33
+ :debug_mode,
34
+ :runtime
35
+ )
36
+
37
+ # Options as returned from {options} representing the options passed to the constructor.
38
+ class Options; end # rubocop:disable Lint/EmptyClass
39
+
40
+ # @return [Options] Options for this replayer which has the same attributes as {initialize}.
41
+ attr_reader :options
42
+
43
+ # Create a new replayer. This combines some options from both {Worker.initialize} and {Client.initialize}.
44
+ #
45
+ # @param workflows [Array<Class<Workflow::Definition>>] Workflows for this replayer.
46
+ # @param namespace [String] Namespace as set in the workflow info.
47
+ # @param task_queue [String] Task queue as set in the workflow info.
48
+ # @param data_converter [Converters::DataConverter] Data converter to use for all data conversions to/from
49
+ # payloads.
50
+ # @param workflow_executor [WorkflowExecutor] Workflow executor that workflow tasks run within. This must be a
51
+ # {WorkflowExecutor::ThreadPool} currently.
52
+ # @param interceptors [Array<Interceptor::Workflow>] Workflow interceptors.
53
+ # @param build_id [String] Unique identifier for the current runtime. This is best set as a unique value
54
+ # representing all code and should change only when code does. This can be something like a git commit hash. If
55
+ # unset, default is hash of known Ruby code.
56
+ # @param identity [String, nil] Override the identity for this replater.
57
+ # @param logger [Logger] Logger to use. Defaults to stdout with warn level. Callers setting this logger are
58
+ # responsible for closing it.
59
+ # @param illegal_workflow_calls [Hash<String, [:all, Array<Symbol>]>] Set of illegal workflow calls that are
60
+ # considered unsafe/non-deterministic and will raise if seen. The key of the hash is the fully qualified string
61
+ # class name (no leading `::`). The value is either `:all` which means any use of the class, or an array of
62
+ # symbols for methods on the class that cannot be used. The methods refer to either instance or class methods,
63
+ # there is no way to differentiate at this time.
64
+ # @param workflow_failure_exception_types [Array<Class<Exception>>] Workflow failure exception types. This is the
65
+ # set of exception types that, if a workflow-thrown exception extends, will cause the workflow/update to fail
66
+ # instead of suspending the workflow via task failure. These are applied in addition to the
67
+ # `workflow_failure_exception_type` on the workflow definition class itself. If {::Exception} is set, it
68
+ # effectively will fail a workflow/update in all user exception cases.
69
+ # @param workflow_payload_codec_thread_pool [ThreadPool, nil] Thread pool to run payload codec encode/decode
70
+ # within. This is required if a payload codec exists and the worker is not fiber based. Codecs can potentially
71
+ # block execution which is why they need to be run in the background.
72
+ # @param debug_mode [Boolean] If true, deadlock detection is disabled. Deadlock detection will fail workflow tasks
73
+ # if they block the thread for too long. This defaults to true if the `TEMPORAL_DEBUG` environment variable is
74
+ # `true` or `1`.
75
+ # @param runtime [Runtime] Runtime for this replayer.
76
+ #
77
+ # @yield If a block is present, this is the equivalent of calling {with_replay_worker} with the block and
78
+ # discarding the result.
79
+ def initialize(
80
+ workflows:,
81
+ namespace: 'ReplayNamespace',
82
+ task_queue: 'ReplayTaskQueue',
83
+ data_converter: Converters::DataConverter.default,
84
+ workflow_executor: WorkflowExecutor::ThreadPool.default,
85
+ interceptors: [],
86
+ build_id: Worker.default_build_id,
87
+ identity: nil,
88
+ logger: Logger.new($stdout, level: Logger::WARN),
89
+ illegal_workflow_calls: Worker.default_illegal_workflow_calls,
90
+ workflow_failure_exception_types: [],
91
+ workflow_payload_codec_thread_pool: nil,
92
+ debug_mode: %w[true 1].include?(ENV['TEMPORAL_DEBUG'].to_s.downcase),
93
+ runtime: Runtime.default,
94
+ &
95
+ )
96
+ @options = Options.new(
97
+ workflows:,
98
+ namespace:,
99
+ task_queue:,
100
+ data_converter:,
101
+ workflow_executor:,
102
+ interceptors:,
103
+ build_id:,
104
+ identity:,
105
+ logger:,
106
+ illegal_workflow_calls:,
107
+ workflow_failure_exception_types:,
108
+ workflow_payload_codec_thread_pool:,
109
+ debug_mode:,
110
+ runtime:
111
+ ).freeze
112
+ # Preload definitions and other settings
113
+ @workflow_definitions = Internal::Worker::WorkflowWorker.workflow_definitions(workflows)
114
+ @nondeterminism_as_workflow_fail, @nondeterminism_as_workflow_fail_for_types =
115
+ Internal::Worker::WorkflowWorker.bridge_workflow_failure_exception_type_options(
116
+ workflow_failure_exception_types:, workflow_definitions: @workflow_definitions
117
+ )
118
+ # If there is a block, we'll go ahead and assume it's for with_replay_worker
119
+ with_replay_worker(&) if block_given? # steep:ignore
120
+ end
121
+
122
+ # Replay a workflow history.
123
+ #
124
+ # If doing multiple histories, it is better to use {replay_workflows} or {with_replay_worker} since they create
125
+ # a replay worker just once instead of each time like this call does.
126
+ #
127
+ # @param history [WorkflowHistory] History to replay.
128
+ # @param raise_on_replay_failure [Boolean] If true, the default, this will raise an exception on any replay
129
+ # failure. If false and the replay fails, the failure will be available in {ReplayResult.replay_failure}.
130
+ #
131
+ # @return [ReplayResult] Result of the replay.
132
+ def replay_workflow(history, raise_on_replay_failure: true)
133
+ with_replay_worker { |worker| worker.replay_workflow(history, raise_on_replay_failure:) }
134
+ end
135
+
136
+ # Replay multiple workflow histories.
137
+ #
138
+ # @param histories [Enumerable<WorkflowHistory>] Histories to replay.
139
+ # @param raise_on_replay_failure [Boolean] If true, this will raise an exception on any replay failure. If false,
140
+ # the default, and the replay fails, the failure will be available in {ReplayResult.replay_failure}.
141
+ #
142
+ # @return [Array<ReplayResult>] Results of the replay.
143
+ def replay_workflows(histories, raise_on_replay_failure: false)
144
+ with_replay_worker do |worker|
145
+ histories.map { |h| worker.replay_workflow(h, raise_on_replay_failure:) }
146
+ end
147
+ end
148
+
149
+ # Run a block of code with a {ReplayWorker} to execute replays.
150
+ #
151
+ # @yield Block of code to run with a replay worker.
152
+ # @yieldparam [ReplayWorker] Worker to run replays on. Note, only one workflow can replay at a time.
153
+ # @yieldreturn [Object] Result of the block.
154
+ def with_replay_worker(&)
155
+ worker = ReplayWorker.new(
156
+ options:,
157
+ workflow_definitions: @workflow_definitions,
158
+ nondeterminism_as_workflow_fail: @nondeterminism_as_workflow_fail,
159
+ nondeterminism_as_workflow_fail_for_types: @nondeterminism_as_workflow_fail_for_types
160
+ )
161
+ begin
162
+ yield worker
163
+ ensure
164
+ worker._shutdown
165
+ end
166
+ end
167
+
168
+ # Result of a single workflow replay run.
169
+ class ReplayResult
170
+ # @return [WorkflowHistory] History originally passed in to the replayer.
171
+ attr_reader :history
172
+
173
+ # @return [Exception, nil] Failure during replay if any.
174
+ attr_reader :replay_failure
175
+
176
+ # @!visibility private
177
+ def initialize(history:, replay_failure:)
178
+ @history = history
179
+ @replay_failure = replay_failure
180
+ end
181
+ end
182
+
183
+ # Replay worker that can be used to replay individual workflow runs. Only one call to {replay_workflow} can be
184
+ # made at a time.
185
+ class ReplayWorker
186
+ # @!visibility private
187
+ def initialize(
188
+ options:,
189
+ workflow_definitions:,
190
+ nondeterminism_as_workflow_fail:,
191
+ nondeterminism_as_workflow_fail_for_types:
192
+ )
193
+ # Create the bridge worker and the replayer
194
+ @bridge_replayer, @bridge_worker = Internal::Bridge::Worker::WorkflowReplayer.new(
195
+ options.runtime._core_runtime,
196
+ Internal::Bridge::Worker::Options.new(
197
+ activity: false,
198
+ workflow: true,
199
+ namespace: options.namespace,
200
+ task_queue: options.task_queue,
201
+ tuner: Tuner.create_fixed(
202
+ workflow_slots: 2, activity_slots: 1, local_activity_slots: 1
203
+ )._to_bridge_options,
204
+ build_id: options.build_id,
205
+ identity_override: options.identity,
206
+ max_cached_workflows: 2,
207
+ max_concurrent_workflow_task_polls: 1,
208
+ nonsticky_to_sticky_poll_ratio: 1.0,
209
+ max_concurrent_activity_task_polls: 1,
210
+ no_remote_activities: true,
211
+ sticky_queue_schedule_to_start_timeout: 1.0,
212
+ max_heartbeat_throttle_interval: 1.0,
213
+ default_heartbeat_throttle_interval: 1.0,
214
+ max_worker_activities_per_second: nil,
215
+ max_task_queue_activities_per_second: nil,
216
+ graceful_shutdown_period: 0.0,
217
+ use_worker_versioning: false,
218
+ nondeterminism_as_workflow_fail:,
219
+ nondeterminism_as_workflow_fail_for_types:
220
+ )
221
+ )
222
+
223
+ # Create the workflow worker
224
+ @workflow_worker = Internal::Worker::WorkflowWorker.new(
225
+ bridge_worker: @bridge_worker,
226
+ namespace: options.namespace,
227
+ task_queue: options.task_queue,
228
+ workflow_definitions:,
229
+ workflow_executor: options.workflow_executor,
230
+ logger: options.logger,
231
+ data_converter: options.data_converter,
232
+ metric_meter: options.runtime.metric_meter,
233
+ workflow_interceptors: options.interceptors.select do |i|
234
+ i.is_a?(Interceptor::Workflow)
235
+ end,
236
+ disable_eager_activity_execution: false,
237
+ illegal_workflow_calls: options.illegal_workflow_calls,
238
+ workflow_failure_exception_types: options.workflow_failure_exception_types,
239
+ workflow_payload_codec_thread_pool: options.workflow_payload_codec_thread_pool,
240
+ debug_mode: options.debug_mode,
241
+ on_eviction: proc { |_, remove_job| @last_workflow_remove_job = remove_job } # steep:ignore
242
+ )
243
+
244
+ # Create the runner
245
+ @runner = Internal::Worker::MultiRunner.new(workers: [self], shutdown_signals: [])
246
+ end
247
+
248
+ # Replay a workflow history.
249
+ #
250
+ # @param history [WorkflowHistory] History to replay.
251
+ # @param raise_on_replay_failure [Boolean] If true, the default, this will raise an exception on any replay
252
+ # failure. If false and the replay fails, the failure will be available in {ReplayResult.replay_failure}.
253
+ #
254
+ # @return [ReplayResult] Result of the replay.
255
+ def replay_workflow(history, raise_on_replay_failure: true)
256
+ raise ArgumentError, 'Expected history as WorkflowHistory' unless history.is_a?(WorkflowHistory)
257
+ # Due to our event processing model, only one can run at a time
258
+ raise 'Already running' if @running
259
+ raise 'Replayer shutdown' if @shutdown
260
+
261
+ # Push history proto
262
+ # TODO(cretz): Unset this
263
+ @running = true
264
+ @last_workflow_remove_job = nil
265
+ begin
266
+ @bridge_replayer.push_history(
267
+ history.workflow_id, Api::History::V1::History.new(events: history.events).to_proto
268
+ )
269
+
270
+ # Process events until workflow complete
271
+ until @last_workflow_remove_job
272
+ event = @runner.next_event
273
+ case event
274
+ when Internal::Worker::MultiRunner::Event::PollSuccess
275
+ @workflow_worker.handle_activation(
276
+ runner: @runner,
277
+ activation: Internal::Bridge::Api::WorkflowActivation::WorkflowActivation.decode(event.bytes),
278
+ decoded: false
279
+ )
280
+ when Internal::Worker::MultiRunner::Event::WorkflowActivationDecoded
281
+ @workflow_worker.handle_activation(runner: @runner, activation: event.activation, decoded: true)
282
+ when Internal::Worker::MultiRunner::Event::WorkflowActivationComplete
283
+ @workflow_worker.handle_activation_complete(
284
+ runner: @runner,
285
+ activation_completion: event.activation_completion,
286
+ encoded: event.encoded,
287
+ completion_complete_queue: event.completion_complete_queue
288
+ )
289
+ when Internal::Worker::MultiRunner::Event::WorkflowActivationCompletionComplete
290
+ # Ignore
291
+ else
292
+ raise "Unexpected event: #{event}"
293
+ end
294
+ end
295
+
296
+ # Create exception if removal is due to error
297
+ err = if @last_workflow_remove_job.reason == :NONDETERMINISM
298
+ Workflow::NondeterminismError.new(
299
+ "#{@last_workflow_remove_job.reason}: #{@last_workflow_remove_job.message}"
300
+ )
301
+ elsif !%i[CACHE_FULL LANG_REQUESTED].include?(@last_workflow_remove_job.reason)
302
+ Workflow::InvalidWorkflowStateError.new(
303
+ "#{@last_workflow_remove_job.reason}: #{@last_workflow_remove_job.message}"
304
+ )
305
+ end
306
+ # Raise if wanting to raise, otherwise return result
307
+ raise err if raise_on_replay_failure && err
308
+
309
+ ReplayResult.new(history:, replay_failure: err)
310
+ ensure
311
+ @running = false
312
+ end
313
+ end
314
+
315
+ # @!visibility private
316
+ def _shutdown
317
+ @shutdown = true
318
+ @runner.initiate_shutdown
319
+ # Wait for all-pollers-shutdown before finalizing
320
+ until @runner.next_event.is_a?(Internal::Worker::MultiRunner::Event::AllPollersShutDown); end
321
+ @runner.wait_complete_and_finalize_shutdown
322
+ @workflow_worker.on_shutdown_complete
323
+ @workflow_worker = nil
324
+ end
325
+
326
+ # @!visibility private
327
+ def _bridge_worker
328
+ @bridge_worker
329
+ end
330
+
331
+ # @!visibility private
332
+ def _initiate_shutdown
333
+ _bridge_worker.initiate_shutdown
334
+ end
335
+
336
+ # @!visibility private
337
+ def _wait_all_complete
338
+ # Do nothing
339
+ end
340
+ end
341
+ end
342
+ end
343
+ end