Skip to content

Commit 74cfa27

Browse files
committed
RBS work and other things
1 parent 515546f commit 74cfa27

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1414
-87
lines changed

temporalio/Rakefile

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ namespace :proto do
134134
desc = Google::Protobuf::DescriptorPool.generated_pool.lookup(qualified_service_name)
135135
raise 'Failed finding service descriptor' unless desc
136136

137-
# Open file to generate
137+
# Open file to generate Ruby code
138138
File.open("lib/temporalio/client/connection/#{file_name}.rb", 'w') do |file|
139139
file.puts <<~TEXT
140140
# frozen_string_literal: true
@@ -189,6 +189,35 @@ namespace :proto do
189189
end
190190
TEXT
191191
end
192+
193+
# Open file to generate RBS code
194+
# TODO(cretz): Improve this when RBS proto is supported
195+
File.open("sig/temporalio/client/connection/#{file_name}.rbs", 'w') do |file|
196+
file.puts <<~TEXT
197+
# Generated code. DO NOT EDIT!
198+
199+
module Temporalio
200+
class Client
201+
class Connection
202+
class #{class_name} < Service
203+
def initialize: (Connection) -> void
204+
TEXT
205+
206+
desc.each do |method|
207+
# Camel case to snake case
208+
rpc = method.name.gsub(/([A-Z])/, '_\1').downcase.delete_prefix('_')
209+
file.puts <<-TEXT
210+
def #{rpc}: (untyped request, ?rpc_retry: bool, ?rpc_metadata: Hash[String, String]?, ?rpc_timeout: Float?) -> untyped
211+
TEXT
212+
end
213+
214+
file.puts <<~TEXT
215+
end
216+
end
217+
end
218+
end
219+
TEXT
220+
end
192221
end
193222

194223
require './lib/temporalio/api/workflowservice/v1/service'
@@ -293,5 +322,4 @@ Rake::Task[:build].enhance([:copy_parent_files]) do
293322
rm ['LICENSE', 'README.md']
294323
end
295324

296-
# TODO(cretz): Add rbs:install_collection and :steep back when RBS is ready
297-
task default: %i[rubocop compile test]
325+
task default: ['rubocop', 'compile', 'rbs:install_collection', 'steep', 'test']

temporalio/Steepfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ target :lib do
1212
library 'uri'
1313

1414
configure_code_diagnostics do |hash|
15+
# TODO(cretz): Fix as more protos are generated
1516
hash[D::Ruby::UnknownConstant] = :information
16-
hash[D::Ruby::NoMethod] = :information
1717
end
1818
end

