temporalio 0.2.0-x86_64-darwin → 0.3.0-x86_64-darwin

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 (118) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +2 -0
  3. data/Gemfile +3 -3
  4. data/Rakefile +10 -296
  5. data/lib/temporalio/activity/complete_async_error.rb +1 -1
  6. data/lib/temporalio/activity/context.rb +5 -2
  7. data/lib/temporalio/activity/definition.rb +163 -65
  8. data/lib/temporalio/activity/info.rb +22 -21
  9. data/lib/temporalio/activity.rb +2 -59
  10. data/lib/temporalio/api/activity/v1/message.rb +25 -0
  11. data/lib/temporalio/api/cloud/account/v1/message.rb +28 -0
  12. data/lib/temporalio/api/cloud/cloudservice/v1/request_response.rb +34 -1
  13. data/lib/temporalio/api/cloud/cloudservice/v1/service.rb +1 -1
  14. data/lib/temporalio/api/cloud/identity/v1/message.rb +6 -1
  15. data/lib/temporalio/api/cloud/namespace/v1/message.rb +8 -1
  16. data/lib/temporalio/api/cloud/nexus/v1/message.rb +31 -0
  17. data/lib/temporalio/api/cloud/operation/v1/message.rb +2 -1
  18. data/lib/temporalio/api/cloud/region/v1/message.rb +2 -1
  19. data/lib/temporalio/api/cloud/resource/v1/message.rb +23 -0
  20. data/lib/temporalio/api/cloud/sink/v1/message.rb +24 -0
  21. data/lib/temporalio/api/cloud/usage/v1/message.rb +31 -0
  22. data/lib/temporalio/api/common/v1/message.rb +7 -1
  23. data/lib/temporalio/api/enums/v1/event_type.rb +1 -1
  24. data/lib/temporalio/api/enums/v1/failed_cause.rb +1 -1
  25. data/lib/temporalio/api/enums/v1/reset.rb +1 -1
  26. data/lib/temporalio/api/history/v1/message.rb +1 -1
  27. data/lib/temporalio/api/nexus/v1/message.rb +2 -2
  28. data/lib/temporalio/api/operatorservice/v1/service.rb +1 -1
  29. data/lib/temporalio/api/payload_visitor.rb +1513 -0
  30. data/lib/temporalio/api/schedule/v1/message.rb +2 -1
  31. data/lib/temporalio/api/testservice/v1/request_response.rb +31 -0
  32. data/lib/temporalio/api/testservice/v1/service.rb +23 -0
  33. data/lib/temporalio/api/workflow/v1/message.rb +1 -1
  34. data/lib/temporalio/api/workflowservice/v1/request_response.rb +17 -2
  35. data/lib/temporalio/api/workflowservice/v1/service.rb +1 -1
  36. data/lib/temporalio/api.rb +1 -0
  37. data/lib/temporalio/cancellation.rb +34 -14
  38. data/lib/temporalio/client/async_activity_handle.rb +12 -37
  39. data/lib/temporalio/client/connection/cloud_service.rb +309 -231
  40. data/lib/temporalio/client/connection/operator_service.rb +36 -84
  41. data/lib/temporalio/client/connection/service.rb +6 -5
  42. data/lib/temporalio/client/connection/test_service.rb +111 -0
  43. data/lib/temporalio/client/connection/workflow_service.rb +264 -441
  44. data/lib/temporalio/client/connection.rb +90 -44
  45. data/lib/temporalio/client/interceptor.rb +160 -60
  46. data/lib/temporalio/client/schedule.rb +967 -0
  47. data/lib/temporalio/client/schedule_handle.rb +126 -0
  48. data/lib/temporalio/client/workflow_execution.rb +7 -10
  49. data/lib/temporalio/client/workflow_handle.rb +38 -95
  50. data/lib/temporalio/client/workflow_update_handle.rb +3 -5
  51. data/lib/temporalio/client.rb +122 -42
  52. data/lib/temporalio/common_enums.rb +17 -0
  53. data/lib/temporalio/converters/data_converter.rb +4 -7
  54. data/lib/temporalio/converters/failure_converter.rb +5 -3
  55. data/lib/temporalio/converters/payload_converter/composite.rb +4 -0
  56. data/lib/temporalio/converters/payload_converter.rb +6 -8
  57. data/lib/temporalio/converters/raw_value.rb +20 -0
  58. data/lib/temporalio/error/failure.rb +1 -1
  59. data/lib/temporalio/error.rb +10 -2
  60. data/lib/temporalio/internal/bridge/3.2/temporalio_bridge.bundle +0 -0
  61. data/lib/temporalio/internal/bridge/3.3/temporalio_bridge.bundle +0 -0
  62. data/lib/temporalio/internal/bridge/{3.1 → 3.4}/temporalio_bridge.bundle +0 -0
  63. data/lib/temporalio/internal/bridge/api/core_interface.rb +5 -1
  64. data/lib/temporalio/internal/bridge/api/nexus/nexus.rb +33 -0
  65. data/lib/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rb +5 -1
  66. data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +4 -1
  67. data/lib/temporalio/internal/bridge/client.rb +11 -6
  68. data/lib/temporalio/internal/bridge/testing.rb +20 -0
  69. data/lib/temporalio/internal/bridge/worker.rb +2 -0
  70. data/lib/temporalio/internal/bridge.rb +1 -1
  71. data/lib/temporalio/internal/client/implementation.rb +245 -70
  72. data/lib/temporalio/internal/metric.rb +122 -0
  73. data/lib/temporalio/internal/proto_utils.rb +86 -7
  74. data/lib/temporalio/internal/worker/activity_worker.rb +52 -24
  75. data/lib/temporalio/internal/worker/multi_runner.rb +51 -7
  76. data/lib/temporalio/internal/worker/workflow_instance/child_workflow_handle.rb +54 -0
  77. data/lib/temporalio/internal/worker/workflow_instance/context.rb +329 -0
  78. data/lib/temporalio/internal/worker/workflow_instance/details.rb +44 -0
  79. data/lib/temporalio/internal/worker/workflow_instance/external_workflow_handle.rb +32 -0
  80. data/lib/temporalio/internal/worker/workflow_instance/externally_immutable_hash.rb +22 -0
  81. data/lib/temporalio/internal/worker/workflow_instance/handler_execution.rb +25 -0
  82. data/lib/temporalio/internal/worker/workflow_instance/handler_hash.rb +41 -0
  83. data/lib/temporalio/internal/worker/workflow_instance/illegal_call_tracer.rb +97 -0
  84. data/lib/temporalio/internal/worker/workflow_instance/inbound_implementation.rb +62 -0
  85. data/lib/temporalio/internal/worker/workflow_instance/outbound_implementation.rb +415 -0
  86. data/lib/temporalio/internal/worker/workflow_instance/replay_safe_logger.rb +37 -0
  87. data/lib/temporalio/internal/worker/workflow_instance/replay_safe_metric.rb +40 -0
  88. data/lib/temporalio/internal/worker/workflow_instance/scheduler.rb +163 -0
  89. data/lib/temporalio/internal/worker/workflow_instance.rb +730 -0
  90. data/lib/temporalio/internal/worker/workflow_worker.rb +196 -0
  91. data/lib/temporalio/metric.rb +109 -0
  92. data/lib/temporalio/retry_policy.rb +37 -14
  93. data/lib/temporalio/runtime.rb +118 -75
  94. data/lib/temporalio/search_attributes.rb +80 -37
  95. data/lib/temporalio/testing/activity_environment.rb +2 -2
  96. data/lib/temporalio/testing/workflow_environment.rb +251 -5
  97. data/lib/temporalio/version.rb +1 -1
  98. data/lib/temporalio/worker/activity_executor/thread_pool.rb +9 -217
  99. data/lib/temporalio/worker/activity_executor.rb +3 -3
  100. data/lib/temporalio/worker/interceptor.rb +340 -66
  101. data/lib/temporalio/worker/thread_pool.rb +237 -0
  102. data/lib/temporalio/worker/workflow_executor/thread_pool.rb +230 -0
  103. data/lib/temporalio/worker/workflow_executor.rb +26 -0
  104. data/lib/temporalio/worker.rb +201 -30
  105. data/lib/temporalio/workflow/activity_cancellation_type.rb +20 -0
  106. data/lib/temporalio/workflow/child_workflow_cancellation_type.rb +21 -0
  107. data/lib/temporalio/workflow/child_workflow_handle.rb +43 -0
  108. data/lib/temporalio/workflow/definition.rb +566 -0
  109. data/lib/temporalio/workflow/external_workflow_handle.rb +41 -0
  110. data/lib/temporalio/workflow/future.rb +151 -0
  111. data/lib/temporalio/workflow/handler_unfinished_policy.rb +13 -0
  112. data/lib/temporalio/workflow/info.rb +82 -0
  113. data/lib/temporalio/workflow/parent_close_policy.rb +19 -0
  114. data/lib/temporalio/workflow/update_info.rb +20 -0
  115. data/lib/temporalio/workflow.rb +523 -0
  116. data/lib/temporalio.rb +4 -0
  117. data/temporalio.gemspec +2 -2
  118. metadata +52 -6
