temporalio 0.2.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.
- checksums.yaml +7 -0
- data/Gemfile +23 -0
- data/Rakefile +387 -0
- data/lib/temporalio/activity/complete_async_error.rb +11 -0
- data/lib/temporalio/activity/context.rb +107 -0
- data/lib/temporalio/activity/definition.rb +77 -0
- data/lib/temporalio/activity/info.rb +63 -0
- data/lib/temporalio/activity.rb +69 -0
- data/lib/temporalio/api/batch/v1/message.rb +31 -0
- data/lib/temporalio/api/cloud/cloudservice/v1/request_response.rb +93 -0
- data/lib/temporalio/api/cloud/cloudservice/v1/service.rb +25 -0
- data/lib/temporalio/api/cloud/cloudservice.rb +3 -0
- data/lib/temporalio/api/cloud/identity/v1/message.rb +36 -0
- data/lib/temporalio/api/cloud/namespace/v1/message.rb +35 -0
- data/lib/temporalio/api/cloud/operation/v1/message.rb +27 -0
- data/lib/temporalio/api/cloud/region/v1/message.rb +23 -0
- data/lib/temporalio/api/command/v1/message.rb +46 -0
- data/lib/temporalio/api/common/v1/grpc_status.rb +23 -0
- data/lib/temporalio/api/common/v1/message.rb +41 -0
- data/lib/temporalio/api/enums/v1/batch_operation.rb +22 -0
- data/lib/temporalio/api/enums/v1/command_type.rb +21 -0
- data/lib/temporalio/api/enums/v1/common.rb +26 -0
- data/lib/temporalio/api/enums/v1/event_type.rb +21 -0
- data/lib/temporalio/api/enums/v1/failed_cause.rb +26 -0
- data/lib/temporalio/api/enums/v1/namespace.rb +23 -0
- data/lib/temporalio/api/enums/v1/query.rb +22 -0
- data/lib/temporalio/api/enums/v1/reset.rb +23 -0
- data/lib/temporalio/api/enums/v1/schedule.rb +21 -0
- data/lib/temporalio/api/enums/v1/task_queue.rb +25 -0
- data/lib/temporalio/api/enums/v1/update.rb +22 -0
- data/lib/temporalio/api/enums/v1/workflow.rb +30 -0
- data/lib/temporalio/api/errordetails/v1/message.rb +42 -0
- data/lib/temporalio/api/export/v1/message.rb +24 -0
- data/lib/temporalio/api/failure/v1/message.rb +35 -0
- data/lib/temporalio/api/filter/v1/message.rb +27 -0
- data/lib/temporalio/api/history/v1/message.rb +90 -0
- data/lib/temporalio/api/namespace/v1/message.rb +31 -0
- data/lib/temporalio/api/nexus/v1/message.rb +40 -0
- data/lib/temporalio/api/operatorservice/v1/request_response.rb +49 -0
- data/lib/temporalio/api/operatorservice/v1/service.rb +23 -0
- data/lib/temporalio/api/operatorservice.rb +3 -0
- data/lib/temporalio/api/protocol/v1/message.rb +23 -0
- data/lib/temporalio/api/query/v1/message.rb +27 -0
- data/lib/temporalio/api/replication/v1/message.rb +26 -0
- data/lib/temporalio/api/schedule/v1/message.rb +42 -0
- data/lib/temporalio/api/sdk/v1/enhanced_stack_trace.rb +25 -0
- data/lib/temporalio/api/sdk/v1/task_complete_metadata.rb +21 -0
- data/lib/temporalio/api/sdk/v1/user_metadata.rb +23 -0
- data/lib/temporalio/api/sdk/v1/workflow_metadata.rb +23 -0
- data/lib/temporalio/api/taskqueue/v1/message.rb +45 -0
- data/lib/temporalio/api/update/v1/message.rb +33 -0
- data/lib/temporalio/api/version/v1/message.rb +26 -0
- data/lib/temporalio/api/workflow/v1/message.rb +43 -0
- data/lib/temporalio/api/workflowservice/v1/request_response.rb +189 -0
- data/lib/temporalio/api/workflowservice/v1/service.rb +23 -0
- data/lib/temporalio/api/workflowservice.rb +3 -0
- data/lib/temporalio/api.rb +13 -0
- data/lib/temporalio/cancellation.rb +150 -0
- data/lib/temporalio/client/activity_id_reference.rb +32 -0
- data/lib/temporalio/client/async_activity_handle.rb +110 -0
- data/lib/temporalio/client/connection/cloud_service.rb +648 -0
- data/lib/temporalio/client/connection/operator_service.rb +249 -0
- data/lib/temporalio/client/connection/service.rb +41 -0
- data/lib/temporalio/client/connection/workflow_service.rb +1218 -0
- data/lib/temporalio/client/connection.rb +270 -0
- data/lib/temporalio/client/interceptor.rb +316 -0
- data/lib/temporalio/client/workflow_execution.rb +103 -0
- data/lib/temporalio/client/workflow_execution_count.rb +36 -0
- data/lib/temporalio/client/workflow_execution_status.rb +18 -0
- data/lib/temporalio/client/workflow_handle.rb +446 -0
- data/lib/temporalio/client/workflow_query_reject_condition.rb +14 -0
- data/lib/temporalio/client/workflow_update_handle.rb +67 -0
- data/lib/temporalio/client/workflow_update_wait_stage.rb +17 -0
- data/lib/temporalio/client.rb +404 -0
- data/lib/temporalio/common_enums.rb +24 -0
- data/lib/temporalio/converters/data_converter.rb +102 -0
- data/lib/temporalio/converters/failure_converter.rb +200 -0
- data/lib/temporalio/converters/payload_codec.rb +26 -0
- data/lib/temporalio/converters/payload_converter/binary_null.rb +34 -0
- data/lib/temporalio/converters/payload_converter/binary_plain.rb +35 -0
- data/lib/temporalio/converters/payload_converter/binary_protobuf.rb +42 -0
- data/lib/temporalio/converters/payload_converter/composite.rb +62 -0
- data/lib/temporalio/converters/payload_converter/encoding.rb +35 -0
- data/lib/temporalio/converters/payload_converter/json_plain.rb +44 -0
- data/lib/temporalio/converters/payload_converter/json_protobuf.rb +41 -0
- data/lib/temporalio/converters/payload_converter.rb +73 -0
- data/lib/temporalio/converters.rb +9 -0
- data/lib/temporalio/error/failure.rb +219 -0
- data/lib/temporalio/error.rb +147 -0
- data/lib/temporalio/internal/bridge/3.1/temporalio_bridge.bundle +0 -0
- data/lib/temporalio/internal/bridge/3.2/temporalio_bridge.bundle +0 -0
- data/lib/temporalio/internal/bridge/3.3/temporalio_bridge.bundle +0 -0
- data/lib/temporalio/internal/bridge/api/activity_result/activity_result.rb +34 -0
- data/lib/temporalio/internal/bridge/api/activity_task/activity_task.rb +31 -0
- data/lib/temporalio/internal/bridge/api/child_workflow/child_workflow.rb +33 -0
- data/lib/temporalio/internal/bridge/api/common/common.rb +26 -0
- data/lib/temporalio/internal/bridge/api/core_interface.rb +36 -0
- data/lib/temporalio/internal/bridge/api/external_data/external_data.rb +27 -0
- data/lib/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rb +52 -0
- data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +54 -0
- data/lib/temporalio/internal/bridge/api/workflow_completion/workflow_completion.rb +30 -0
- data/lib/temporalio/internal/bridge/api.rb +3 -0
- data/lib/temporalio/internal/bridge/client.rb +90 -0
- data/lib/temporalio/internal/bridge/runtime.rb +53 -0
- data/lib/temporalio/internal/bridge/testing.rb +46 -0
- data/lib/temporalio/internal/bridge/worker.rb +83 -0
- data/lib/temporalio/internal/bridge.rb +36 -0
- data/lib/temporalio/internal/client/implementation.rb +525 -0
- data/lib/temporalio/internal/proto_utils.rb +54 -0
- data/lib/temporalio/internal/worker/activity_worker.rb +345 -0
- data/lib/temporalio/internal/worker/multi_runner.rb +169 -0
- data/lib/temporalio/internal.rb +7 -0
- data/lib/temporalio/retry_policy.rb +51 -0
- data/lib/temporalio/runtime.rb +271 -0
- data/lib/temporalio/scoped_logger.rb +96 -0
- data/lib/temporalio/search_attributes.rb +300 -0
- data/lib/temporalio/testing/activity_environment.rb +132 -0
- data/lib/temporalio/testing/workflow_environment.rb +137 -0
- data/lib/temporalio/testing.rb +10 -0
- data/lib/temporalio/version.rb +5 -0
- data/lib/temporalio/worker/activity_executor/fiber.rb +49 -0
- data/lib/temporalio/worker/activity_executor/thread_pool.rb +254 -0
- data/lib/temporalio/worker/activity_executor.rb +55 -0
- data/lib/temporalio/worker/interceptor.rb +88 -0
- data/lib/temporalio/worker/tuner.rb +151 -0
- data/lib/temporalio/worker.rb +426 -0
- data/lib/temporalio/workflow_history.rb +22 -0
- data/lib/temporalio.rb +7 -0
- data/temporalio.gemspec +28 -0
- metadata +191 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 209ea74a531b7d0259dc1708d459875aefeabf8cd514052dde31fdb5ed901072
|
4
|
+
data.tar.gz: '038fc31c03ba9e3d2b542ebc863c7dc85b61a477f906b615562efde503764f4f'
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0cb8f9adf5d9f0b25680abfb31aa6d1c89f46cdeb9ab30abc805461528e55c72777b49b4c2102335913d877eb1231a6db6bea97a4329a595e8e7f3753ccb70d0
|
7
|
+
data.tar.gz: 86a1a7a7df4391bacb975be3e42e48662c85a6fffd6e8114eeee79f02ac4638cc83be4bdb6778a7b29dcf21c64a310977f48a1e3fa308bdd8d73e392bd94d286
|
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,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
|