temporalio/ext/src/client.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub fn init(ruby: &Ruby) -> Result<(), Error> {
3939
class.define_singleton_method("async_new", function!(Client::async_new, 2))?;
4040
class.define_method("async_invoke_rpc", method!(Client::async_invoke_rpc, -1))?;
4141

42-
let inner_class = class.define_error("RpcFailure", ruby.get_inner(&ROOT_ERR))?;
42+
let inner_class = class.define_error("RPCFailure", ruby.get_inner(&ROOT_ERR))?;
4343
inner_class.define_method("code", method!(RpcFailure::code, 0))?;
4444
inner_class.define_method("message", method!(RpcFailure::message, 0))?;
4545
inner_class.define_method("details", method!(RpcFailure::details, 0))?;
@@ -220,7 +220,7 @@ impl Client {
220220

221221
#[derive(DataTypeFunctions, TypedData)]
222222
#[magnus(
223-
class = "Temporalio::Internal::Bridge::Client::RpcFailure",
223+
class = "Temporalio::Internal::Bridge::Client::RPCFailure",
224224
free_immediately
225225
)]
226226
pub struct RpcFailure {

temporalio/lib/temporalio/client.rb

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ module Temporalio
1616
# Client for accessing Temporal.
1717
#
1818
# Most users will use {connect} to connect a client. The {workflow_service} method provides access to a raw gRPC
19-
# client. To create another client on the same connection, like for a different namespace, {dup_options} may be
20-
# used to get the options as a struct which can then be altered and splatted as kwargs to the constructor (e.g.
19+
# client. To create another client on the same connection, like for a different namespace, {options} may be used to
20+
# get the options as a struct which can then be dup'd, altered, and splatted as kwargs to the constructor (e.g.
2121
# +Client.new(**my_options.to_h)+).
2222
#
2323
# Clients are thread-safe and are meant to be reused for the life of the application. They are built to work in both
2424
# synchronous and asynchronous contexts. Internally they use callbacks based on {::Queue} which means they are
2525
# Fiber-compatible.
2626
class Client
27-
# Options as returned from {dup_options} for +**to_h+ splat use in {initialize}. See {initialize} for details.
27+
# Options as returned from {options} for +**to_h+ splat use in {initialize}. See {initialize} for details.
2828
Options = Struct.new(
2929
:connection,
3030
:namespace,
@@ -58,7 +58,7 @@ class Client
5858
# @param identity [String] Identity for this client.
5959
# @param keep_alive [Connection::KeepAliveOptions] Keep-alive options for the client connection. Can be set to +nil+
6060
# to disable.
61-
# @param http_connect_proxy [Connection::HTTPConnectProxyOptions] Options for HTTP CONNECT proxy.
61+
# @param http_connect_proxy [Connection::HTTPConnectProxyOptions, nil] Options for HTTP CONNECT proxy.
6262
# @param runtime [Runtime] Runtime for this client.
6363
# @param lazy_connect [Boolean] If true, the client will not connect until the first call is attempted or a worker
6464
# is created with it. Lazy clients cannot be used for workers if they have not performed a connection.
@@ -103,8 +103,12 @@ def self.connect(
103103
)
104104
end
105105

106+
# @return [Options] Frozen options for this client which has the same attributes as {initialize}.
107+
attr_reader :options
108+
106109
# Create a client from an existing connection. Most users will prefer {connect} instead. Parameters here match
107-
# {Options} returned from {dup_options} by intention so options can be altered and splatted to create a new client.
110+
# {Options} returned from {options} by intention so options can be dup'd, altered, and splatted to create a new
111+
# client.
108112
#
109113
# @param connection [Connection] Existing connection to create a client from.
110114
# @param namespace [String] Namespace to use for client calls.
@@ -132,7 +136,7 @@ def initialize(
132136
data_converter:,
133137
interceptors:,
134138
default_workflow_query_reject_condition:
135-
)
139+
).freeze
136140
# Initialize interceptors
137141
@impl = interceptors.reverse_each.reduce(Implementation.new(self)) do |acc, int|
138142
int.intercept_client(acc)
@@ -164,12 +168,6 @@ def operator_service
164168
connection.operator_service
165169
end
166170

167-
# @return [Options] Shallow duplication of options for potential use in {initialize}. Note, this is shallow, so
168-
# attributes like {Options.interceptors} are not duplicated, but no mutations will apply.
169-
def dup_options
170-
@options.dup
171-
end
172-
173171
# Start a workflow and return its handle.
174172
#
175173
# @param workflow [Workflow, String] Name of the workflow

temporalio/lib/temporalio/client/connection.rb

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class Client
1313
# Connection to Temporal server that is not namespace specific. Most users will use {Client.connect} instead of this
1414
# directly.
1515
class Connection
16-
# Options as returned from {dup_options} for +**to_h+ splat use in {initialize}. See {initialize} for details.
16+
# Options as returned from {options} for +**to_h+ splat use in {initialize}. See {initialize} for details.
1717
Options = Struct.new(
1818
:target_host,
1919
:api_key,
@@ -72,7 +72,8 @@ class Connection
7272
:max_retries,
7373
keyword_init: true
7474
) do
75-
def initialize(*, **kwargs)
75+
def initialize(**kwargs)
76+
# @type var kwargs: untyped
7677
kwargs[:initial_interval] = 0.1 unless kwargs.key?(:initial_interval)
7778
kwargs[:randomization_factor] = 0.2 unless kwargs.key?(:randomization_factor)
7879
kwargs[:multiplier] = 1.5 unless kwargs.key?(:multiplier)
@@ -95,7 +96,8 @@ def initialize(*, **kwargs)
9596
:timeout,
9697
keyword_init: true
9798
) do
98-
def initialize(*, **kwargs)
99+
def initialize(**kwargs)
100+
# @type var kwargs: untyped
99101
kwargs[:interval] = 30.0 unless kwargs.key?(:interval)
100102
kwargs[:timeout] = 15.0 unless kwargs.key?(:timeout)
101103
super
@@ -117,8 +119,8 @@ def initialize(*, **kwargs)
117119
keyword_init: true
118120
)
119121