@@ -1,54 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Much of this logic taken from
4
- # https://github.com/ruby-concurrency/concurrent-ruby/blob/044020f44b36930b863b930f3ee8fa1e9f750469/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb,
5
- # see MIT license at
6
- # https://github.com/ruby-concurrency/concurrent-ruby/blob/044020f44b36930b863b930f3ee8fa1e9f750469/LICENSE.txt
3
+ require 'temporalio/worker/thread_pool'
7
4
 
8
5
  module Temporalio
9
6
  class Worker
10
7
  class ActivityExecutor
11
- # Activity executor for scheduling activities in their own thread. This implementation is a stripped down form of
12
- # Concurrent Ruby's `CachedThreadPool`.
8
+ # Activity executor for scheduling activities in their own thread using {Worker::ThreadPool}.
13
9
  class ThreadPool < ActivityExecutor
14
- # @return [ThreadPool] Default/shared thread pool executor instance with unlimited max threads.
10
+ # @return [ThreadPool] Default/shared thread pool executor using default thread pool.
15
11
  def self.default
16
12
  @default ||= new
17
13
  end
18
14
 
19
- # @!visibility private
20
- def self._monotonic_time
21
- Process.clock_gettime(Process::CLOCK_MONOTONIC)
22
- end
23
-
24
- # Create a new thread pool executor that creates threads as needed.
15
+ # Create a new thread pool executor.
25
16
  #
