temporalio 0.2.0-arm64-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 (130) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +23 -0
  3. data/Rakefile +387 -0
  4. data/lib/temporalio/activity/complete_async_error.rb +11 -0
  5. data/lib/temporalio/activity/context.rb +107 -0
  6. data/lib/temporalio/activity/definition.rb +77 -0
  7. data/lib/temporalio/activity/info.rb +63 -0
  8. data/lib/temporalio/activity.rb +69 -0
  9. data/lib/temporalio/api/batch/v1/message.rb +31 -0
  10. data/lib/temporalio/api/cloud/cloudservice/v1/request_response.rb +93 -0
  11. data/lib/temporalio/api/cloud/cloudservice/v1/service.rb +25 -0
  12. data/lib/temporalio/api/cloud/cloudservice.rb +3 -0
  13. data/lib/temporalio/api/cloud/identity/v1/message.rb +36 -0
  14. data/lib/temporalio/api/cloud/namespace/v1/message.rb +35 -0
  15. data/lib/temporalio/api/cloud/operation/v1/message.rb +27 -0
  16. data/lib/temporalio/api/cloud/region/v1/message.rb +23 -0
  17. data/lib/temporalio/api/command/v1/message.rb +46 -0
  18. data/lib/temporalio/api/common/v1/grpc_status.rb +23 -0
  19. data/lib/temporalio/api/common/v1/message.rb +41 -0
  20. data/lib/temporalio/api/enums/v1/batch_operation.rb +22 -0
  21. data/lib/temporalio/api/enums/v1/command_type.rb +21 -0
  22. data/lib/temporalio/api/enums/v1/common.rb +26 -0
  23. data/lib/temporalio/api/enums/v1/event_type.rb +21 -0
  24. data/lib/temporalio/api/enums/v1/failed_cause.rb +26 -0
  25. data/lib/temporalio/api/enums/v1/namespace.rb +23 -0
  26. data/lib/temporalio/api/enums/v1/query.rb +22 -0
  27. data/lib/temporalio/api/enums/v1/reset.rb +23 -0
  28. data/lib/temporalio/api/enums/v1/schedule.rb +21 -0
  29. data/lib/temporalio/api/enums/v1/task_queue.rb +25 -0
  30. data/lib/temporalio/api/enums/v1/update.rb +22 -0
  31. data/lib/temporalio/api/enums/v1/workflow.rb +30 -0
  32. data/lib/temporalio/api/errordetails/v1/message.rb +42 -0
  33. data/lib/temporalio/api/export/v1/message.rb +24 -0
  34. data/lib/temporalio/api/failure/v1/message.rb +35 -0
  35. data/lib/temporalio/api/filter/v1/message.rb +27 -0
  36. data/lib/temporalio/api/history/v1/message.rb +90 -0
  37. data/lib/temporalio/api/namespace/v1/message.rb +31 -0
  38. data/lib/temporalio/api/nexus/v1/message.rb +40 -0
  39. data/lib/temporalio/api/operatorservice/v1/request_response.rb +49 -0
  40. data/lib/temporalio/api/operatorservice/v1/service.rb +23 -0
  41. data/lib/temporalio/api/operatorservice.rb +3 -0
  42. data/lib/temporalio/api/protocol/v1/message.rb +23 -0
  43. data/lib/temporalio/api/query/v1/message.rb +27 -0
  44. data/lib/temporalio/api/replication/v1/message.rb +26 -0
  45. data/lib/temporalio/api/schedule/v1/message.rb +42 -0
  46. data/lib/temporalio/api/sdk/v1/enhanced_stack_trace.rb +25 -0
  47. data/lib/temporalio/api/sdk/v1/task_complete_metadata.rb +21 -0
  48. data/lib/temporalio/api/sdk/v1/user_metadata.rb +23 -0
  49. data/lib/temporalio/api/sdk/v1/workflow_metadata.rb +23 -0
  50. data/lib/temporalio/api/taskqueue/v1/message.rb +45 -0
  51. data/lib/temporalio/api/update/v1/message.rb +33 -0
  52. data/lib/temporalio/api/version/v1/message.rb +26 -0
  53. data/lib/temporalio/api/workflow/v1/message.rb +43 -0
  54. data/lib/temporalio/api/workflowservice/v1/request_response.rb +189 -0
  55. data/lib/temporalio/api/workflowservice/v1/service.rb +23 -0
  56. data/lib/temporalio/api/workflowservice.rb +3 -0
  57. data/lib/temporalio/api.rb +13 -0
  58. data/lib/temporalio/cancellation.rb +150 -0
  59. data/lib/temporalio/client/activity_id_reference.rb +32 -0
  60. data/lib/temporalio/client/async_activity_handle.rb +110 -0
  61. data/lib/temporalio/client/connection/cloud_service.rb +648 -0
  62. data/lib/temporalio/client/connection/operator_service.rb +249 -0
  63. data/lib/temporalio/client/connection/service.rb +41 -0
  64. data/lib/temporalio/client/connection/workflow_service.rb +1218 -0
  65. data/lib/temporalio/client/connection.rb +270 -0
  66. data/lib/temporalio/client/interceptor.rb +316 -0
  67. data/lib/temporalio/client/workflow_execution.rb +103 -0
  68. data/lib/temporalio/client/workflow_execution_count.rb +36 -0
  69. data/lib/temporalio/client/workflow_execution_status.rb +18 -0
  70. data/lib/temporalio/client/workflow_handle.rb +446 -0
  71. data/lib/temporalio/client/workflow_query_reject_condition.rb +14 -0
  72. data/lib/temporalio/client/workflow_update_handle.rb +67 -0
  73. data/lib/temporalio/client/workflow_update_wait_stage.rb +17 -0
  74. data/lib/temporalio/client.rb +404 -0
  75. data/lib/temporalio/common_enums.rb +24 -0
  76. data/lib/temporalio/converters/data_converter.rb +102 -0
  77. data/lib/temporalio/converters/failure_converter.rb +200 -0
  78. data/lib/temporalio/converters/payload_codec.rb +26 -0
  79. data/lib/temporalio/converters/payload_converter/binary_null.rb +34 -0
  80. data/lib/temporalio/converters/payload_converter/binary_plain.rb +35 -0
  81. data/lib/temporalio/converters/payload_converter/binary_protobuf.rb +42 -0
  82. data/lib/temporalio/converters/payload_converter/composite.rb +62 -0
  83. data/lib/temporalio/converters/payload_converter/encoding.rb +35 -0
  84. data/lib/temporalio/converters/payload_converter/json_plain.rb +44 -0
  85. data/lib/temporalio/converters/payload_converter/json_protobuf.rb +41 -0
  86. data/lib/temporalio/converters/payload_converter.rb +73 -0
  87. data/lib/temporalio/converters.rb +9 -0
  88. data/lib/temporalio/error/failure.rb +219 -0
  89. data/lib/temporalio/error.rb +147 -0
  90. data/lib/temporalio/internal/bridge/3.1/temporalio_bridge.bundle +0 -0
  91. data/lib/temporalio/internal/bridge/3.2/temporalio_bridge.bundle +0 -0
  92. data/lib/temporalio/internal/bridge/3.3/temporalio_bridge.bundle +0 -0
  93. data/lib/temporalio/internal/bridge/api/activity_result/activity_result.rb +34 -0
  94. data/lib/temporalio/internal/bridge/api/activity_task/activity_task.rb +31 -0
  95. data/lib/temporalio/internal/bridge/api/child_workflow/child_workflow.rb +33 -0
  96. data/lib/temporalio/internal/bridge/api/common/common.rb +26 -0
  97. data/lib/temporalio/internal/bridge/api/core_interface.rb +36 -0
  98. data/lib/temporalio/internal/bridge/api/external_data/external_data.rb +27 -0
  99. data/lib/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rb +52 -0
  100. data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +54 -0
  101. data/lib/temporalio/internal/bridge/api/workflow_completion/workflow_completion.rb +30 -0
  102. data/lib/temporalio/internal/bridge/api.rb +3 -0
  103. data/lib/temporalio/internal/bridge/client.rb +90 -0
  104. data/lib/temporalio/internal/bridge/runtime.rb +53 -0
  105. data/lib/temporalio/internal/bridge/testing.rb +46 -0
  106. data/lib/temporalio/internal/bridge/worker.rb +83 -0
  107. data/lib/temporalio/internal/bridge.rb +36 -0
  108. data/lib/temporalio/internal/client/implementation.rb +525 -0
  109. data/lib/temporalio/internal/proto_utils.rb +54 -0
  110. data/lib/temporalio/internal/worker/activity_worker.rb +345 -0
  111. data/lib/temporalio/internal/worker/multi_runner.rb +169 -0
  112. data/lib/temporalio/internal.rb +7 -0
  113. data/lib/temporalio/retry_policy.rb +51 -0
  114. data/lib/temporalio/runtime.rb +271 -0
  115. data/lib/temporalio/scoped_logger.rb +96 -0
  116. data/lib/temporalio/search_attributes.rb +300 -0
  117. data/lib/temporalio/testing/activity_environment.rb +132 -0
  118. data/lib/temporalio/testing/workflow_environment.rb +137 -0
  119. data/lib/temporalio/testing.rb +10 -0
  120. data/lib/temporalio/version.rb +5 -0
  121. data/lib/temporalio/worker/activity_executor/fiber.rb +49 -0
  122. data/lib/temporalio/worker/activity_executor/thread_pool.rb +254 -0
  123. data/lib/temporalio/worker/activity_executor.rb +55 -0
  124. data/lib/temporalio/worker/interceptor.rb +88 -0
  125. data/lib/temporalio/worker/tuner.rb +151 -0
  126. data/lib/temporalio/worker.rb +426 -0
  127. data/lib/temporalio/workflow_history.rb +22 -0
  128. data/lib/temporalio.rb +7 -0
  129. data/temporalio.gemspec +28 -0
  130. metadata +191 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 85e9742c3972195738939eed7be5d8fdd907414f534399f863df2df9f65f048b