120-
# @return [String] Client identity.
121-
attr_reader :identity
122+
# @return [Options] Frozen options for this client which has the same attributes as {initialize}.
123+
attr_reader :options
122124

123125
# @return [WorkflowService] Raw gRPC workflow service.
124126
attr_reader :workflow_service
@@ -130,7 +132,7 @@ def initialize(*, **kwargs)
130132
attr_reader :cloud_service
131133

132134
# Connect to Temporal server. Most users will use {Client.connect} instead of this directly. Parameters here match
133-
# {Options} returned from {dup_options} by intention so options can be altered and splatted to create a new
135+
# {Options} returned from {options} by intention so options can be dup'd, altered, splatted to create a new
134136
# connection.
135137
#
136138
# @param target_host [String] +host:port+ for the Temporal server. For local development, this is often
@@ -146,7 +148,7 @@ def initialize(*, **kwargs)
146148
# @param identity [String] Identity for this client.
147149
# @param keep_alive [KeepAliveOptions] Keep-alive options for the client connection. Can be set to +nil+ to
148150
# disable.
149-
# @param http_connect_proxy [HTTPConnectProxyOptions] Options for HTTP CONNECT proxy.
151+
# @param http_connect_proxy [HTTPConnectProxyOptions, nil] Options for HTTP CONNECT proxy.
150152
# @param runtime [Runtime] Runtime for this client.
151153
# @param lazy_connect [Boolean] If true, there is no connection until the first call is attempted or a worker
152154
# is created with it. Clients from lazy connections cannot be used for workers if they have not performed a
@@ -176,7 +178,7 @@ def initialize(
176178
http_connect_proxy:,
177179
runtime:,
178180
lazy_connect:
179-
)
181+
).freeze
180182
# Create core client now if not lazy
181183
_core_client unless lazy_connect
182184
# Create service instances
@@ -190,10 +192,9 @@ def target_host
190192
@options.target_host
191193
end
192194

193-
# @return [Options] Shallow duplication of options for potential use in {initialize}. Note, this is shallow, so
194-
# attributes like {Options.rpc_metadata} are not duplicated, but no mutations will apply.
195-
def dup_options
196-
@options.dup
195+
# @return [String] Client identity.
196+
def identity
197+
@options.identity
197198
end
198199

199200
# @return [Boolean] Whether this connection is connected. This is always `true` unless `lazy_connect` option was
@@ -237,10 +238,10 @@ def new_core_client
237238
if @options.tls
238239
options.tls = if @options.tls.is_a?(TLSOptions)
239240
Internal::Bridge::Client::TLSOptions.new(
240-
client_cert: @options.tls.client_cert,
241-
client_private_key: @options.tls.client_private_key,
242-
server_root_ca_cert: @options.tls.server_root_ca_cert,
243-
domain: @options.tls.domain
241+
client_cert: @options.tls.client_cert, # steep:ignore
242+
client_private_key: @options.tls.client_private_key, # steep:ignore
243+
server_root_ca_cert: @options.tls.server_root_ca_cert, # steep:ignore
244+
domain: @options.tls.domain # steep:ignore
244245
)
245246
else
246247
Internal::Bridge::Client::TLSOptions.new

temporalio/lib/temporalio/client/connection/service.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def invoke_rpc(rpc:, request_class:, response_class:, request:, rpc_retry:, rpc_
3131
rpc_metadata:,
3232
rpc_timeout:
3333
)
34-
rescue Internal::Bridge::Client::RpcFailure => e
34+
rescue Internal::Bridge::Client::RPCFailure => e
3535
raise Error::RPCError.new(e.message, code: e.code, raw_grpc_status: e.details)
3636
end
3737
end