26
- # @param max_threads [Integer, nil] Maximum number of thread workers to create, or nil for unlimited max.
27
- # @param idle_timeout [Float] Number of seconds before a thread worker with no work should be stopped. Note,
28
- # the check of whether a thread worker is idle is only done on each new activity.
29
- def initialize(max_threads: nil, idle_timeout: 20) # rubocop:disable Lint/MissingSuper
30
- @max_threads = max_threads
31
- @idle_timeout = idle_timeout
32
-
33
- @mutex = Mutex.new
34
- @pool = []
35
- @ready = []
36
- @queue = []
37
- @scheduled_task_count = 0
38
- @completed_task_count = 0
39
- @largest_length = 0
40
- @workers_counter = 0
41
- @prune_interval = @idle_timeout / 2
42
- @next_prune_time = ThreadPool._monotonic_time + @prune_interval
17
+ # @param thread_pool [Worker::ThreadPool] Thread pool to use.
18
+ def initialize(thread_pool = Worker::ThreadPool.default) # rubocop:disable Lint/MissingSuper
19
+ @thread_pool = thread_pool
43
20
  end
44
21
 
45
22
  # @see ActivityExecutor.execute_activity
46
- def execute_activity(_defn, &block)
47
- @mutex.synchronize do
48
- locked_assign_worker(&block) || locked_enqueue(&block)
49
- @scheduled_task_count += 1
50
- locked_prune_pool if @next_prune_time < ThreadPool._monotonic_time
51
- end
23
+ def execute_activity(_defn, &)
24
+ @thread_pool.execute(&)
52
25
  end