4
+ data.tar.gz: 69e2e7aec3c673928ca75599d8a900834553b18d84e19c41d5035f0d402106dc
5
+ SHA512:
6
+ metadata.gz: 1b3e7cc7b38534cd5d3297238706167ca9d1f4637bf55eab2d92b2ba361c71fd4dfc38877907dafb63b987c207dcf43f41fb02b80c3bfee749da290ebfdf96ff
7
+ data.tar.gz: 9de54048ace1235d180b4789bd733829bef3951a7426a41dde3986c2fddb928e1d9ba68664a11a81a4883f5ef783c766f231096ef869ed7f8d5267451fa86491
data/Gemfile ADDED
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
6
+
7
+ group :development do
8
+ gem 'activemodel'
9
+ gem 'activerecord'
10
+ gem 'async'
11
+ gem 'base64'
12
+ gem 'grpc', '>= 1.65.0.pre2'
13
+ gem 'grpc-tools'
14
+ gem 'minitest'
15
+ gem 'rake'
16
+ gem 'rake-compiler'
17
+ gem 'rbs', '~> 3.5.3'
18
+ gem 'rb_sys', '~> 0.9.63'
19
+ gem 'rubocop'
20
+ gem 'sqlite3', '~> 1.4'
21
+ gem 'steep', '~> 1.7.1'
22
+ gem 'yard'
23
+ end
data/Rakefile ADDED
@@ -0,0 +1,387 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Metrics/BlockLength, Lint/MissingCopEnableDirective, Style/DocumentationMethod
4
+
5
+ require 'bundler/gem_tasks'
6
+ require 'rb_sys/cargo/metadata'
7
+ require 'rb_sys/extensiontask'
8
+
9
+ task build: :compile
10
+
11
+ GEMSPEC = Gem::Specification.load('temporalio.gemspec')
12
+
13
+ begin
14
+ RbSys::ExtensionTask.new('temporalio_bridge', GEMSPEC) do |ext|
15
+ ext.lib_dir = 'lib/temporalio/internal/bridge'
16
+ end
17
+ rescue RbSys::CargoMetadataError
18
+ raise 'Source gem cannot be installed directly, must be a supported platform'
19
+ end
20
+
21
+ require 'rake/testtask'
22
+
23
+ Rake::TestTask.new(:test) do |t|
24
+ t.warning = false
25
+ t.libs << 'test'
26
+ t.libs << 'lib'
27
+ t.test_files = FileList['test/**/*_test.rb']
28
+ end
29
+
30
+ def add_protoc_to_path
31
+ tools_spec = Gem::Specification.find_by_name('grpc-tools')
32
+ cpu = RbConfig::CONFIG['host_cpu']
33
+ cpu = 'x86_64' if cpu == 'x64'
34
+ os = RbConfig::CONFIG['host_os']
35
+ os = 'windows' if os.start_with?('mingw')
36
+ protoc_path = "#{tools_spec.gem_dir}/bin/#{cpu}-#{os}"
37
+ separator = os == 'windows' ? ';' : ':'
38
+ ENV['PATH'] = "#{ENV.fetch('PATH', nil)}#{separator}#{protoc_path}"
39
+ end
40
+
41
+ add_protoc_to_path
42
+
43
+ require 'rubocop/rake_task'
44
+
45
+ RuboCop::RakeTask.new
46
+
47
+ require 'steep/rake_task'
48
+
49
+ Steep::RakeTask.new
50
+
51
+ require 'yard'
52
+
53
+ module CustomizeYardWarnings # rubocop:disable Style/Documentation
54
+ def process
55
+ super
56
+ rescue YARD::Parser::UndocumentableError
57
+ # We ignore if it's an API warning
58
+ raise unless statement.last.file.start_with?('lib/temporalio/api/') ||
59
+ statement.last.file.start_with?('lib/temporalio/internal/bridge/api/')
60
+ end
61
+ end
62
+
63
+ YARD::Handlers::Ruby::ConstantHandler.prepend(CustomizeYardWarnings)
64
+
65
+ YARD::Rake::YardocTask.new { |t| t.options = ['--fail-on-warning'] }
66
+
67
+ require 'fileutils'
68
+ require 'google/protobuf'
69
+
70
+ namespace :proto do
71
+ desc 'Generate API and Core protobufs'
72
+ task :generate do
73
+ # Remove all existing
74
+ FileUtils.rm_rf('lib/temporalio/api')
75
+
76
+ def generate_protos(api_protos)
77
+ # Generate API to temp dir and move
78
+ FileUtils.rm_rf('tmp-proto')
79
+ FileUtils.mkdir_p('tmp-proto')
80
+ sh 'bundle exec grpc_tools_ruby_protoc ' \
81
+ '--proto_path=ext/sdk-core/sdk-core-protos/protos/api_upstream ' \
82
+ '--proto_path=ext/sdk-core/sdk-core-protos/protos/api_cloud_upstream ' \
83
+ '--proto_path=ext/additional_protos ' \
84
+ '--ruby_out=tmp-proto ' \
85
+ "#{api_protos.join(' ')}"
86
+
87
+ # Walk all generated Ruby files and cleanup content and filename
88
+ Dir.glob('tmp-proto/temporal/api/**/*.rb') do |path|
89
+ # Fix up the import
90
+ content = File.read(path)
91
+ content.gsub!(%r{^require 'temporal/(.*)_pb'$}, "require 'temporalio/\\1'")
92
+ File.write(path, content)
93
+
94
+ # Remove _pb from the filename
95
+ FileUtils.mv(path, path.sub('_pb', ''))
96
+ end
97
+
98
+ # Move from temp dir and remove temp dir
99
+ FileUtils.cp_r('tmp-proto/temporal/api', 'lib/temporalio')
100
+ FileUtils.rm_rf('tmp-proto')
101
+ end
102
+
103
+ # Generate from API with Google ones removed
104
+ generate_protos(Dir.glob('ext/sdk-core/sdk-core-protos/protos/api_upstream/**/*.proto').reject do |proto|
105
+ proto.include?('google')
106
+ end)
107
+
108
+ # Generate from Cloud API
109
+ generate_protos(Dir.glob('ext/sdk-core/sdk-core-protos/protos/api_cloud_upstream/**/*.proto'))
110
+
111
+ # Generate additional protos
112
+ generate_protos(Dir.glob('ext/additional_protos/**/*.proto'))
113
+
114
+ # Write files that will help with imports. We are requiring the
115
+ # request_response and not the service because the service depends on Google
116
+ # API annotations we don't want to have to depend on.
117
+ File.write(
118
+ 'lib/temporalio/api/cloud/cloudservice.rb',
119
+ <<~TEXT
120
+ # frozen_string_literal: true
121
+
122
+ require 'temporalio/api/cloud/cloudservice/v1/request_response'
123
+ TEXT
124
+ )
125
+ File.write(
126
+ 'lib/temporalio/api/workflowservice.rb',
127
+ <<~TEXT
128
+ # frozen_string_literal: true
129
+
130
+ require 'temporalio/api/workflowservice/v1/request_response'
131
+ TEXT
132
+ )
133
+ File.write(
134
+ 'lib/temporalio/api/operatorservice.rb',
135
+ <<~TEXT
136
+ # frozen_string_literal: true
137
+
138
+ require 'temporalio/api/operatorservice/v1/request_response'
139
+ TEXT
140
+ )
141
+ File.write(
142
+ 'lib/temporalio/api.rb',
143
+ <<~TEXT
144
+ # frozen_string_literal: true
145
+
146
+ require 'temporalio/api/cloud/cloudservice'
147
+ require 'temporalio/api/common/v1/grpc_status'
148
+ require 'temporalio/api/errordetails/v1/message'
149
+ require 'temporalio/api/operatorservice'
150
+ require 'temporalio/api/workflowservice'
151
+
152
+ module Temporalio
153
+ # Raw protocol buffer models.
154
+ module Api
155
+ end
156
+ end
157
+ TEXT
158
+ )
159
+
160
+ # Write the service classes that have the RPC calls
161
+ def write_service_file(qualified_service_name:, file_name:, class_name:, service_enum:)
162
+ # Do service lookup
163
+ desc = Google::Protobuf::DescriptorPool.generated_pool.lookup(qualified_service_name)
164
+ raise 'Failed finding service descriptor' unless desc
165
+
166
+ # Open file to generate Ruby code
167
+ File.open("lib/temporalio/client/connection/#{file_name}.rb", 'w') do |file|
168
+ file.puts <<~TEXT
169
+ # frozen_string_literal: true
170
+
171
+ # Generated code. DO NOT EDIT!
172
+
173
+ require 'temporalio/api'
174
+ require 'temporalio/client/connection/service'
175
+ require 'temporalio/internal/bridge/client'
176
+
177
+ module Temporalio
178
+ class Client
179
+ class Connection
180
+ # #{class_name} API.
181
+ class #{class_name} < Service
182
+ # @!visibility private
183
+ def initialize(connection)
184
+ super(connection, Internal::Bridge::Client::#{service_enum})
185
+ end
186
+ TEXT
187
+
188
+ desc.each do |method|
189
+ # Camel case to snake case
190
+ rpc = method.name.gsub(/([A-Z])/, '_\1').downcase.delete_prefix('_')
191
+ file.puts <<-TEXT
192
+
193
+ # Calls #{class_name}.#{method.name} API call.
194
+ #
195
+ # @param request [#{method.input_type.msgclass}] API request.
196
+ # @param rpc_retry [Boolean] Whether to implicitly retry known retryable errors.
197
+ # @param rpc_metadata [Hash<String, String>, nil] Headers to include on the RPC call.
198
+ # @param rpc_timeout [Float, nil] Number of seconds before timeout.
199
+ # @return [#{method.output_type.msgclass}] API response.
200
+ def #{rpc}(request, rpc_retry: false, rpc_metadata: nil, rpc_timeout: nil)
201
+ invoke_rpc(
202
+ rpc: '#{rpc}',
203
+ request_class: #{method.input_type.msgclass},
204
+ response_class: #{method.output_type.msgclass},
205
+ request:,
206
+ rpc_retry:,
207
+ rpc_metadata:,
208
+ rpc_timeout:
209
+ )
210
+ end
211
+ TEXT
212
+ end
213
+
214
+ file.puts <<~TEXT
215
+ end
216
+ end
217
+ end
218
+ end
219
+ TEXT
220
+ end
221
+
222
+ # Open file to generate RBS code
223
+ # TODO(cretz): Improve this when RBS proto is supported
224
+ File.open("sig/temporalio/client/connection/#{file_name}.rbs", 'w') do |file|
225
+ file.puts <<~TEXT
226
+ # Generated code. DO NOT EDIT!
227
+
228
+ module Temporalio
229
+ class Client
230
+ class Connection
231
+ class #{class_name} < Service
232
+ def initialize: (Connection) -> void
233
+ TEXT
234
+
235
+ desc.each do |method|
236
+ # Camel case to snake case
237
+ rpc = method.name.gsub(/([A-Z])/, '_\1').downcase.delete_prefix('_')
238
+ file.puts <<-TEXT
239
+ def #{rpc}: (untyped request, ?rpc_retry: bool, ?rpc_metadata: Hash[String, String]?, ?rpc_timeout: Float?) -> untyped
240
+ TEXT
241
+ end
242
+
243
+ file.puts <<~TEXT
244
+ end
245
+ end
246
+ end
247
+ end
248
+ TEXT
249
+ end
250
+ end
251
+
252
+ require './lib/temporalio/api/workflowservice/v1/service'
253
+ write_service_file(
254
+ qualified_service_name: 'temporal.api.workflowservice.v1.WorkflowService',
255
+ file_name: 'workflow_service',
256
+ class_name: 'WorkflowService',
257
+ service_enum: 'SERVICE_WORKFLOW'
258
+ )
259
+ require './lib/temporalio/api/operatorservice/v1/service'
260
+ write_service_file(
261
+ qualified_service_name: 'temporal.api.operatorservice.v1.OperatorService',
262
+ file_name: 'operator_service',
263
+ class_name: 'OperatorService',
264
+ service_enum: 'SERVICE_OPERATOR'
265
+ )
266
+ require './lib/temporalio/api/cloud/cloudservice/v1/service'
267
+ write_service_file(
268
+ qualified_service_name: 'temporal.api.cloud.cloudservice.v1.CloudService',
269
+ file_name: 'cloud_service',
270
+ class_name: 'CloudService',
271
+ service_enum: 'SERVICE_CLOUD'
272
+ )
273
+
274
+ # Generate Rust code
275
+ def generate_rust_match_arm(file:, qualified_service_name:, service_enum:, trait:)
276
+ # Do service lookup
277
+ desc = Google::Protobuf::DescriptorPool.generated_pool.lookup(qualified_service_name)
278
+ file.puts <<~TEXT
279
+ #{service_enum} => match call.rpc.as_str() {
280
+ TEXT
281
+
282
+ desc.to_a.sort_by(&:name).each do |method|
283
+ # Camel case to snake case
284
+ rpc = method.name.gsub(/([A-Z])/, '_\1').downcase.delete_prefix('_')
285
+ file.puts <<~TEXT
286
+ "#{rpc}" => rpc_call!(self, callback, call, #{trait}, #{rpc}),
287
+ TEXT
288
+ end
289
+ file.puts <<~TEXT
290
+ _ => Err(error!("Unknown RPC call {}", call.rpc)),
291
+ },
292
+ TEXT
293
+ end
294
+ File.open('ext/src/client_rpc_generated.rs', 'w') do |file|
295
+ file.puts <<~TEXT
296
+ // Generated code. DO NOT EDIT!
297
+
298
+ use magnus::{Error, Ruby};
299
+ use temporal_client::{CloudService, OperatorService, WorkflowService};
300
+
301
+ use super::{error, rpc_call};
302
+ use crate::{
303
+ client::{Client, RpcCall, SERVICE_CLOUD, SERVICE_OPERATOR, SERVICE_WORKFLOW},
304
+ util::AsyncCallback,
305
+ };
306
+
307
+ impl Client {
308
+ pub fn invoke_rpc(&self, service: u8, callback: AsyncCallback, call: RpcCall) -> Result<(), Error> {
309
+ match service {
310
+ TEXT
311
+ generate_rust_match_arm(
312
+ file:,
313
+ qualified_service_name: 'temporal.api.workflowservice.v1.WorkflowService',
314
+ service_enum: 'SERVICE_WORKFLOW',
315
+ trait: 'WorkflowService'
316
+ )
317
+ generate_rust_match_arm(
318
+ file:,
319
+ qualified_service_name: 'temporal.api.operatorservice.v1.OperatorService',
320
+ service_enum: 'SERVICE_OPERATOR',
321
+ trait: 'OperatorService'
322
+ )
323
+ generate_rust_match_arm(
324
+ file:,
325
+ qualified_service_name: 'temporal.api.cloud.cloudservice.v1.CloudService',
326
+ service_enum: 'SERVICE_CLOUD',
327
+ trait: 'CloudService'
328
+ )
329
+ file.puts <<~TEXT
330
+ _ => Err(error!("Unknown service")),
331
+ }
332
+ }
333
+ }
334
+ TEXT
335
+ end
336
+ sh 'cargo', 'fmt', '--', 'ext/src/client_rpc_generated.rs'
337
+
338
+ # Generate core protos
339
+ FileUtils.rm_rf('lib/temporalio/internal/bridge/api')
340
+ # Generate API to temp dir
341
+ FileUtils.rm_rf('tmp-proto')
342
+ FileUtils.mkdir_p('tmp-proto')
343
+ sh 'bundle exec grpc_tools_ruby_protoc ' \
344
+ '--proto_path=ext/sdk-core/sdk-core-protos/protos/api_upstream ' \
345
+ '--proto_path=ext/sdk-core/sdk-core-protos/protos/local ' \
346
+ '--ruby_out=tmp-proto ' \
347
+ "#{Dir.glob('ext/sdk-core/sdk-core-protos/protos/local/**/*.proto').join(' ')}"
348
+ # Walk all generated Ruby files and cleanup content and filename
349
+ Dir.glob('tmp-proto/temporal/sdk/**/*.rb') do |path|
350
+ # Fix up the imports
351
+ content = File.read(path)
352
+ content.gsub!(%r{^require 'temporal/(.*)_pb'$}, "require 'temporalio/\\1'")
353
+ content.gsub!(%r{^require 'temporalio/sdk/core/(.*)'$}, "require 'temporalio/internal/bridge/api/\\1'")
354
+ File.write(path, content)
355
+
356
+ # Remove _pb from the filename
357
+ FileUtils.mv(path, path.sub('_pb', ''))
358
+ end
359
+ # Move from temp dir and remove temp dir
360
+ FileUtils.mkdir_p('lib/temporalio/internal/bridge/api')
361
+ FileUtils.cp_r(Dir.glob('tmp-proto/temporal/sdk/core/*'), 'lib/temporalio/internal/bridge/api')
362
+ FileUtils.rm_rf('tmp-proto')
363
+ end
364
+ end
365
+
366
+ namespace :rbs do
367
+ desc 'RBS tasks'
368
+ task :install_collection do
369
+ sh 'rbs collection install'
370
+ end
371
+ end
372
+
373
+ # We have to copy some parent files to this dir for gem
374
+ task :copy_parent_files do
375
+ cp '../LICENSE', 'LICENSE'
376
+ cp '../README.md', 'README.md'
377
+ end
378
+ Rake::Task[:build].enhance([:copy_parent_files]) do
379
+ rm ['LICENSE', 'README.md']
380
+ end
381
+
382
+ task :rust_lint do
383
+ sh 'cargo', 'clippy'
384
+ sh 'cargo', 'fmt', '--check'
385
+ end
386
+
387
+ task default: ['rubocop', 'yard', 'rbs:install_collection', 'steep', 'rust_lint', 'compile', 'test']
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'temporalio/error'
4
+
5
+ module Temporalio
6
+ class Activity
7
+ # Error raised inside an activity to mark that the activity will be completed asynchronously.
8
+ class CompleteAsyncError < Error
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'temporalio/error'
4
+
5
+ module Temporalio
6
+ class Activity
7
+ # Context accessible only within an activity. Use {current} to get the current context. Contexts are fiber or thread
8
+ # local so may not be available in a newly started thread from an activity and may have to be propagated manually.
9
+ class Context
10
+ # @return [Context] The current context, or raises an error if not in activity fiber/thread.
11
+ def self.current
12
+ context = current_or_nil
13
+ raise Error, 'Not in activity context' if context.nil?
14
+
15
+ context
16
+ end
17
+
18
+ # @return [Context, nil] The current context or nil if not in activity fiber/thread.
19
+ def self.current_or_nil
20
+ _current_executor&.activity_context
21
+ end
22
+
23
+ # @return [Boolean] Whether there is a current context available.
24
+ def self.exist?
25
+ !current_or_nil.nil?
26
+ end
27
+
28
+ # @!visibility private
29
+ def self._current_executor
30
+ if Fiber.current_scheduler
31
+ Fiber[:temporal_activity_executor]
32
+ else
33
+ Thread.current[:temporal_activity_executor]
34
+ end
35
+ end
36
+
37
+ # @!visibility private
38
+ def self._current_executor=(executor)
39
+ if Fiber.current_scheduler
40
+ Fiber[:temporal_activity_executor] = executor
41
+ else
42
+ Thread.current[:temporal_activity_executor] = executor
43
+ end
44
+ end
45
+
46
+ # @return [Info] Activity info for this activity.
47
+ def info
48
+ raise NotImplementedError
49
+ end
50
+
51
+ # Record a heartbeat on the activity.
52
+ #
53
+ # Heartbeats should be used for all non-immediately-returning, non-local activities and they are required to
54
+ # receive cancellation. Heartbeat calls are throttled internally based on the heartbeat timeout of the activity.
55
+ # Users do not have to be concerned with burdening the server by calling this too frequently.
56
+ #
57
+ # @param details [Array<Object>] Details to record with the heartbeat.
58
+ def heartbeat(*details)
59
+ raise NotImplementedError
60
+ end
61
+
62
+ # @return [Cancellation] Cancellation that is canceled when the activity is canceled.
63
+ def cancellation
64
+ raise NotImplementedError
65
+ end
66
+
67
+ # @return [Cancellation] Cancellation that is canceled when the worker is shutting down. On worker shutdown, this
68
+ # is canceled, then the `graceful_shutdown_period` is waited (default 0s), then the activity is canceled.
69
+ def worker_shutdown_cancellation
70
+ raise NotImplementedError
71
+ end
72
+
73
+ # @return [Converters::PayloadConverter] Payload converter associated with this activity.
74
+ def payload_converter
75
+ raise NotImplementedError
76
+ end
77
+
78
+ # @return [ScopedLogger] Logger for this activity. Note, this is a shared logger not created each activity
79
+ # invocation. It just has logic to extract current activity details and so is only able to do so on log calls
80
+ # made with a current context available.
81
+ def logger
82
+ raise NotImplementedError
83
+ end
84
+
85
+ # @!visibility private
86
+ def _scoped_logger_info
87
+ return @scoped_logger_info unless @scoped_logger_info.nil?
88
+
89
+ curr_info = info
90
+ @scoped_logger_info = {
91
+ temporal_activity: {
92
+ activity_id: curr_info.activity_id,
93
+ activity_type: curr_info.activity_type,
94
+ attempt: curr_info.attempt,
95
+ task_queue: curr_info.task_queue,
96
+ workflow_id: curr_info.workflow_id,
97
+ workflow_namespace: curr_info.workflow_namespace,
98
+ workflow_run_id: curr_info.workflow_run_id,
99
+ workflow_type: curr_info.workflow_type
100
+ }
101
+ }.freeze
102
+ end
103
+
104
+ # TODO(cretz): metric meter
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Temporalio
4
+ class Activity
5
+ # Definition of an activity. Activities are usually classes/instances that extend {Activity}, but definitions can
6
+ # also be manually created with a proc/block.
7
+ class Definition
8
+ # @return [String, Symbol] Name of the activity.
9
+ attr_reader :name
10
+
11
+ # @return [Proc] Proc for the activity.
12
+ attr_reader :proc
13
+
14
+ # @return [Symbol] Name of the executor. Default is `:default`.
15
+ attr_reader :executor
16
+
17
+ # @return [Boolean] Whether to raise in thread/fiber on cancellation. Default is `true`.
18
+ attr_reader :cancel_raise
19
+
20
+ # Obtain a definition representing the given activity, which can be a class, instance, or definition.
21
+ #
22
+ # @param activity [Activity, Class<Activity>, Definition] Activity to get definition for.
23
+ # @return Definition Obtained definition.
24
+ def self.from_activity(activity)
25
+ # Class means create each time, instance means just call, definition
26
+ # does nothing special
27
+ case activity
28
+ when Class
29
+ raise ArgumentError, "Class '#{activity}' does not extend Activity" unless activity < Activity
30
+
31
+ details = activity._activity_definition_details
32
+ new(
33
+ name: details[:activity_name],
34
+ executor: details[:activity_executor],
35
+ cancel_raise: details[:activity_cancel_raise],
36
+ # Instantiate and call
37
+ proc: proc { |*args| activity.new.execute(*args) }
38
+ )
39
+ when Activity
40
+ details = activity.class._activity_definition_details
41
+ new(
42
+ name: details[:activity_name],
43
+ executor: details[:activity_executor],
44
+ cancel_raise: details[:activity_cancel_raise],
45
+ # Just call
46
+ proc: proc { |*args| activity.execute(*args) }
47
+ )
48
+ when Activity::Definition
49
+ activity
50
+ else
51
+ raise ArgumentError, "#{activity} is not an activity class, instance, or definition"
52
+ end
53
+ end
54
+
55
+ # Manually create activity definition. Most users will use an instance/class of {Activity}.
56
+ #
57
+ # @param name [String, Symbol] Name of the activity.
58
+ # @param proc [Proc, nil] Proc for the activity, or can give block.
59
+ # @param executor [Symbol] Name of the executor.
60
+ # @param cancel_raise [Boolean] Whether to raise in thread/fiber on cancellation.
61
+ # @yield Use this block as the activity. Cannot be present with `proc`.
62
+ def initialize(name:, proc: nil, executor: :default, cancel_raise: true, &block)
63
+ @name = name
64
+ if proc.nil?
65
+ raise ArgumentError, 'Must give proc or block' unless block_given?
66
+
67
+ proc = block
68
+ elsif block_given?
69
+ raise ArgumentError, 'Cannot give proc and block'
70
+ end
71
+ @proc = proc
72
+ @executor = executor
73
+ @cancel_raise = cancel_raise
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Temporalio
4
+ class Activity
5
+ # Information about an activity.
6
+ #
7
+ # @!attribute activity_id
8
+ # @return [String] ID for the activity.
9
+ # @!attribute activity_type
10
+ # @return [String] Type name for the activity.
11
+ # @!attribute attempt
12
+ # @return [Integer] Attempt the activity is on.
13
+ # @!attribute current_attempt_scheduled_time
14
+ # @return [Time] When the current attempt was scheduled.
15
+ # @!attribute heartbeat_details
16
+ # @return [Array<Object>] Details from the last heartbeat of the last attempt.
17
+ # @!attribute heartbeat_timeout
18
+ # @return [Float, nil] Heartbeat timeout set by the caller.
19
+ # @!attribute local?
20
+ # @return [Boolean] Whether the activity is a local activity or not.
21
+ # @!attribute schedule_to_close_timeout
22
+ # @return [Float, nil] Schedule to close timeout set by the caller.
23
+ # @!attribute scheduled_time
24
+ # @return [Time] When the activity was scheduled.
25
+ # @!attribute start_to_close_timeout
26
+ # @return [Float, nil] Start to close timeout set by the caller.
27
+ # @!attribute started_time
28
+ # @return [Time] When the activity started.
29
+ # @!attribute task_queue
30
+ # @return [String] Task queue this activity is on.
31
+ # @!attribute task_token
32
+ # @return [String] Task token uniquely identifying this activity. Note, this is a `ASCII-8BIT` encoded string, not
33
+ # a `UTF-8` encoded string nor a valid UTF-8 string.
34
+ # @!attribute workflow_id
35
+ # @return [String] Workflow ID that started this activity.
36
+ # @!attribute workflow_namespace
37
+ # @return [String] Namespace this activity is on.
38
+ # @!attribute workflow_run_id
39
+ # @return [String] Workflow run ID that started this activity.
40
+ # @!attribute workflow_type
41
+ # @return [String] Workflow type name that started this activity.
42
+ Info = Struct.new(
43
+ :activity_id,
44
+ :activity_type,
45
+ :attempt,
46
+ :current_attempt_scheduled_time,
47
+ :heartbeat_details,
48
+ :heartbeat_timeout,
49
+ :local?,
50
+ :schedule_to_close_timeout,
51
+ :scheduled_time,
52
+ :start_to_close_timeout,
53
+ :started_time,
54
+ :task_queue,
55
+ :task_token,
56
+ :workflow_id,
57
+ :workflow_namespace,
58
+ :workflow_run_id,
59
+ :workflow_type,
60
+ keyword_init: true
61
+ )
62
+ end
63
+ end