temporalio/lib/temporalio/client/workflow_handle.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,13 @@ def result(
9292
when :EVENT_TYPE_WORKFLOW_EXECUTION_COMPLETED
9393
attrs = event.workflow_execution_completed_event_attributes
9494
hist_run_id = attrs.new_execution_run_id
95-
next if follow_runs && !hist_run_id.empty?
95+
next if follow_runs && hist_run_id && !hist_run_id.empty?
9696

9797
return @client.data_converter.from_payloads(attrs.result).first
9898
when :EVENT_TYPE_WORKFLOW_EXECUTION_FAILED
9999
attrs = event.workflow_execution_failed_event_attributes
100100
hist_run_id = attrs.new_execution_run_id
101-
next if follow_runs && !hist_run_id.empty?
101+
next if follow_runs && hist_run_id && !hist_run_id.empty?
102102

103103
raise Error::WorkflowFailureError.new(cause: @client.data_converter.from_failure(attrs.failure))
104104
when :EVENT_TYPE_WORKFLOW_EXECUTION_CANCELED
@@ -120,7 +120,7 @@ def result(
120120
when :EVENT_TYPE_WORKFLOW_EXECUTION_TIMED_OUT
121121
attrs = event.workflow_execution_timed_out_event_attributes
122122
hist_run_id = attrs.new_execution_run_id
123-
next if follow_runs && !hist_run_id.empty?
123+
next if follow_runs && hist_run_id && !hist_run_id.empty?
124124

125125
raise Error::WorkflowFailureError.new(
126126
cause: Error::TimeoutError.new(
@@ -131,7 +131,7 @@ def result(
131131
when :EVENT_TYPE_WORKFLOW_EXECUTION_CONTINUED_AS_NEW
132132
attrs = event.workflow_execution_continued_as_new_event_attributes
133133
hist_run_id = attrs.new_execution_run_id
134-
next if follow_runs && !hist_run_id.empty?
134+
next if follow_runs && hist_run_id && !hist_run_id.empty?
135135

136136
# TODO: Use more specific error and decode failure
137137
raise Error::WorkflowContinuedAsNewError.new(new_run_id: attrs.new_execution_run_id)
@@ -182,8 +182,8 @@ def fetch_history_events_for_run(
182182
wait_new_event:,
183183
event_filter_type:,
184184
skip_archival:,
185-
rpc_metadata: nil,
186-
rpc_timeout: nil
185+
rpc_metadata:,
186+
rpc_timeout:
187187
)
188188
Enumerator.new do |yielder|
189189
input = Interceptor::FetchWorkflowHistoryEventPageInput.new(

temporalio/lib/temporalio/converters/failure_converter.rb

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,22 @@ def initialize(encode_common_attributes: false)
1919

2020
# Convert a Ruby error to a Temporal failure.
2121
#
22-
# @param _error [Exception] Ruby error.
23-
# @param _payload_converter [PayloadConverter] Payload converter.
22+
# @param error [Exception] Ruby error.
23+
# @param payload_converter [PayloadConverter] Payload converter.
2424
# @return [Api::Failure::V1::Failure] Converted failure.
25-
def to_failure(_error, _payload_converter)
26-
raise 'TODO'
25+
def to_failure(error, payload_converter)
26+
# TODO
27+
raise NotImplementedError
2728
end
2829

2930
# Convert a Temporal failure to a Ruby error.
3031
#
31-
# @param _failure [Api::Failure::V1::Failure] Failure.
32-
# @param _payload_converter [PayloadConverter] Payload converter.
32+
# @param failure [Api::Failure::V1::Failure] Failure.
33+
# @param payload_converter [PayloadConverter] Payload converter.
3334
# @return [Exception] Converted Ruby error.
34-
def from_failure(_failure, _payload_converter)
35-
raise 'TODO'
35+
def from_failure(failure, payload_converter)
36+
# TODO
37+
raise NotImplementedError
3638
end
3739
end
3840
end
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# frozen_string_literal: true
2+
3+
module Temporalio
4+
module Converters
5+
class PayloadCodec # rubocop:disable Lint/EmptyClass
6+
# TODO
7+
end
8+
end
9+
end

temporalio/lib/temporalio/converters/payload_converter.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ module Temporalio
1111
module Converters
1212
# Base class for converting Ruby values to/from Temporal payloads.
1313
class PayloadConverter
14-
# @return [FailureConverter] Default payload converter.
14+
# @return [PayloadConverter] Default payload converter.
1515
def self.default
1616
@default ||= new_with_defaults
1717
end
@@ -20,6 +20,7 @@ def self.default
2020
#
2121
# @param json_parse_options [Hash] Options for {::JSON.parse}.
2222
# @param json_generate_options [Hash] Options for {::JSON.generate}.
23+
# @return [PayloadConverter] Created payload converter.
2324
def self.new_with_defaults(json_parse_options: { create_additions: true }, json_generate_options: {})
2425
Ractor.make_shareable(
2526
PayloadConverter::Composite.new(

0 commit comments

Comments
 (0)