53
26
 
54
27
  # @see ActivityExecutor.activity_context
@@ -67,187 +40,6 @@ module Temporalio
67
40
  thread.raise(Error::CanceledError.new('Activity canceled')) if thread[:temporal_activity_context] == context
68
41
  end
69
42
  end
70
-
71
- # @return [Integer] The largest number of threads that have been created in the pool since construction.
72
- def largest_length
73
- @mutex.synchronize { @largest_length }
74
- end
75
-
76
- # @return [Integer] The number of tasks that have been scheduled for execution on the pool since construction.
77
- def scheduled_task_count
78
- @mutex.synchronize { @scheduled_task_count }
79
- end
80
-
81
- # @return [Integer] The number of tasks that have been completed by the pool since construction.
82
- def completed_task_count
83
- @mutex.synchronize { @completed_task_count }
84
- end
85
-
86
- # @return [Integer] The number of threads that are actively executing tasks.
87
- def active_count
88
- @mutex.synchronize { @pool.length - @ready.length }
89
- end
90
-
91
- # @return [Integer] The number of threads currently in the pool.
92
- def length
93
- @mutex.synchronize { @pool.length }
94
- end
95
-
96
- # @return [Integer] The number of tasks in the queue awaiting execution.
97
- def queue_length
98
- @mutex.synchronize { @queue.length }
99
- end
100
-
101
- # Gracefully shutdown each thread when it is done with its current task. This should not be called until all
102
- # workers using this executor are complete. This does not need to be called at all on program exit (e.g. for the
103
- # global default).
104
- def shutdown
105
- @mutex.synchronize do
106
- # Stop all workers
107
- @pool.each(&:stop)
108
- end
109
- end
110
-
111
- # Kill each thread. This should not be called until all workers using this executor are complete. This does not
112
- # need to be called at all on program exit (e.g. for the global default).
113
- def kill
114
- @mutex.synchronize do
115
- # Kill all workers
116
- @pool.each(&:kill)
117
- @pool.clear
118
- @ready.clear
119
- end
120
- end
121
-
122
- # @!visibility private
123
- def _remove_busy_worker(worker)
124
- @mutex.synchronize { locked_remove_busy_worker(worker) }
125
- end
126
-
127
- # @!visibility private
128
- def _ready_worker(worker, last_message)
129
- @mutex.synchronize { locked_ready_worker(worker, last_message) }
130
- end
131
-
132
- # @!visibility private
133
- def _worker_died(worker)
134
- @mutex.synchronize { locked_worker_died(worker) }
135
- end
136
-
137
- # @!visibility private
138
- def _worker_task_completed
139
- @mutex.synchronize { @completed_task_count += 1 }
140
- end
141
-
142
- private
143
-
144
- def locked_assign_worker(&block)
145
- # keep growing if the pool is not at the minimum yet
146
- worker, = @ready.pop || locked_add_busy_worker
147
- if worker
148
- worker << block
149
- true
150
- else
151
- false
152
- end
153
- end
154
-
155
- def locked_enqueue(&block)
156
- @queue << block
157
- end
158
-
159
- def locked_add_busy_worker
160
- return if @max_threads && @pool.size >= @max_threads
161
-
162
- @workers_counter += 1
163
- @pool << (worker = Worker.new(self, @workers_counter))
164
- @largest_length = @pool.length if @pool.length > @largest_length
165
- worker
166
- end
167
-
168
- def locked_prune_pool
169
- now = ThreadPool._monotonic_time
170
- stopped_workers = 0
171
- while !@ready.empty? && (@pool.size - stopped_workers).positive?
172
- worker, last_message = @ready.first
173
- break unless now - last_message > @idle_timeout
174
-
175
- stopped_workers += 1
176
- @ready.shift
177
- worker << :stop
178
-
179
- end
180
-
181
- @next_prune_time = ThreadPool._monotonic_time + @prune_interval
182
- end
183
-
184
- def locked_remove_busy_worker(worker)
185
- @pool.delete(worker)
186
- end
187
-
188
- def locked_ready_worker(worker, last_message)
189
- block = @queue.shift
190
- if block
191
- worker << block
192
- else
193
- @ready.push([worker, last_message])
194
- end
195
- end
196
-
197
- def locked_worker_died(worker)
198
- locked_remove_busy_worker(worker)
199
- replacement_worker = locked_add_busy_worker
200
- locked_ready_worker(replacement_worker, ThreadPool._monotonic_time) if replacement_worker
201
- end
202
-
203
- # @!visibility private
204
- class Worker
205
- def initialize(pool, id)
206
- @queue = Queue.new
207
- @thread = Thread.new(@queue, pool) do |my_queue, my_pool|
208
- catch(:stop) do
209
- loop do
210
- case block = my_queue.pop
211
- when :stop
212
- pool._remove_busy_worker(self)
213
- throw :stop
214
- else
215
- begin
216
- block.call
217
- my_pool._worker_task_completed
218
- my_pool._ready_worker(self, ThreadPool._monotonic_time)
219
- rescue StandardError => e
220
- # Ignore
221
- warn("Unexpected activity block error: #{e}")
222
- rescue Exception => e # rubocop:disable Lint/RescueException
223
- warn("Unexpected activity block exception: #{e}")
224
- my_pool._worker_died(self)
225
- throw :stop
226
- end
227
- end
228
- end
229
- end
230
- end
231
- @thread.name = "activity-thread-#{id}"
232
- end
233
-
234
- # @!visibility private
235
- def <<(block)
236
- @queue << block
237
- end
238
-
239
- # @!visibility private
240
- def stop
241
- @queue << :stop
242
- end
243
-
244
- # @!visibility private
245
- def kill
246
- @thread.kill
247
- end
248
- end
249
-
250
- private_constant :Worker
251
43
  end
