temporalio 0.4.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.
Files changed (183) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +2 -0
  3. data/Gemfile +27 -0
  4. data/Rakefile +101 -0
  5. data/lib/temporalio/activity/complete_async_error.rb +11 -0
  6. data/lib/temporalio/activity/context.rb +123 -0
  7. data/lib/temporalio/activity/definition.rb +192 -0
  8. data/lib/temporalio/activity/info.rb +67 -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 +36 -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 +48 -0
  27. data/lib/temporalio/api/deployment/v1/message.rb +38 -0
  28. data/lib/temporalio/api/enums/v1/batch_operation.rb +22 -0
  29. data/lib/temporalio/api/enums/v1/command_type.rb +21 -0
  30. data/lib/temporalio/api/enums/v1/common.rb +26 -0
  31. data/lib/temporalio/api/enums/v1/deployment.rb +23 -0
  32. data/lib/temporalio/api/enums/v1/event_type.rb +21 -0
  33. data/lib/temporalio/api/enums/v1/failed_cause.rb +26 -0
  34. data/lib/temporalio/api/enums/v1/namespace.rb +23 -0
  35. data/lib/temporalio/api/enums/v1/nexus.rb +21 -0
  36. data/lib/temporalio/api/enums/v1/query.rb +22 -0
  37. data/lib/temporalio/api/enums/v1/reset.rb +23 -0
  38. data/lib/temporalio/api/enums/v1/schedule.rb +21 -0
  39. data/lib/temporalio/api/enums/v1/task_queue.rb +25 -0
  40. data/lib/temporalio/api/enums/v1/update.rb +22 -0
  41. data/lib/temporalio/api/enums/v1/workflow.rb +31 -0
  42. data/lib/temporalio/api/errordetails/v1/message.rb +44 -0
  43. data/lib/temporalio/api/export/v1/message.rb +24 -0
  44. data/lib/temporalio/api/failure/v1/message.rb +37 -0
  45. data/lib/temporalio/api/filter/v1/message.rb +27 -0
  46. data/lib/temporalio/api/history/v1/message.rb +92 -0
  47. data/lib/temporalio/api/namespace/v1/message.rb +31 -0
  48. data/lib/temporalio/api/nexus/v1/message.rb +41 -0
  49. data/lib/temporalio/api/operatorservice/v1/request_response.rb +49 -0
  50. data/lib/temporalio/api/operatorservice/v1/service.rb +23 -0
  51. data/lib/temporalio/api/operatorservice.rb +3 -0
  52. data/lib/temporalio/api/payload_visitor.rb +1581 -0
  53. data/lib/temporalio/api/protocol/v1/message.rb +23 -0
  54. data/lib/temporalio/api/query/v1/message.rb +28 -0
  55. data/lib/temporalio/api/replication/v1/message.rb +26 -0
  56. data/lib/temporalio/api/schedule/v1/message.rb +43 -0
  57. data/lib/temporalio/api/sdk/v1/enhanced_stack_trace.rb +25 -0
  58. data/lib/temporalio/api/sdk/v1/task_complete_metadata.rb +21 -0
  59. data/lib/temporalio/api/sdk/v1/user_metadata.rb +23 -0
  60. data/lib/temporalio/api/sdk/v1/workflow_metadata.rb +23 -0
  61. data/lib/temporalio/api/taskqueue/v1/message.rb +48 -0
  62. data/lib/temporalio/api/testservice/v1/request_response.rb +31 -0
  63. data/lib/temporalio/api/testservice/v1/service.rb +23 -0
  64. data/lib/temporalio/api/update/v1/message.rb +33 -0
  65. data/lib/temporalio/api/version/v1/message.rb +26 -0
  66. data/lib/temporalio/api/workflow/v1/message.rb +51 -0
  67. data/lib/temporalio/api/workflowservice/v1/request_response.rb +233 -0
  68. data/lib/temporalio/api/workflowservice/v1/service.rb +23 -0
  69. data/lib/temporalio/api/workflowservice.rb +3 -0
  70. data/lib/temporalio/api.rb +15 -0
  71. data/lib/temporalio/cancellation.rb +170 -0
  72. data/lib/temporalio/client/activity_id_reference.rb +32 -0
  73. data/lib/temporalio/client/async_activity_handle.rb +85 -0
  74. data/lib/temporalio/client/connection/cloud_service.rb +726 -0
  75. data/lib/temporalio/client/connection/operator_service.rb +201 -0
  76. data/lib/temporalio/client/connection/service.rb +42 -0
  77. data/lib/temporalio/client/connection/test_service.rb +111 -0
  78. data/lib/temporalio/client/connection/workflow_service.rb +1251 -0
  79. data/lib/temporalio/client/connection.rb +316 -0
  80. data/lib/temporalio/client/interceptor.rb +455 -0
  81. data/lib/temporalio/client/schedule.rb +991 -0
  82. data/lib/temporalio/client/schedule_handle.rb +126 -0
  83. data/lib/temporalio/client/with_start_workflow_operation.rb +115 -0
  84. data/lib/temporalio/client/workflow_execution.rb +119 -0
  85. data/lib/temporalio/client/workflow_execution_count.rb +36 -0
  86. data/lib/temporalio/client/workflow_execution_status.rb +18 -0
  87. data/lib/temporalio/client/workflow_handle.rb +389 -0
  88. data/lib/temporalio/client/workflow_query_reject_condition.rb +14 -0
  89. data/lib/temporalio/client/workflow_update_handle.rb +65 -0
  90. data/lib/temporalio/client/workflow_update_wait_stage.rb +17 -0
  91. data/lib/temporalio/client.rb +607 -0
  92. data/lib/temporalio/common_enums.rb +41 -0
  93. data/lib/temporalio/contrib/open_telemetry.rb +470 -0
  94. data/lib/temporalio/converters/data_converter.rb +99 -0
  95. data/lib/temporalio/converters/failure_converter.rb +202 -0
  96. data/lib/temporalio/converters/payload_codec.rb +26 -0
  97. data/lib/temporalio/converters/payload_converter/binary_null.rb +34 -0
  98. data/lib/temporalio/converters/payload_converter/binary_plain.rb +35 -0
  99. data/lib/temporalio/converters/payload_converter/binary_protobuf.rb +42 -0
  100. data/lib/temporalio/converters/payload_converter/composite.rb +66 -0
  101. data/lib/temporalio/converters/payload_converter/encoding.rb +35 -0
  102. data/lib/temporalio/converters/payload_converter/json_plain.rb +44 -0
  103. data/lib/temporalio/converters/payload_converter/json_protobuf.rb +41 -0
  104. data/lib/temporalio/converters/payload_converter.rb +71 -0
  105. data/lib/temporalio/converters/raw_value.rb +20 -0
  106. data/lib/temporalio/converters.rb +9 -0
  107. data/lib/temporalio/error/failure.rb +219 -0
  108. data/lib/temporalio/error.rb +156 -0
  109. data/lib/temporalio/internal/bridge/3.2/temporalio_bridge.so +0 -0
  110. data/lib/temporalio/internal/bridge/3.3/temporalio_bridge.so +0 -0
  111. data/lib/temporalio/internal/bridge/3.4/temporalio_bridge.so +0 -0
  112. data/lib/temporalio/internal/bridge/api/activity_result/activity_result.rb +34 -0
  113. data/lib/temporalio/internal/bridge/api/activity_task/activity_task.rb +31 -0
  114. data/lib/temporalio/internal/bridge/api/child_workflow/child_workflow.rb +33 -0
  115. data/lib/temporalio/internal/bridge/api/common/common.rb +27 -0
  116. data/lib/temporalio/internal/bridge/api/core_interface.rb +40 -0
  117. data/lib/temporalio/internal/bridge/api/external_data/external_data.rb +27 -0
  118. data/lib/temporalio/internal/bridge/api/nexus/nexus.rb +33 -0
  119. data/lib/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rb +56 -0
  120. data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +57 -0
  121. data/lib/temporalio/internal/bridge/api/workflow_completion/workflow_completion.rb +31 -0
  122. data/lib/temporalio/internal/bridge/api.rb +3 -0
  123. data/lib/temporalio/internal/bridge/client.rb +95 -0
  124. data/lib/temporalio/internal/bridge/runtime.rb +56 -0
  125. data/lib/temporalio/internal/bridge/testing.rb +69 -0
  126. data/lib/temporalio/internal/bridge/worker.rb +85 -0
  127. data/lib/temporalio/internal/bridge.rb +36 -0
  128. data/lib/temporalio/internal/client/implementation.rb +922 -0
  129. data/lib/temporalio/internal/metric.rb +122 -0
  130. data/lib/temporalio/internal/proto_utils.rb +165 -0
  131. data/lib/temporalio/internal/worker/activity_worker.rb +385 -0
  132. data/lib/temporalio/internal/worker/multi_runner.rb +213 -0
  133. data/lib/temporalio/internal/worker/workflow_instance/child_workflow_handle.rb +54 -0
  134. data/lib/temporalio/internal/worker/workflow_instance/context.rb +383 -0
  135. data/lib/temporalio/internal/worker/workflow_instance/details.rb +46 -0
  136. data/lib/temporalio/internal/worker/workflow_instance/external_workflow_handle.rb +32 -0
  137. data/lib/temporalio/internal/worker/workflow_instance/externally_immutable_hash.rb +22 -0
  138. data/lib/temporalio/internal/worker/workflow_instance/handler_execution.rb +25 -0
  139. data/lib/temporalio/internal/worker/workflow_instance/handler_hash.rb +41 -0
  140. data/lib/temporalio/internal/worker/workflow_instance/illegal_call_tracer.rb +97 -0
  141. data/lib/temporalio/internal/worker/workflow_instance/inbound_implementation.rb +62 -0
  142. data/lib/temporalio/internal/worker/workflow_instance/outbound_implementation.rb +400 -0
  143. data/lib/temporalio/internal/worker/workflow_instance/replay_safe_logger.rb +37 -0
  144. data/lib/temporalio/internal/worker/workflow_instance/replay_safe_metric.rb +40 -0
  145. data/lib/temporalio/internal/worker/workflow_instance/scheduler.rb +183 -0
  146. data/lib/temporalio/internal/worker/workflow_instance.rb +774 -0
  147. data/lib/temporalio/internal/worker/workflow_worker.rb +239 -0
  148. data/lib/temporalio/internal.rb +7 -0
  149. data/lib/temporalio/metric.rb +109 -0
  150. data/lib/temporalio/retry_policy.rb +74 -0
  151. data/lib/temporalio/runtime/metric_buffer.rb +94 -0
  152. data/lib/temporalio/runtime.rb +352 -0
  153. data/lib/temporalio/scoped_logger.rb +96 -0
  154. data/lib/temporalio/search_attributes.rb +356 -0
  155. data/lib/temporalio/testing/activity_environment.rb +160 -0
  156. data/lib/temporalio/testing/workflow_environment.rb +406 -0
  157. data/lib/temporalio/testing.rb +10 -0
  158. data/lib/temporalio/version.rb +5 -0
  159. data/lib/temporalio/worker/activity_executor/fiber.rb +49 -0
  160. data/lib/temporalio/worker/activity_executor/thread_pool.rb +46 -0
  161. data/lib/temporalio/worker/activity_executor.rb +55 -0
  162. data/lib/temporalio/worker/interceptor.rb +365 -0
  163. data/lib/temporalio/worker/thread_pool.rb +237 -0
  164. data/lib/temporalio/worker/tuner.rb +189 -0
  165. data/lib/temporalio/worker/workflow_executor/thread_pool.rb +235 -0
  166. data/lib/temporalio/worker/workflow_executor.rb +26 -0
  167. data/lib/temporalio/worker/workflow_replayer.rb +350 -0
  168. data/lib/temporalio/worker.rb +603 -0
  169. data/lib/temporalio/workflow/activity_cancellation_type.rb +20 -0
  170. data/lib/temporalio/workflow/child_workflow_cancellation_type.rb +21 -0
  171. data/lib/temporalio/workflow/child_workflow_handle.rb +43 -0
  172. data/lib/temporalio/workflow/definition.rb +598 -0
  173. data/lib/temporalio/workflow/external_workflow_handle.rb +41 -0
  174. data/lib/temporalio/workflow/future.rb +151 -0
  175. data/lib/temporalio/workflow/handler_unfinished_policy.rb +13 -0
  176. data/lib/temporalio/workflow/info.rb +104 -0
  177. data/lib/temporalio/workflow/parent_close_policy.rb +19 -0
  178. data/lib/temporalio/workflow/update_info.rb +20 -0
  179. data/lib/temporalio/workflow.rb +575 -0
  180. data/lib/temporalio/workflow_history.rb +47 -0
  181. data/lib/temporalio.rb +11 -0
  182. data/temporalio.gemspec +29 -0
  183. metadata +258 -0