252
44
  end
253
45
  end
@@ -21,7 +21,7 @@ module Temporalio
21
21
  # allows executor implementations to do eager validation based on the definition. This does not have to be
22
22
  # implemented and the default is a no-op.
23
23
  #
24
- # @param defn [Activity::Definition] Activity definition.
24
+ # @param defn [Activity::Definition::Info] Activity definition info.
25
25
  def initialize_activity(defn)
26
26
  # Default no-op
27
27
  end
@@ -29,7 +29,7 @@ module Temporalio
29
29
  # Execute the given block in the executor. The block is built to never raise and need no arguments. Implementers
30
30
  # must implement this.
31
31
  #
32
- # @param defn [Activity::Definition] Activity definition.
32
+ # @param defn [Activity::Definition::Info] Activity definition info.
33
33
  # @yield Block to execute.
34
34
  def execute_activity(defn, &)
35
35
  raise NotImplementedError
@@ -45,7 +45,7 @@ module Temporalio
45
45
  # {execute_activity} with a context before user code is executed and with nil after user code is complete.
46
46
  # Implementers must implement this.
47
47
  #
48
- # @param defn [Activity::Definition] Activity definition.
48
+ # @param defn [Activity::Definition::Info] Activity definition info.
49
49
  # @param context [Activity::Context, nil] The value to set.
50
50
  def set_activity_context(defn, context)
51
51
  raise NotImplementedError