@@ -0,0 +1,213 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'singleton'
4
+ require 'temporalio/internal/bridge/worker'
5
+
6
+ module Temporalio
7
+ module Internal
8
+ module Worker
9
+ # Primary worker (re)actor-style event handler. This handles multiple workers, receiving events from the bridge,
10
+ # and handling a user block.
11
+ class MultiRunner
12
+ def initialize(workers:, shutdown_signals:)
13
+ @workers = workers
14
+ @queue = Queue.new
15
+
16
+ @shutdown_initiated_mutex = Mutex.new
17
+ @shutdown_initiated = false
18
+
19
+ # Trap signals to push to queue
20
+ shutdown_signals.each do |signal|
21
+ Signal.trap(signal) { @queue.push(Event::ShutdownSignalReceived.new) }
22
+ end
23
+
24
+ # Start pollers
25
+ Bridge::Worker.async_poll_all(workers.map(&:_bridge_worker), @queue)
26
+ end
27
+
28
+ def apply_thread_or_fiber_block(&)
29
+ return unless block_given?
30
+
31
+ @thread_or_fiber = if Fiber.current_scheduler
32
+ Fiber.schedule do
33
+ @queue.push(Event::BlockSuccess.new(result: yield))
34
+ rescue InjectEventForTesting => e
35
+ @queue.push(e.event)
36
+ @queue.push(Event::BlockSuccess.new(result: e))
37
+ rescue Exception => e # rubocop:disable Lint/RescueException -- Intentionally catch all
38
+ @queue.push(Event::BlockFailure.new(error: e))
39
+ end
40
+ else
41
+ Thread.new do
42
+ @queue.push(Event::BlockSuccess.new(result: yield))
43
+ rescue InjectEventForTesting => e
44
+ @queue.push(e.event)
45
+ @queue.push(Event::BlockSuccess.new(result: e))
46
+ rescue Exception => e # rubocop:disable Lint/RescueException -- Intentionally catch all
47
+ @queue.push(Event::BlockFailure.new(error: e))
48
+ end
49
+ end
50
+ end
51
+
52
+ def apply_workflow_activation_decoded(workflow_worker:, activation:)
53
+ @queue.push(Event::WorkflowActivationDecoded.new(workflow_worker:, activation:))
54
+ end
55
+
56
+ def apply_workflow_activation_complete(workflow_worker:, activation_completion:, encoded:)
57
+ @queue.push(Event::WorkflowActivationComplete.new(
58
+ workflow_worker:, activation_completion:, encoded:, completion_complete_queue: @queue
59
+ ))
60
+ end
61
+
62
+ def raise_in_thread_or_fiber_block(error)
63
+ @thread_or_fiber&.raise(error)
64
+ end
65
+
66
+ # Clarify this is the only thread-safe function here
67
+ def initiate_shutdown
68
+ should_call = @shutdown_initiated_mutex.synchronize do
69
+ break false if @shutdown_initiated
70
+
71
+ @shutdown_initiated = true
72
+ end
73
+ return unless should_call
74
+
75
+ @workers.each(&:_initiate_shutdown)
76
+ end
77
+
78
+ def wait_complete_and_finalize_shutdown
79
+ # Wait for them all to complete
80
+ @workers.each(&:_wait_all_complete)
81
+
82
+ # Finalize them all
83
+ Bridge::Worker.finalize_shutdown_all(@workers.map(&:_bridge_worker))
84
+ end
85
+
86
+ # Intentionally not an enumerable/enumerator since stop semantics are
87
+ # caller determined
88
+ def next_event
89
+ # Queue value is one of the following:
90
+ # * Event - non-poller event
91
+ # * [worker index, :activity/:workflow, bytes] - poll success
92
+ # * [worker index, :activity/:workflow, error] - poll fail
93
+ # * [worker index, :activity/:workflow, nil] - worker shutdown
94
+ # * [nil, nil, nil] - all pollers done
95
+ # * [-1, run_id_string, error_or_nil] - workflow activation completion complete
96
+ result = @queue.pop
97
+ if result.is_a?(Event)
98
+ result
99
+ else
100
+ first, second, third = result
101
+ if first.nil? || second.nil?
102
+ Event::AllPollersShutDown.instance
103
+ elsif first == -1
104
+ Event::WorkflowActivationCompletionComplete.new(run_id: second, error: third)
105
+ else
106
+ worker = @workers[first]
107
+ case third
108
+ when nil
109
+ Event::PollerShutDown.new(worker:, worker_type: second)
110
+ when Exception
111
+ Event::PollFailure.new(worker:, worker_type: second, error: third)
112
+ else
113
+ Event::PollSuccess.new(worker:, worker_type: second, bytes: third)
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ class Event
120
+ class PollSuccess < Event
121
+ attr_reader :worker, :worker_type, :bytes
122
+
123
+ def initialize(worker:, worker_type:, bytes:) # rubocop:disable Lint/MissingSuper
124
+ @worker = worker
125
+ @worker_type = worker_type
126
+ @bytes = bytes
127
+ end
128
+ end
129
+
130
+ class PollFailure < Event
131
+ attr_reader :worker, :worker_type, :error
132
+
133
+ def initialize(worker:, worker_type:, error:) # rubocop:disable Lint/MissingSuper
134
+ @worker = worker
135
+ @worker_type = worker_type
136
+ @error = error
137
+ end
138
+ end
139
+
140
+ class WorkflowActivationDecoded < Event
141
+ attr_reader :workflow_worker, :activation
142
+
143
+ def initialize(workflow_worker:, activation:) # rubocop:disable Lint/MissingSuper
144
+ @workflow_worker = workflow_worker
145
+ @activation = activation
146
+ end
147
+ end
148
+
149
+ class WorkflowActivationComplete < Event
150
+ attr_reader :workflow_worker, :activation_completion, :encoded, :completion_complete_queue
151
+
152
+ def initialize(workflow_worker:, activation_completion:, encoded:, completion_complete_queue:) # rubocop:disable Lint/MissingSuper
153
+ @workflow_worker = workflow_worker
154
+ @activation_completion = activation_completion
155
+ @encoded = encoded
156
+ @completion_complete_queue = completion_complete_queue
157
+ end
158
+ end
159
+
160
+ class WorkflowActivationCompletionComplete < Event
161
+ attr_reader :run_id, :error
162
+
163
+ def initialize(run_id:, error:) # rubocop:disable Lint/MissingSuper
164
+ @run_id = run_id
165
+ @error = error
166
+ end
167
+ end
168
+
169
+ class PollerShutDown < Event
170
+ attr_reader :worker, :worker_type
171
+
172
+ def initialize(worker:, worker_type:) # rubocop:disable Lint/MissingSuper
173
+ @worker = worker
174
+ @worker_type = worker_type
175
+ end
176
+ end
177
+
178
+ class AllPollersShutDown < Event
179
+ include Singleton
180
+ end
181
+
182
+ class BlockSuccess < Event
183
+ attr_reader :result
184
+
185
+ def initialize(result:) # rubocop:disable Lint/MissingSuper
186
+ @result = result
187
+ end
188
+ end
189
+
190
+ class BlockFailure < Event
191
+ attr_reader :error
192
+
193
+ def initialize(error:) # rubocop:disable Lint/MissingSuper
194
+ @error = error
195
+ end
196
+ end
197
+
198
+ class ShutdownSignalReceived < Event
199
+ end
200
+ end
201
+
202
+ class InjectEventForTesting < Temporalio::Error
203
+ attr_reader :event
204
+
205
+ def initialize(event)
206
+ super('Injecting event for testing')
207
+ @event = event
208
+ end
209
+ end
210
+ end
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'temporalio/cancellation'
4
+ require 'temporalio/workflow'
5
+ require 'temporalio/workflow/child_workflow_handle'
6
+
7
+ module Temporalio
8
+ module Internal
9
+ module Worker
10
+ class WorkflowInstance
11
+ # Implementation of the child workflow handle.
12
+ class ChildWorkflowHandle < Workflow::ChildWorkflowHandle
13
+ attr_reader :id, :first_execution_run_id
14
+
15
+ def initialize(id:, first_execution_run_id:, instance:, cancellation:, cancel_callback_key:) # rubocop:disable Lint/MissingSuper
16
+ @id = id
17
+ @first_execution_run_id = first_execution_run_id
18
+ @instance = instance
19
+ @cancellation = cancellation
20
+ @cancel_callback_key = cancel_callback_key
21
+ @resolution = nil
22
+ end
23
+
24
+ def result
25
+ # Notice that we actually provide a detached cancellation here instead of defaulting to workflow
26
+ # cancellation because we don't want workflow cancellation (or a user-provided cancellation to this result
27
+ # call) to be able to interrupt waiting on a child that may be processing the cancellation.
28
+ Workflow.wait_condition(cancellation: Cancellation.new) { @resolution }
29
+
30
+ case @resolution.status
31
+ when :completed
32
+ @instance.payload_converter.from_payload(@resolution.completed.result)
33
+ when :failed
34
+ raise @instance.failure_converter.from_failure(@resolution.failed.failure, @instance.payload_converter)
35
+ when :cancelled
36
+ raise @instance.failure_converter.from_failure(@resolution.cancelled.failure, @instance.payload_converter)
37
+ else
38
+ raise "Unrecognized resolution status: #{@resolution.status}"
39
+ end
40
+ end
41
+
42
+ def _resolve(resolution)
43
+ @cancellation.remove_cancel_callback(@cancel_callback_key)
44
+ @resolution = resolution
45
+ end
46
+
47
+ def signal(signal, *args, cancellation: Workflow.cancellation)
48
+ @instance.context._signal_child_workflow(id:, signal:, args:, cancellation:)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,383 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'temporalio/cancellation'
4
+ require 'temporalio/error'
5
+ require 'temporalio/internal/bridge/api'
6
+ require 'temporalio/internal/proto_utils'
7
+ require 'temporalio/internal/worker/workflow_instance'
8
+ require 'temporalio/internal/worker/workflow_instance/external_workflow_handle'
9
+ require 'temporalio/worker/interceptor'
10
+ require 'temporalio/workflow'
11
+
12
+ module Temporalio
13
+ module Internal
14
+ module Worker
15
+ class WorkflowInstance
16
+ # Context for all workflow calls. All calls in the {Workflow} class should call a method on this class and then
17
+ # this class can delegate the call as needed to other parts of the workflow instance system.
18
+ class Context
19
+ def initialize(instance)
20
+ @instance = instance
21
+ end
22
+
23
+ def all_handlers_finished?
24
+ @instance.in_progress_handlers.empty?
25
+ end
26
+
27
+ def cancellation
28
+ @instance.cancellation
29
+ end
30
+
31
+ def continue_as_new_suggested
32
+ @instance.continue_as_new_suggested
33
+ end
34
+
35
+ def current_details
36
+ @instance.current_details || ''
37
+ end
38
+
39
+ def current_details=(details)
40
+ raise 'Details must be a String' unless details.nil? || details.is_a?(String)
41
+
42
+ @instance.current_details = (details || '')
43
+ end
44
+
45
+ def current_history_length
46
+ @instance.current_history_length
47
+ end
48
+
49
+ def current_history_size
50
+ @instance.current_history_size
51
+ end
52
+
53
+ def current_update_info
54
+ Fiber[:__temporal_update_info]
55
+ end
56
+
57
+ def deprecate_patch(patch_id)
58
+ @instance.patch(patch_id:, deprecated: true)
59
+ end
60
+
61
+ def execute_activity(
62
+ activity,
63
+ *args,
64
+ task_queue:,
65
+ summary:,
66
+ schedule_to_close_timeout:,
67
+ schedule_to_start_timeout:,
68
+ start_to_close_timeout:,
69
+ heartbeat_timeout:,
70
+ retry_policy:,
71
+ cancellation:,
72
+ cancellation_type:,
73
+ activity_id:,
74
+ disable_eager_execution:
75
+ )
76
+ activity = case activity
77
+ when Class
78
+ Activity::Definition::Info.from_activity(activity).name&.to_s
79
+ when Symbol, String
80
+ activity.to_s
81
+ else
82
+ raise ArgumentError, 'Activity must be a definition class, or a symbol/string'
83
+ end
84
+ raise 'Cannot invoke dynamic activities' unless activity
85
+
86
+ @outbound.execute_activity(
87
+ Temporalio::Worker::Interceptor::Workflow::ExecuteActivityInput.new(
88
+ activity:,
89
+ args:,
90
+ task_queue: task_queue || info.task_queue,
91
+ summary:,
92
+ schedule_to_close_timeout:,
93
+ schedule_to_start_timeout:,
94
+ start_to_close_timeout:,
95
+ heartbeat_timeout:,
96
+ retry_policy:,
97
+ cancellation:,
98
+ cancellation_type:,
99
+ activity_id:,
100
+ disable_eager_execution: disable_eager_execution || @instance.disable_eager_activity_execution,
101
+ headers: {}
102
+ )
103
+ )
104
+ end
105
+
106
+ def execute_local_activity(
107
+ activity,
108
+ *args,
109
+ schedule_to_close_timeout:,
110
+ schedule_to_start_timeout:,
111
+ start_to_close_timeout:,
112
+ retry_policy:,
113
+ local_retry_threshold:,
114
+ cancellation:,
115
+ cancellation_type:,
116
+ activity_id:
117
+ )
118
+ activity = case activity
119
+ when Class
120
+ Activity::Definition::Info.from_activity(activity).name&.to_s
121
+ when Symbol, String
122
+ activity.to_s
123
+ else
124
+ raise ArgumentError, 'Activity must be a definition class, or a symbol/string'
125
+ end
126
+ raise 'Cannot invoke dynamic activities' unless activity
127
+
128
+ @outbound.execute_local_activity(
129
+ Temporalio::Worker::Interceptor::Workflow::ExecuteLocalActivityInput.new(
130
+ activity:,
131
+ args:,
132
+ schedule_to_close_timeout:,
133
+ schedule_to_start_timeout:,
134
+ start_to_close_timeout:,
135
+ retry_policy:,
136
+ local_retry_threshold:,
137
+ cancellation:,
138
+ cancellation_type:,
139
+ activity_id:,
140
+ headers: {}
141
+ )
142
+ )
143
+ end
144
+
145
+ def external_workflow_handle(workflow_id, run_id: nil)
146
+ ExternalWorkflowHandle.new(id: workflow_id, run_id:, instance: @instance)
147
+ end
148
+
149
+ def illegal_call_tracing_disabled(&)
150
+ @instance.illegal_call_tracing_disabled(&)
151
+ end
152
+
153
+ def info
154
+ @instance.info
155
+ end
156
+
157
+ def instance
158
+ @instance.instance
159
+ end
160
+
161
+ def initialize_continue_as_new_error(error)
162
+ @outbound.initialize_continue_as_new_error(
163
+ Temporalio::Worker::Interceptor::Workflow::InitializeContinueAsNewErrorInput.new(error:)
164
+ )
165
+ end
166
+
167
+ def io_enabled(&)
168
+ prev = @instance.io_enabled
169
+ @instance.io_enabled = true
170
+ begin
171
+ yield
172
+ ensure
173
+ @instance.io_enabled = prev
174
+ end
175
+ end
176
+
177
+ def logger
178
+ @instance.logger
179
+ end
180
+
181
+ def memo
182
+ @instance.memo
183
+ end
184
+
185
+ def metric_meter
186
+ @instance.metric_meter
187
+ end
188
+
189
+ def now
190
+ @instance.now
191
+ end
192
+
193
+ def patched(patch_id)
194
+ @instance.patch(patch_id:, deprecated: false)
195
+ end
196
+
197
+ def payload_converter
198
+ @instance.payload_converter
199
+ end
200
+
201
+ def query_handlers
202
+ @instance.query_handlers
203
+ end
204
+
205
+ def random
206
+ @instance.random
207
+ end
208
+
209
+ def replaying?
210
+ @instance.replaying
211
+ end
212
+
213
+ def search_attributes
214
+ @instance.search_attributes
215
+ end
216
+
217
+ def signal_handlers
218
+ @instance.signal_handlers
219
+ end
220
+
221
+ def sleep(duration, summary:, cancellation:)
222
+ @outbound.sleep(
223
+ Temporalio::Worker::Interceptor::Workflow::SleepInput.new(
224
+ duration:,
225
+ summary:,
226
+ cancellation:
227
+ )
228
+ )
229
+ end
230
+
231
+ def start_child_workflow(
232
+ workflow,
233
+ *args,
234
+ id:,
235
+ task_queue:,
236
+ static_summary:,
237
+ static_details:,
238
+ cancellation:,
239
+ cancellation_type:,
240
+ parent_close_policy:,
241
+ execution_timeout:,
242
+ run_timeout:,
243
+ task_timeout:,
244
+ id_reuse_policy:,
245
+ retry_policy:,
246
+ cron_schedule:,
247
+ memo:,
248
+ search_attributes:
249
+ )
250
+ @outbound.start_child_workflow(
251
+ Temporalio::Worker::Interceptor::Workflow::StartChildWorkflowInput.new(
252
+ workflow: Workflow::Definition._workflow_type_from_workflow_parameter(workflow),
253
+ args:,
254
+ id:,
255
+ task_queue:,
256
+ static_summary:,
257
+ static_details:,
258
+ cancellation:,
259
+ cancellation_type:,
260
+ parent_close_policy:,
261
+ execution_timeout:,
262
+ run_timeout:,
263
+ task_timeout:,
264
+ id_reuse_policy:,
265
+ retry_policy:,
266
+ cron_schedule:,
267
+ memo:,
268
+ search_attributes:,
269
+ headers: {}
270
+ )
271
+ )
272
+ end
273
+
274
+ def storage
275
+ @storage ||= {}
276
+ end
277
+
278
+ def timeout(duration, exception_class, *exception_args, summary:, &)
279
+ raise 'Block required for timeout' unless block_given?
280
+
281
+ # Run timer in background and block in foreground. This gives better stack traces than a future any-of race.
282
+ # We make a detached cancellation because we don't want to link to workflow cancellation.
283
+ sleep_cancel, sleep_cancel_proc = Cancellation.new
284
+ fiber = Fiber.current
285
+ Workflow::Future.new do
286
+ Workflow.sleep(duration, summary:, cancellation: sleep_cancel)
287
+ fiber.raise(exception_class, *exception_args) if fiber.alive? # steep:ignore
288
+ rescue Exception => e # rubocop:disable Lint/RescueException
289
+ # Re-raise in fiber
290
+ fiber.raise(e) if fiber.alive?
291
+ end
292
+
293
+ begin
294
+ yield
295
+ ensure
296
+ sleep_cancel_proc.call
297
+ end
298
+ end
299
+
300
+ def update_handlers
301
+ @instance.update_handlers
302
+ end
303
+
304
+ def upsert_memo(hash)
305
+ # Convert to memo, apply updates, then add the command (so command adding is post validation)
306
+ upserted_memo = ProtoUtils.memo_to_proto(hash, payload_converter)
307
+ memo._update do |new_hash|
308
+ hash.each do |key, val|
309
+ # Nil means delete
310
+ if val.nil?
311
+ new_hash.delete(key.to_s)
312
+ else
313
+ new_hash[key.to_s] = val
314
+ end
315
+ end
316
+ end
317
+ @instance.add_command(
318
+ Bridge::Api::WorkflowCommands::WorkflowCommand.new(
319
+ modify_workflow_properties: Bridge::Api::WorkflowCommands::ModifyWorkflowProperties.new(
320
+ upserted_memo:
321
+ )
322
+ )
323
+ )
324
+ end
325
+
326
+ def upsert_search_attributes(*updates)
327
+ # Apply updates then add the command (so command adding is post validation)
328
+ search_attributes._disable_mutations = false
329
+ search_attributes.update!(*updates)
330
+ @instance.add_command(
331
+ Bridge::Api::WorkflowCommands::WorkflowCommand.new(
332
+ upsert_workflow_search_attributes: Bridge::Api::WorkflowCommands::UpsertWorkflowSearchAttributes.new(
333
+ search_attributes: updates.to_h(&:_to_proto_pair)
334
+ )
335
+ )
336
+ )
337
+ ensure
338
+ search_attributes._disable_mutations = true
339
+ end
340
+
341
+ def wait_condition(cancellation:, &)
342
+ @instance.scheduler.wait_condition(cancellation:, &)
343
+ end
344
+
345
+ def _cancel_external_workflow(id:, run_id:)
346
+ @outbound.cancel_external_workflow(
347
+ Temporalio::Worker::Interceptor::Workflow::CancelExternalWorkflowInput.new(id:, run_id:)
348
+ )
349
+ end
350
+
351
+ def _outbound=(outbound)
352
+ @outbound = outbound
353
+ end
354
+
355
+ def _signal_child_workflow(id:, signal:, args:, cancellation:)
356
+ @outbound.signal_child_workflow(
357
+ Temporalio::Worker::Interceptor::Workflow::SignalChildWorkflowInput.new(
358
+ id:,
359
+ signal: Workflow::Definition::Signal._name_from_parameter(signal),
360
+ args:,
361
+ cancellation:,
362
+ headers: {}
363
+ )
364
+ )
365
+ end
366
+
367
+ def _signal_external_workflow(id:, run_id:, signal:, args:, cancellation:)
368
+ @outbound.signal_external_workflow(
369
+ Temporalio::Worker::Interceptor::Workflow::SignalExternalWorkflowInput.new(
370
+ id:,
371
+ run_id:,
372
+ signal: Workflow::Definition::Signal._name_from_parameter(signal),
373
+ args:,
374
+ cancellation:,
375
+ headers: {}
376
+ )
377
+ )
378
+ end
379
+ end
380
+ end
381
+ end
382
+ end
383
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Temporalio
4
+ module Internal
5
+ module Worker
6
+ class WorkflowInstance
7
+ # Details needed to instantiate a {WorkflowInstance}.
8
+ class Details
9
+ attr_reader :namespace, :task_queue, :definition, :initial_activation, :logger, :metric_meter,
10
+ :payload_converter, :failure_converter, :interceptors, :disable_eager_activity_execution,
11
+ :illegal_calls, :workflow_failure_exception_types, :unsafe_workflow_io_enabled
12
+
13
+ def initialize(
14
+ namespace:,
15
+ task_queue:,
16
+ definition:,
17
+ initial_activation:,
18
+ logger:,
19
+ metric_meter:,
20
+ payload_converter:,
21
+ failure_converter:,
22
+ interceptors:,
23
+ disable_eager_activity_execution:,
24
+ illegal_calls:,
25
+ workflow_failure_exception_types:,
26
+ unsafe_workflow_io_enabled:
27
+ )
28
+ @namespace = namespace
29
+ @task_queue = task_queue
30
+ @definition = definition
31
+ @initial_activation = initial_activation
32
+ @logger = logger
33
+ @metric_meter = metric_meter
34
+ @payload_converter = payload_converter
35
+ @failure_converter = failure_converter
36
+ @interceptors = interceptors
37
+ @disable_eager_activity_execution = disable_eager_activity_execution
38
+ @illegal_calls = illegal_calls
39
+ @workflow_failure_exception_types = workflow_failure_exception_types
40
+ @unsafe_workflow_io_enabled = unsafe_workflow_io_enabled
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end