temporalio 0.6.0-aarch64-linux → 1.0.0-aarch64-linux

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c6392e502beb6d8efe8c82a61b8fe04019cf07ab3fb14c607c954a7c4f377016
4
- data.tar.gz: c74820f6c105324cea2695cf188f43ef52c2010423d922055027fa2eb32f8edf
3
+ metadata.gz: ebd63f43e6352b2e6c90908129e7e6563c4de136dccd88992f5335ea74bc2147
4
+ data.tar.gz: b2fec7313d7b5d706a688cca09bc44e7bc0cf8b59f675c22881e342b7b1e4931
5
5
  SHA512:
6
- metadata.gz: f4dc6046ad00fb550609b469856a37ba99e292248ff13968f5f4949618bb3b84932c948a7b367241a701a71751677a4f1c6bcfcff88e59fa11d14eeca25224af
7
- data.tar.gz: 5aa5bada79633821057032e478267f4bc63dad37f6e753cfcd78eda9a922736f407d861be1e6c71cd04e4dc75276644dab6c6c6364db2a643615fc1f9602dc51
6
+ metadata.gz: 3ceb2889cf8e0331789f7ad30594ff57de0076529086242a817b42378f721f2b481a6fa1abe977cec65244737d6a0f5228905f88e8341bf18f38c508b3e5fb19
7
+ data.tar.gz: b494b8806e05d9c2af4327f16d20a336e1c9f39ac2abc6c1670391fa11535d18cb262b1cde7ab825637208b8949fb247b61dd884a53afee361e8ee957e4baf6f
@@ -13,6 +13,7 @@ module Temporalio
13
13
  :heartbeat_timeout,
14
14
  :local?,
15
15
  :priority,
16
+ :retry_policy,
16
17
  :raw_heartbeat_details,
17
18
  :schedule_to_close_timeout,
18
19
  :scheduled_time,
@@ -42,6 +43,10 @@ module Temporalio
42
43
  # @return [Boolean] Whether the activity is a local activity or not.
43
44
  # @!attribute priority
44
45
  # @return [Priority] The priority of this activity.
46
+ # @!attribute retry_policy
47
+ # @return [RetryPolicy, nil] Retry policy for the activity. Note that the server may have set a different policy
48
+ # than the one provided when scheduling the activity. If the value is None, it means the server didn't send
49
+ # information about retry policy (e.g. due to old server version), but it may still be defined server-side.
45
50
  # @!attribute raw_heartbeat_details
46
51
  # @return [Array<Converter::RawValue>] Raw details from the last heartbeat of the last attempt. Can use
47
52
  # {heartbeat_details} to get lazily-converted values.
@@ -167,8 +167,8 @@ module Temporalio
167
167
  to_return.values
168
168
  end
169
169
 
170
- def canceled_mutex_synchronize(&)
171
- Workflow::Unsafe.illegal_call_tracing_disabled { @canceled_mutex.synchronize(&) }
170
+ def canceled_mutex_synchronize(&block)
171
+ Workflow::Unsafe.illegal_call_tracing_disabled { @canceled_mutex.synchronize(&block) }
172
172
  end
173
173
  end
174
174
  end
@@ -29,6 +29,7 @@ module Temporalio
29
29
  # @param details [Array<Object>] Details of the heartbeat.
30
30
  # @param detail_hints [Array<Object>, nil] Converter hints for the details.
31
31
  # @param rpc_options [RPCOptions, nil] Advanced RPC options.
32
+ # @raise [Error::AsyncActivityCanceledError] If the activity was canceled, paused, and/or reset.
32
33
  def heartbeat(*details, detail_hints: nil, rpc_options: nil)
33
34
  @client._impl.heartbeat_async_activity(Interceptor::HeartbeatAsyncActivityInput.new(
34
35
  task_token_or_id_reference:,
@@ -0,0 +1,343 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+ require 'temporalio/internal/bridge'
5
+
6
+ module Temporalio
7
+ # Environment and file-based configuration for Temporal clients
8
+ #
9
+ # WARNING: Experimental API.
10
+ module EnvConfig
11
+ # This module provides utilities to load Temporal client configuration from TOML files
12
+ # and environment variables.
13
+
14
+ # TLS configuration as specified as part of client configuration
15
+ #
16
+ # @!attribute [r] disabled
17
+ # @return [Boolean, nil] If true, TLS is explicitly disabled; if nil, not specified
18
+ # @!attribute [r] server_name
19
+ # @return [String, nil] SNI override
20
+ # @!attribute [r] server_root_ca_cert
21
+ # @return [Pathname, String, nil] Server CA certificate source
22
+ # @!attribute [r] client_cert
23
+ # @return [Pathname, String, nil] Client certificate source
24
+ # @!attribute [r] client_private_key
25
+ # @return [Pathname, String, nil] Client key source
26
+ ClientConfigTLS = Data.define(:disabled, :server_name, :server_root_ca_cert, :client_cert, :client_private_key)
27
+
28
+ # TLS configuration for Temporal client connections.
29
+ #
30
+ # This class provides methods for creating, serializing, and converting
31
+ # TLS configuration objects used by Temporal clients.
32
+ class ClientConfigTLS
33
+ # Create a ClientConfigTLS from a hash
34
+ # @param hash [Hash, nil] Hash representation
35
+ # @return [ClientConfigTLS, nil] The TLS configuration or nil if hash is nil/empty
36
+ def self.from_h(hash)
37
+ return nil if hash.nil? || hash.empty?
38
+
39
+ new(
40
+ disabled: hash[:disabled],
41
+ server_name: hash[:server_name],
42
+ server_root_ca_cert: hash_to_source(hash[:server_ca_cert]),
43
+ client_cert: hash_to_source(hash[:client_cert]),
44
+ client_private_key: hash_to_source(hash[:client_key])
45
+ )
46
+ end
47
+
48
+ # Set default values
49
+ def initialize(disabled: nil, server_name: nil, server_root_ca_cert: nil, client_cert: nil,
50
+ client_private_key: nil)
51
+ super
52
+ end
53
+
54
+ # Convert to a hash that can be used for TOML serialization
55
+ # @return [Hash] Dictionary representation
56
+ def to_h
57
+ {
58
+ disabled:,
59
+ server_name:,
60
+ server_ca_cert: server_root_ca_cert ? source_to_hash(server_root_ca_cert) : nil,
61
+ client_cert: client_cert ? source_to_hash(client_cert) : nil,
62
+ client_key: client_private_key ? source_to_hash(client_private_key) : nil
63
+ }.compact
64
+ end
65
+
66
+ # Create a TLS configuration for use with connections
67
+ # @return [Connection::TLSOptions, false] TLS options or false if disabled
68
+ def to_client_tls_options
69
+ return false if disabled
70
+
71
+ Client::Connection::TLSOptions.new(
72
+ domain: server_name,
73
+ server_root_ca_cert: read_source(server_root_ca_cert),
74
+ client_cert: read_source(client_cert),
75
+ client_private_key: read_source(client_private_key)
76
+ )
77
+ end
78
+
79
+ private
80
+
81
+ class << self
82
+ private
83
+
84
+ # Convert hash to source object (Pathname or String)
85
+ def hash_to_source(hash)
86
+ return nil if hash.nil?
87
+
88
+ # Always expect a hash with path or data
89
+ if hash[:path]
90
+ Pathname.new(hash[:path])
91
+ elsif hash[:data]
92
+ hash[:data]
93
+ end
94
+ end
95
+ end
96
+
97
+ def source_to_hash(source)
98
+ case source
99
+ when Pathname
100
+ { path: source.to_s }
101
+ when String
102
+ # String is always treated as data content
103
+ { data: source }
104
+ when nil
105
+ nil
106
+ else
107
+ raise TypeError, "Source must be Pathname, String, or nil, got #{source.class}"
108
+ end
109
+ end
110
+
111
+ def read_source(source)
112
+ case source
113
+ when Pathname
114
+ File.read(source.to_s)
115
+ when String
116
+ # String is always treated as raw data content
117
+ source
118
+ when nil
119
+ nil
120
+ else
121
+ raise TypeError, "Source must be Pathname, String, or nil, got #{source.class}"
122
+ end
123
+ end
124
+ end
125
+
126
+ # Represents a client configuration profile.
127
+ #
128
+ # This class holds the configuration as loaded from a file or environment.
129
+ # See #to_client_connect_options to transform the profile to a connect config hash.
130
+ #
131
+ # @!attribute [r] address
132
+ # @return [String, nil] Client address
133
+ # @!attribute [r] namespace
134
+ # @return [String, nil] Client namespace
135
+ # @!attribute [r] api_key
136
+ # @return [String, nil] Client API key
137
+ # @!attribute [r] tls
138
+ # @return [Boolean, ClientConfigTLS, nil] TLS configuration
139
+ # @!attribute [r] grpc_meta
140
+ # @return [Hash] gRPC metadata
141
+ ClientConfigProfile = Data.define(:address, :namespace, :api_key, :tls, :grpc_meta)
142
+
143
+ # A client configuration profile loaded from environment and files.
144
+ #
145
+ # This class represents a complete client configuration profile that can be
146
+ # loaded from TOML files and environment variables, and converted to client
147
+ # connection options.
148
+ class ClientConfigProfile
149
+ # Create a ClientConfigProfile from a hash
150
+ # @param hash [Hash] Hash representation
151
+ # @return [ClientConfigProfile] The client profile
152
+ def self.from_h(hash)
153
+ new(
154
+ address: hash[:address],
155
+ namespace: hash[:namespace],
156
+ api_key: hash[:api_key],
157
+ tls: ClientConfigTLS.from_h(hash[:tls]),
158
+ grpc_meta: hash[:grpc_meta] || {}
159
+ )
160
+ end
161
+
162
+ # Load a single client profile from given sources, applying env overrides.
163
+ #
164
+ # @param profile [String, nil] Profile to load from the config
165
+ # @param config_source [Pathname, String, nil] Configuration source -
166
+ # Pathname for file path, String for TOML content
167
+ # @param disable_file [Boolean] If true, file loading is disabled
168
+ # @param disable_env [Boolean] If true, environment variable loading and overriding is disabled
169
+ # @param config_file_strict [Boolean] If true, will error on unrecognized keys
170
+ # @param override_env_vars [Hash, nil] Environment variables to use for loading and overrides
171
+ # @return [ClientConfigProfile] The client configuration profile
172
+ def self.load(
173
+ profile: nil,
174
+ config_source: nil,
175
+ disable_file: false,
176
+ disable_env: false,
177
+ config_file_strict: false,
178
+ override_env_vars: nil
179
+ )
180
+ path, data = EnvConfig._source_to_path_and_data(config_source)
181
+
182
+ raw_profile = Internal::Bridge::EnvConfig.load_client_connect_config(
183
+ profile,
184
+ path,
185
+ data,
186
+ disable_file,
187
+ disable_env,
188
+ config_file_strict,
189
+ override_env_vars || {}
190
+ )
191
+
192
+ from_h(raw_profile)
193
+ end
194
+
195
+ # Create a ClientConfigProfile instance with defaults
196
+ def initialize(address: nil, namespace: nil, api_key: nil, tls: nil, grpc_meta: {})
197
+ super
198
+ end
199
+
200
+ # Convert to a hash that can be used for TOML serialization
201
+ # @return [Hash] Dictionary representation
202
+ def to_h
203
+ {
204
+ address: address,
205
+ namespace: namespace,
206
+ api_key: api_key,
207
+ tls: tls&.to_h&.then { |tls_hash| tls_hash.empty? ? nil : tls_hash }, # steep:ignore
208
+ grpc_meta: grpc_meta && grpc_meta.empty? ? nil : grpc_meta
209
+ }.compact
210
+ end
211
+
212
+ # Create a client connect config from this profile
213
+ # @return [Array] Tuple of [positional_args, keyword_args] that can be splatted to Client.connect
214
+ def to_client_connect_options
215
+ positional_args = [address, namespace].compact
216
+ tls_value = false
217
+ if tls
218
+ tls_value = tls.to_client_tls_options
219
+ elsif api_key
220
+ tls_value = true
221
+ end
222
+
223
+ keyword_args = {
224
+ api_key: api_key,
225
+ rpc_metadata: (grpc_meta if grpc_meta && !grpc_meta.empty?),
226
+ tls: tls_value
227
+ }.compact
228
+
229
+ [positional_args, keyword_args]
230
+ end
231
+ end
232
+
233
+ # Client configuration loaded from TOML and environment variables.
234
+ #
235
+ # This contains a mapping of profile names to client profiles.
236
+ #
237
+ # @!attribute [r] profiles
238
+ # @return [Hash<String, ClientConfigProfile>] Map of profile name to its corresponding ClientConfigProfile
239
+ ClientConfig = Data.define(:profiles)
240
+
241
+ # Container for multiple client configuration profiles.
242
+ #
243
+ # This class holds a collection of named client profiles loaded from
244
+ # configuration sources and provides methods for profile management
245
+ # and client connection configuration.
246
+ class ClientConfig
247
+ # Create a ClientConfig from a hash
248
+ # @param hash [Hash] Hash representation
249
+ # @return [ClientConfig] The client configuration
250
+ def self.from_h(hash)
251
+ profiles = hash.transform_values do |profile_hash|
252
+ ClientConfigProfile.from_h(profile_hash)
253
+ end
254
+ new(profiles: profiles)
255
+ end
256
+
257
+ # Load all client profiles from given sources.
258
+ #
259
+ # This does not apply environment variable overrides to the profiles, it
260
+ # only uses an environment variable to find the default config file path
261
+ # (TEMPORAL_CONFIG_FILE).
262
+ #
263
+ # @param config_source [Pathname, String, nil] Configuration source
264
+ # @param config_file_strict [Boolean] If true, will error on unrecognized keys
265
+ # @param override_env_vars [Hash, nil] Environment variables to use
266
+ # @return [ClientConfig] The client configuration
267
+ def self.load(
268
+ config_source: nil,
269
+ config_file_strict: false,
270
+ override_env_vars: nil
271
+ )
272
+ path, data = EnvConfig._source_to_path_and_data(config_source)
273
+
274
+ loaded_profiles = Internal::Bridge::EnvConfig.load_client_config(
275
+ path,
276
+ data,
277
+ config_file_strict,
278
+ override_env_vars || {}
279
+ )
280
+
281
+ from_h(loaded_profiles)
282
+ end
283
+
284
+ # Load a single client profile and convert to connect config
285
+ #
286
+ # This is a convenience function that combines loading a profile and
287
+ # converting it to a connect config hash.
288
+ #
289
+ # @param profile [String, nil] The profile to load from the config
290
+ # @param config_source [Pathname, String, nil] Configuration source
291
+ # @param disable_file [Boolean] If true, file loading is disabled
292
+ # @param disable_env [Boolean] If true, environment variable loading and overriding is disabled
293
+ # @param config_file_strict [Boolean] If true, will error on unrecognized keys
294
+ # @param override_env_vars [Hash, nil] Environment variables to use for loading and overrides
295
+ # @return [Array] Tuple of [positional_args, keyword_args] that can be splatted to Client.connect
296
+ def self.load_client_connect_options(
297
+ profile: nil,
298
+ config_source: nil,
299
+ disable_file: false,
300
+ disable_env: false,
301
+ config_file_strict: false,
302
+ override_env_vars: nil
303
+ )
304
+ prof = ClientConfigProfile.load(
305
+ profile: profile,
306
+ config_source: config_source,
307
+ disable_file: disable_file,
308
+ disable_env: disable_env,
309
+ config_file_strict: config_file_strict,
310
+ override_env_vars: override_env_vars
311
+ )
312
+ prof.to_client_connect_options
313
+ end
314
+
315
+ # Create a ClientConfig instance with defaults
316
+ def initialize(profiles: {})
317
+ super
318
+ end
319
+
320
+ # Convert to a hash that can be used for TOML serialization
321
+ # @return [Hash] Dictionary representation
322
+ def to_h
323
+ profiles.transform_values(&:to_h)
324
+ end
325
+ end
326
+
327
+ # @param source [Pathname, String, nil] Configuration source
328
+ # @return [Array<String?, String?>] Tuple of [path, data]
329
+ # @!visibility private
330
+ def self._source_to_path_and_data(source)
331
+ case source
332
+ when Pathname
333
+ [source.to_s, nil]
334
+ when String
335
+ [nil, source]
336
+ when nil
337
+ [nil, nil]
338
+ else
339
+ raise TypeError, "Must be Pathname, String, or nil, got #{source.class}"
340
+ end
341
+ end
342
+ end
343
+ end
@@ -97,9 +97,13 @@ module Temporalio
97
97
 
98
98
  # Error that occurs when an async activity handle tries to heartbeat and the activity is marked as canceled.
99
99
  class AsyncActivityCanceledError < Error
100
+ # @return [Activity::CancellationDetails]
101
+ attr_reader :details
102
+
100
103
  # @!visibility private
101
- def initialize
104
+ def initialize(details)
102
105
  super('Activity canceled')
106
+ @details = details
103
107
  end
104
108
  end
105
109
 
@@ -40,6 +40,7 @@ module Temporalio
40
40
  TunerSlotSupplierOptions = Struct.new(
41
41
  :fixed_size,
42
42
  :resource_based,
43
+ :custom,
43
44
  keyword_init: true
44
45
  )
45
46
 
@@ -103,6 +104,55 @@ module Temporalio
103
104
  # TODO(cretz): Log error on this somehow?
104
105
  async_complete_activity_task(proto.to_proto, queue)
105
106
  end
107
+
108
+ class CustomSlotSupplier
109
+ def initialize(slot_supplier:, thread_pool:)
110
+ @slot_supplier = slot_supplier
111
+ @thread_pool = thread_pool
112
+ end
113
+
114
+ def reserve_slot(context, cancellation, &block)
115
+ run_user_code do
116
+ @slot_supplier.reserve_slot(context, cancellation) { |v| block.call(v) }
117
+ rescue Exception => e # rubocop:disable Lint/RescueException
118
+ block.call(e)
119
+ end
120
+ end
121
+
122
+ def try_reserve_slot(context, &block)
123
+ run_user_code do
124
+ block.call(@slot_supplier.try_reserve_slot(context))
125
+ rescue Exception => e # rubocop:disable Lint/RescueException
126
+ block.call(e)
127
+ end
128
+ end
129
+
130
+ def mark_slot_used(context, &block)
131
+ run_user_code do
132
+ block.call(@slot_supplier.mark_slot_used(context))
133
+ rescue Exception => e # rubocop:disable Lint/RescueException
134
+ block.call(e)
135
+ end
136
+ end
137
+
138
+ def release_slot(context, &block)
139
+ run_user_code do
140
+ block.call(@slot_supplier.release_slot(context))
141
+ rescue Exception => e # rubocop:disable Lint/RescueException
142
+ block.call(e)
143
+ end
144
+ end
145
+
146
+ private
147
+
148
+ def run_user_code(&)
149
+ if @thread_pool
150
+ @thread_pool.execute(&)
151
+ else
152
+ yield
153
+ end
154
+ end
155
+ end
106
156
  end
107
157
  end
108
158
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'google/protobuf/well_known_types'
4
4
  require 'securerandom'
5
+ require 'temporalio/activity'
5
6
  require 'temporalio/api'
6
7
  require 'temporalio/client/activity_id_reference'
7
8
  require 'temporalio/client/async_activity_handle'
@@ -829,9 +830,13 @@ module Temporalio
829
830
  rpc_options: Implementation.with_default_rpc_options(input.rpc_options)
830
831
  )
831
832
  end
832
- raise Error::AsyncActivityCanceledError if resp.cancel_requested
833
+ return unless resp.cancel_requested || resp.activity_paused || resp.activity_reset
833
834
 
834
- nil
835
+ raise Error::AsyncActivityCanceledError, Activity::CancellationDetails.new(
836
+ cancel_requested: resp.cancel_requested,
837
+ paused: resp.activity_paused,
838
+ reset: resp.activity_reset
839
+ )
835
840
  end
836
841
 
837
842
  def complete_async_activity(input)
@@ -185,6 +185,7 @@ module Temporalio
185
185
  payloads = codec.decode(payloads) if codec
186
186
  payloads.map { |p| Temporalio::Converters::RawValue.new(p) }
187
187
  end,
188
+ retry_policy: (RetryPolicy._from_proto(start.retry_policy) if start.retry_policy),
188
189
  schedule_to_close_timeout: Internal::ProtoUtils.duration_to_seconds(start.schedule_to_close_timeout),
189
190
  scheduled_time: Internal::ProtoUtils.timestamp_to_time(start.scheduled_time) || raise, # Never nil
190
191
  start_to_close_timeout: Internal::ProtoUtils.duration_to_seconds(start.start_to_close_timeout),
@@ -130,6 +130,7 @@ module Temporalio
130
130
  def execute_local_activity(
131
131
  activity,
132
132
  *args,
133
+ summary:,
133
134
  schedule_to_close_timeout:,
134
135
  schedule_to_start_timeout:,
135
136
  start_to_close_timeout:,
@@ -157,6 +158,7 @@ module Temporalio
157
158
  Temporalio::Worker::Interceptor::Workflow::ExecuteLocalActivityInput.new(
158
159
  activity:,
159
160
  args:,
161
+ summary:,
160
162
  schedule_to_close_timeout:,
161
163
  schedule_to_start_timeout:,
162
164
  start_to_close_timeout:,
@@ -84,7 +84,7 @@ module Temporalio
84
84
  when :all
85
85
  ''
86
86
  when Temporalio::Worker::IllegalWorkflowCallValidator
87
- disable do
87
+ disable_temporarily do
88
88
  vals.block.call(Temporalio::Worker::IllegalWorkflowCallValidator::CallInfo.new(
89
89
  class_name:, method_name: tp.callee_id, trace_point: tp
90
90
  ))
@@ -98,7 +98,7 @@ module Temporalio
98
98
  when true
99
99
  ''
100
100
  when Temporalio::Worker::IllegalWorkflowCallValidator
101
- disable do
101
+ disable_temporarily do
102
102
  per_method.block.call(Temporalio::Worker::IllegalWorkflowCallValidator::CallInfo.new(
103
103
  class_name:, method_name: tp.callee_id, trace_point: tp
104
104
  ))
@@ -118,8 +118,11 @@ module Temporalio
118
118
  end
119
119
 
120
120
  def enable(&block)
121
- # We've seen leaking issues in Ruby 3.2 where the TracePoint inadvertently remains enabled even for threads
122
- # that it was not started on. So we will check the thread ourselves.
121
+ # This is not reentrant and not expected to be called as such. We've seen leaking issues in Ruby 3.2 where
122
+ # the TracePoint inadvertently remains enabled even for threads that it was not started on. So we will check
123
+ # the thread ourselves. We also use the "enabled thread" concept for disabling checks too, see
124
+ # disable_temporarily for more details.
125
+
123
126
  @enabled_thread = Thread.current
124
127
  @tracepoint.enable do
125
128
  block.call
@@ -128,13 +131,17 @@ module Temporalio
128
131
  end
129
132
  end
130
133
 
131
- def disable(&block)
134
+ def disable_temporarily(&)
135
+ # An earlier version of this used @tracepoint.disable, but in some versions of Ruby, the observed behavior
136
+ # is confusingly not reentrant or at least not predictable. Therefore, instead of calling
137
+ # @tracepoint.disable, we are just unsetting the enabled thread. This means the tracer is still running, but
138
+ # no checks are performed. This is effectively a no-op if tracing was never enabled.
139
+
132
140
  previous_thread = @enabled_thread
133
- @tracepoint.disable do
134
- block.call
135
- ensure
136
- @enabled_thread = previous_thread
137
- end
141
+ @enabled_thread = nil
142
+ yield
143
+ ensure
144
+ @enabled_thread = previous_thread
138
145
  end
139
146
  end
140
147
  end
@@ -114,14 +114,15 @@ module Temporalio
114
114
  local_retry_threshold: ProtoUtils.seconds_to_duration(input.local_retry_threshold),
115
115
  attempt: do_backoff&.attempt || 0,
116
116
  original_schedule_time: do_backoff&.original_schedule_time
117
- )
117
+ ),
118
+ user_metadata: ProtoUtils.to_user_metadata(input.summary, nil, @instance.payload_converter)
118
119
  )
119
120
  )
120
121
  seq
121
122
  end
122
123
  end
123
124
 
124
- def execute_activity_with_local_backoffs(local:, cancellation:, result_hint:, &)
125
+ def execute_activity_with_local_backoffs(local:, cancellation:, result_hint:, &block)
125
126
  # We do not even want to schedule if the cancellation is already cancelled. We choose to use canceled
126
127
  # failure instead of wrapping in activity failure which is similar to what other SDKs do, with the accepted
127
128
  # tradeoff that it makes rescue more difficult (hence the presence of Error.canceled? helper).
@@ -130,7 +131,7 @@ module Temporalio
130
131
  # This has to be done in a loop for local activity backoff
131
132
  last_local_backoff = nil
132
133
  loop do
133
- result = execute_activity_once(local:, cancellation:, last_local_backoff:, result_hint:, &)
134
+ result = execute_activity_once(local:, cancellation:, last_local_backoff:, result_hint:, &block)
134
135
  return result unless result.is_a?(Bridge::Api::ActivityResult::DoBackoff)
135
136
 
136
137
  # @type var result: untyped
@@ -142,9 +143,9 @@ module Temporalio
142
143
  end
143
144
 
144
145
  # If this doesn't raise, it returns success | DoBackoff
145
- def execute_activity_once(local:, cancellation:, last_local_backoff:, result_hint:, &)
146
+ def execute_activity_once(local:, cancellation:, last_local_backoff:, result_hint:, &block)
146
147
  # Add to pending activities (removed by the resolver)
147
- seq = yield last_local_backoff
148
+ seq = block.call(last_local_backoff)
148
149
  @instance.pending_activities[seq] = Fiber.current
149
150
 
150
151
  # Add cancellation hook
@@ -125,6 +125,7 @@ module Temporalio
125
125
  continued_run_id: ProtoUtils.string_or(@init_job.continued_from_execution_run_id),
126
126
  cron_schedule: ProtoUtils.string_or(@init_job.cron_schedule),
127
127
  execution_timeout: ProtoUtils.duration_to_seconds(@init_job.workflow_execution_timeout),
128
+ first_execution_run_id: @init_job.first_execution_run_id,
128
129
  headers: ProtoUtils.headers_from_proto_map(@init_job.headers, @payload_converter) || {},
129
130
  last_failure: if @init_job.continued_failure
130
131
  @failure_converter.from_failure(@init_job.continued_failure, @payload_converter)
@@ -162,86 +163,9 @@ module Temporalio
162
163
  end
163
164
 
164
165
  def activate(activation)
165
- # Run inside of scheduler
166
- run_in_scheduler { activate_internal(activation) }
167
- end
168
-
169
- def add_command(command)
170
- raise Workflow::InvalidWorkflowStateError, 'Cannot add commands in this context' if @context_frozen
171
-
172
- @commands << command
173
- end
174
-
175
- def instance
176
- @instance or raise 'Instance accessed before created'
177
- end
178
-
179
- def search_attributes
180
- # Lazy on first access
181
- @search_attributes ||= SearchAttributes._from_proto(
182
- @init_job.search_attributes, disable_mutations: true, never_nil: true
183
- ) || raise
184
- end
185
-
186
- def memo
187
- # Lazy on first access
188
- @memo ||= ExternallyImmutableHash.new(ProtoUtils.memo_from_proto(@init_job.memo, payload_converter) || {})
189
- end
190
-
191
- def now
192
- # Create each time
193
- ProtoUtils.timestamp_to_time(@now_timestamp) or raise 'Time unexpectedly not present'
194
- end
195
-
196
- def illegal_call_tracing_disabled(&)
197
- @tracer.disable(&)
198
- end
199
-
200
- def patch(patch_id:, deprecated:)
201
- # Use memoized result if present. If this is being deprecated, we can still use memoized result and skip the
202
- # command.
203
- patch_id = patch_id.to_s
204
- @patches_memoized ||= {}
205
- @patches_memoized.fetch(patch_id) do
206
- patched = !replaying || @patches_notified.include?(patch_id)
207
- @patches_memoized[patch_id] = patched
208
- if patched
209
- add_command(
210
- Bridge::Api::WorkflowCommands::WorkflowCommand.new(
211
- set_patch_marker: Bridge::Api::WorkflowCommands::SetPatchMarker.new(patch_id:, deprecated:)
212
- )
213
- )
214
- end
215
- patched
216
- end
217
- end
218
-
219
- def metric_meter
220
- @metric_meter ||= ReplaySafeMetric::Meter.new(
221
- @runtime_metric_meter.with_additional_attributes(
222
- {
223
- namespace: info.namespace,
224
- task_queue: info.task_queue,
225
- workflow_type: info.workflow_type
226
- }
227
- )
228
- )
229
- end
230
-
231
- private
232
-
233
- def run_in_scheduler(&)
166
+ # Run inside of scheduler (removed on ensure)
234
167
  Fiber.set_scheduler(@scheduler)
235
- if @tracer
236
- @tracer.enable(&)
237
- else
238
- yield
239
- end
240
- ensure
241
- Fiber.set_scheduler(nil)
242
- end
243
168
 
244
- def activate_internal(activation)
245
169
  # Reset some activation state
246
170
  @commands = []
247
171
  @current_activation_error = nil
@@ -266,8 +190,12 @@ module Temporalio
266
190
  # the first activation)
267
191
  @primary_fiber ||= schedule(top_level: true) { run_workflow }
268
192
 
269
- # Run the event loop
270
- @scheduler.run_until_all_yielded
193
+ # Run the event loop in the tracer if it exists
194
+ if @tracer
195
+ @tracer.enable { @scheduler.run_until_all_yielded }
196
+ else
197
+ @scheduler.run_until_all_yielded
198
+ end
271
199
  rescue Exception => e # rubocop:disable Lint/RescueException
272
200
  on_top_level_exception(e)
273
201
  end
@@ -306,8 +234,77 @@ module Temporalio
306
234
  ensure
307
235
  @commands = nil
308
236
  @current_activation_error = nil
237
+ Fiber.set_scheduler(nil)
238
+ end
239
+
240
+ def add_command(command)
241
+ raise Workflow::InvalidWorkflowStateError, 'Cannot add commands in this context' if @context_frozen
242
+
243
+ @commands << command
244
+ end
245
+
246
+ def instance
247
+ @instance or raise 'Instance accessed before created'
248
+ end
249
+
250
+ def search_attributes
251
+ # Lazy on first access
252
+ @search_attributes ||= SearchAttributes._from_proto(
253
+ @init_job.search_attributes, disable_mutations: true, never_nil: true
254
+ ) || raise
255
+ end
256
+
257
+ def memo
258
+ # Lazy on first access
259
+ @memo ||= ExternallyImmutableHash.new(ProtoUtils.memo_from_proto(@init_job.memo, payload_converter) || {})
260
+ end
261
+
262
+ def now
263
+ # Create each time
264
+ ProtoUtils.timestamp_to_time(@now_timestamp) or raise 'Time unexpectedly not present'
309
265
  end
310
266
 
267
+ def illegal_call_tracing_disabled(&)
268
+ if @tracer
269
+ @tracer.disable_temporarily(&)
270
+ else
271
+ yield
272
+ end
273
+ end
274
+
275
+ def patch(patch_id:, deprecated:)
276
+ # Use memoized result if present. If this is being deprecated, we can still use memoized result and skip the
277
+ # command.
278
+ patch_id = patch_id.to_s
279
+ @patches_memoized ||= {}
280
+ @patches_memoized.fetch(patch_id) do
281
+ patched = !replaying || @patches_notified.include?(patch_id)
282
+ @patches_memoized[patch_id] = patched
283
+ if patched
284
+ add_command(
285
+ Bridge::Api::WorkflowCommands::WorkflowCommand.new(
286
+ set_patch_marker: Bridge::Api::WorkflowCommands::SetPatchMarker.new(patch_id:, deprecated:)
287
+ )
288
+ )
289
+ end
290
+ patched
291
+ end
292
+ end
293
+
294
+ def metric_meter
295
+ @metric_meter ||= ReplaySafeMetric::Meter.new(
296
+ @runtime_metric_meter.with_additional_attributes(
297
+ {
298
+ namespace: info.namespace,
299
+ task_queue: info.task_queue,
300
+ workflow_type: info.workflow_type
301
+ }
302
+ )
303
+ )
304
+ end
305
+
306
+ private
307
+
311
308
  def create_instance
312
309
  # Convert workflow arguments
313
310
  @workflow_arguments = convert_args(payload_array: @init_job.arguments,
@@ -25,6 +25,7 @@ module Temporalio
25
25
  local?: false,
26
26
  priority: Temporalio::Priority.default,
27
27
  raw_heartbeat_details: [],
28
+ retry_policy: RetryPolicy.new,
28
29
  schedule_to_close_timeout: 1.0,
29
30
  scheduled_time: Time.at(0),
30
31
  start_to_close_timeout: 1.0,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Temporalio
4
- VERSION = '0.6.0'
4
+ VERSION = '1.0.0'
5
5
  end
@@ -228,6 +228,7 @@ module Temporalio
228
228
  ExecuteLocalActivityInput = Data.define(
229
229
  :activity,
230
230
  :args,
231
+ :summary,
231
232
  :schedule_to_close_timeout,
232
233
  :schedule_to_start_timeout,
233
234
  :start_to_close_timeout,
@@ -22,10 +22,11 @@ module Temporalio
22
22
  end
23
23
 
24
24
  # @!visibility private
25
- def _to_bridge_options
25
+ def _to_bridge_options(_tuner)
26
26
  Internal::Bridge::Worker::TunerSlotSupplierOptions.new(
27
27
  fixed_size: slots,
28
- resource_based: nil
28
+ resource_based: nil,
29
+ custom: nil
29
30
  )
30
31
  end
31
32
  end
@@ -36,7 +37,7 @@ module Temporalio
36
37
  class ResourceBased < SlotSupplier
37
38
  attr_reader :tuner_options, :slot_options
38
39
 
39
- # Create a reosurce-based slot supplier.
40
+ # Create a resource-based slot supplier.
40
41
  #
41
42
  # @param tuner_options [ResourceBasedTunerOptions] General tuner options.
42
43
  # @param slot_options [ResourceBasedSlotOptions] Slot-supplier-specific tuner options.
@@ -46,7 +47,7 @@ module Temporalio
46
47
  end
47
48
 
48
49
  # @!visibility private
49
- def _to_bridge_options
50
+ def _to_bridge_options(_tuner)
50
51
  Internal::Bridge::Worker::TunerSlotSupplierOptions.new(
51
52
  fixed_size: nil,
52
53
  resource_based: Internal::Bridge::Worker::TunerResourceBasedSlotSupplierOptions.new(
@@ -55,14 +56,175 @@ module Temporalio
55
56
  min_slots: slot_options.min_slots,
56
57
  max_slots: slot_options.max_slots,
57
58
  ramp_throttle: slot_options.ramp_throttle
59
+ ),
60
+ custom: nil
61
+ )
62
+ end
63
+ end
64
+
65
+ # A slot supplier that has callbacks invoked to handle slot supplying.
66
+ #
67
+ # Users should be cautious when implementing this and make sure it is heavily tested and the documentation for
68
+ # every method is well understood.
69
+ #
70
+ # @note WARNING: This API is experimental.
71
+ class Custom < SlotSupplier
72
+ # Context provided for slot reservation on custom slot supplier.
73
+ #
74
+ # @!attribute slot_type
75
+ # @return [:workflow, :activity, :local_activity, :nexus] Slot type.
76
+ # @!attribute task_queue
77
+ # @return [String] Task queue.
78
+ # @!attribute worker_identity
79
+ # @return [String] Worker identity.
80
+ # @!attribute worker_deployment_name
81
+ # @return [String] Worker deployment name or empty string if not applicable.
82
+ # @!attribute worker_build_id
83
+ # @return [String] Worker build ID or empty string if not applicable.
84
+ # @!attribute sticky?
85
+ # @return [Boolean] True if this reservation is for a sticky workflow task.
86
+ ReserveContext = Data.define(
87
+ :slot_type,
88
+ :task_queue,
89
+ :worker_identity,
90
+ :worker_deployment_name,
91
+ :worker_build_id,
92
+ :sticky?
93
+ )
94
+
95
+ # Context provided for marking a slot used.
96
+ #
97
+ # @!attribute slot_info
98
+ # @return [SlotInfo::Workflow, SlotInfo::Activity, SlotInfo::LocalActivity, SlotInfo::Nexus] Information
99
+ # about the slot. This is never nil.
100
+ # @!attribute permit
101
+ # @return [Object] Object that was provided as the permit on reserve.
102
+ MarkUsedContext = Data.define(
103
+ :slot_info,
104
+ :permit
105
+ )
106
+
107
+ # Context provided for releasing a slot.
108
+ #
109
+ # @!attribute slot_info
110
+ # @return [SlotInfo::Workflow, SlotInfo::Activity, SlotInfo::LocalActivity, SlotInfo::Nexus, nil]
111
+ # Information about the slot. This may be nil if the slot was never used.
112
+ # @!attribute permit
113
+ # @return [Object] Object that was provided as the permit on reserve.
114
+ ReleaseContext = Data.define(
115
+ :slot_info,
116
+ :permit
117
+ )
118
+
119
+ # Reserve a slot.
120
+ #
121
+ # This can/should block and must provide the permit to the (code) block. The permit is any object (including
122
+ # nil) that will be given on the context for mark_slot_used and release_slot.
123
+ #
124
+ # Just returning from this call is not enough to reserve the slot, a permit must be provided to the block
125
+ # (e.g. via yield or block.call). If the call completes, the system will still wait on the block (so this can
126
+ # be backgrounded by passing the block to something else). Reservations may be canceled via the given
127
+ # cancellation. Users can do things like add_cancel_callback, but it is very important that the code in the
128
+ # callback is fast as it is run on the same reactor thread as many other Temporal Ruby worker calls.
129
+ #
130
+ # @note WARNING: This call should never raise an exception. Any exception raised is ignored and this is called
131
+ # again after 1 second.
132
+ #
133
+ # @param context [ReserveContext] Contextual information about this reserve call.
134
+ # @param cancellation [Cancellation] Cancellation that is canceled when the reservation is no longer being
135
+ # asked for.
136
+ # @yield [Object] Confirm reservation and provide a permit.
137
+ def reserve_slot(context, cancellation, &)
138
+ raise NotImplementedError
139
+ end
140
+
141
+ # Try to reserve a slot.
142
+ #
143
+ # @note WARNING: This should never block, this should return immediately with a permit, or nil if the
144
+ # reservation could not occur.
145
+ #
146
+ # @note WARNING: This call should never raise an exception. Any exception raised is ignored and the slot
147
+ # reservation attempt fails (i.e. same as if this method returned nil).
148
+ #
149
+ # @param context [ReserveContext] Contextual information about this reserve call.
150
+ # @return [Object, nil] A non-nil object to perform the reservation successfully, a nil to fail the
151
+ # reservation.
152
+ def try_reserve_slot(context)
153
+ raise NotImplementedError
154
+ end
155
+
156
+ # Mark a slot as used.
157
+ #
158
+ # Due to the nature of Temporal polling, slots are reserved before they are used and may never get used. This
159
+ # call is made as just a notification when a slot is actually used.
160
+ #
161
+ # @note WARNING: This should never block, this should return immediately.
162
+ #
163
+ # @note WARNING: This call should never raise an exception. Any exception raised is ignored.
164
+ #
165
+ # @param context [MarkUsedContext] Contextual information about this reserve call.
166
+ def mark_slot_used(context)
167
+ raise NotImplementedError
168
+ end
169
+
170
+ # Release a previously reserved slot.
171
+ #
172
+ # @note WARNING: This should never block, this should return immediately.
173
+ #
174
+ # @note WARNING: This call should never raise an exception. Any exception raised is ignored.
175
+ #
176
+ # @param context [ReleaseContext] Contextual information about this reserve call.
177
+ def release_slot(context)
178
+ raise NotImplementedError
179
+ end
180
+
181
+ # @!visibility private
182
+ def _to_bridge_options(tuner)
183
+ Internal::Bridge::Worker::TunerSlotSupplierOptions.new(
184
+ fixed_size: nil,
185
+ resource_based: nil,
186
+ custom: Internal::Bridge::Worker::CustomSlotSupplier.new(
187
+ slot_supplier: self,
188
+ thread_pool: tuner.custom_slot_supplier_thread_pool
58
189
  )
59
190
  )
60
191
  end
192
+
193
+ # Slot information.
194
+ module SlotInfo
195
+ # Information about a workflow slot.
196
+ #
197
+ # @!attribute workflow_type
198
+ # @return [String] Workflow type.
199
+ # @!attribute sticky?
200
+ # @return [Boolean] Whether the slot was for a sticky task.
201
+ Workflow = Data.define(:workflow_type, :sticky?)
202
+
203
+ # Information about an activity slot.
204
+ #
205
+ # @!attribute activity_type
206
+ # @return [String] Activity type.
207
+ Activity = Data.define(:activity_type)
208
+
209
+ # Information about a local activity slot.
210
+ #
211
+ # @!attribute activity_type
212
+ # @return [String] Activity type.
213
+ LocalActivity = Data.define(:activity_type)
214
+
215
+ # Information about a Nexus slot.
216
+ #
217
+ # @!attribute service
218
+ # @return [String] Nexus service.
219
+ # @!attribute operation
220
+ # @return [String] Nexus operation.
221
+ Nexus = Data.define(:service, :operation)
222
+ end
61
223
  end
62
224
 
63
225
  # @!visibility private
64
- def _to_bridge_options
65
- raise ArgumentError, 'Tuner slot suppliers must be instances of Fixed or ResourceBased'
226
+ def _to_bridge_options(_tuner)
227
+ raise ArgumentError, 'Tuner slot suppliers must be instances of Fixed, ResourceBased, or Custom'
66
228
  end
67
229
  end
68
230
 
@@ -75,10 +237,9 @@ module Temporalio
75
237
  # @!attribute target_cpu_usage
76
238
  # @return [Float] A value between 0 and 1 that represents the target (system) CPU usage. This can be set to 1.0
77
239
  # if desired, but it's recommended to leave some headroom for other processes.
78
- ResourceBasedTunerOptions = Struct.new(
240
+ ResourceBasedTunerOptions = Data.define(
79
241
  :target_memory_usage,
80
- :target_cpu_usage,
81
- keyword_init: true
242
+ :target_cpu_usage
82
243
  )
83
244
 
84
245
  # Options for a specific slot type being used with {SlotSupplier::ResourceBased}.
@@ -94,11 +255,10 @@ module Temporalio
94
255
  #
95
256
  # This value matters because how many resources a task will use cannot be determined ahead of time, and thus
96
257
  # the system should wait to see how much resources are used before issuing more slots.
97
- ResourceBasedSlotOptions = Struct.new(
258
+ ResourceBasedSlotOptions = Data.define(
98
259
  :min_slots,
99
260
  :max_slots,
100
- :ramp_throttle,
101
- keyword_init: true
261
+ :ramp_throttle
102
262
  )
103
263
 
104
264
  # Create a fixed-size tuner with the provided number of slots.
@@ -161,27 +321,36 @@ module Temporalio
161
321
  # @return [SlotSupplier] Slot supplier for local activities.
162
322
  attr_reader :local_activity_slot_supplier
163
323
 
324
+ # @return [ThreadPool, nil] Thread pool for custom slot suppliers.
325
+ attr_reader :custom_slot_supplier_thread_pool
326
+
164
327
  # Create a tuner from 3 slot suppliers.
165
328
  #
166
329
  # @param workflow_slot_supplier [SlotSupplier] Slot supplier for workflows.
167
330
  # @param activity_slot_supplier [SlotSupplier] Slot supplier for activities.
168
331
  # @param local_activity_slot_supplier [SlotSupplier] Slot supplier for local activities.
332
+ # @param custom_slot_supplier_thread_pool [ThreadPool, nil] Thread pool to make all custom slot supplier calls on.
333
+ # If there are no custom slot suppliers, this parameter is ignored. Technically users may set this to nil which
334
+ # will not use a thread pool to make slot supplier calls, but that is dangerous and not advised because even the
335
+ # slightest blocking call can slow down the system.
169
336
  def initialize(
170
337
  workflow_slot_supplier:,
171
338
  activity_slot_supplier:,
172
- local_activity_slot_supplier:
339
+ local_activity_slot_supplier:,
340
+ custom_slot_supplier_thread_pool: ThreadPool.default
173
341
  )
174
342
  @workflow_slot_supplier = workflow_slot_supplier
175
343
  @activity_slot_supplier = activity_slot_supplier
176
344
  @local_activity_slot_supplier = local_activity_slot_supplier
345
+ @custom_slot_supplier_thread_pool = custom_slot_supplier_thread_pool
177
346
  end
178
347
 
179
348
  # @!visibility private
180
349
  def _to_bridge_options
181
350
  Internal::Bridge::Worker::TunerOptions.new(
182
- workflow_slot_supplier: workflow_slot_supplier._to_bridge_options,
183
- activity_slot_supplier: activity_slot_supplier._to_bridge_options,
184
- local_activity_slot_supplier: local_activity_slot_supplier._to_bridge_options
351
+ workflow_slot_supplier: workflow_slot_supplier._to_bridge_options(self),
352
+ activity_slot_supplier: activity_slot_supplier._to_bridge_options(self),
353
+ local_activity_slot_supplier: local_activity_slot_supplier._to_bridge_options(self)
185
354
  )
186
355
  end
187
356
  end
@@ -7,6 +7,7 @@ module Temporalio
7
7
  :continued_run_id,
8
8
  :cron_schedule,
9
9
  :execution_timeout,
10
+ :first_execution_run_id,
10
11
  :headers,
11
12
  :last_failure,
12
13
  :last_result,
@@ -35,6 +36,8 @@ module Temporalio
35
36
  # @return [String, nil] Cron schedule if applicable.
36
37
  # @!attribute execution_timeout
37
38
  # @return [Float, nil] Execution timeout for the workflow.
39
+ # @!attribute first_execution_run_id
40
+ # @return [String] The very first run ID the workflow ever had, following continuation chains.
38
41
  # @!attribute headers
39
42
  # @return [Hash<String, Api::Common::V1::Payload>] Headers.
40
43
  # @!attribute last_failure
@@ -208,14 +208,16 @@ module Temporalio
208
208
  #
209
209
  # @param activity [Class<Activity::Definition>, Symbol, String] Activity definition class or name.
210
210
  # @param args [Array<Object>] Arguments to the activity.
211
+ # @param summary [String, nil] Single-line summary for this activity that may appear in CLI/UI. This can be in
212
+ # single-line Temporal markdown format. This is currently experimental.
211
213
  # @param schedule_to_close_timeout [Float, nil] Max amount of time the activity can take from first being scheduled
212
214
  # to being completed before it times out. This is inclusive of all retries.
213
215
  # @param schedule_to_start_timeout [Float, nil] Max amount of time the activity can take to be started from first
214
216
  # being scheduled.
215
217
  # @param start_to_close_timeout [Float, nil] Max amount of time a single activity run can take from when it starts
216
218
  # to when it completes. This is per retry.
217
- # @param retry_policy [RetryPolicy] How an activity is retried on failure. If unset, a server-defined default is
218
- # used. Set maximum attempts to 1 to disable retries.
219
+ # @param retry_policy [RetryPolicy, nil] How an activity is retried on failure. If unset, a default policy is used.
220
+ # Set maximum attempts to 1 to disable retries.
219
221
  # @param local_retry_threshold [Float, nil] If the activity is retrying and backoff would exceed this value, a timer
220
222
  # is scheduled and the activity is retried after. Otherwise, backoff will happen internally within the task.
221
223
  # Defaults to 1 minute.
@@ -238,6 +240,7 @@ module Temporalio
238
240
  def self.execute_local_activity(
239
241
  activity,
240
242
  *args,
243
+ summary: nil,
241
244
  schedule_to_close_timeout: nil,
242
245
  schedule_to_start_timeout: nil,
243
246
  start_to_close_timeout: nil,
@@ -251,7 +254,7 @@ module Temporalio
251
254
  )
252
255
  _current.execute_local_activity(
253
256
  activity, *args,
254
- schedule_to_close_timeout:, schedule_to_start_timeout:, start_to_close_timeout:,
257
+ summary:, schedule_to_close_timeout:, schedule_to_start_timeout:, start_to_close_timeout:,
255
258
  retry_policy:, local_retry_threshold:, cancellation:, cancellation_type:,
256
259
  activity_id:, arg_hints:, result_hint:
257
260
  )
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: temporalio
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 1.0.0
5
5
  platform: aarch64-linux
6
6
  authors:
7
7
  - Temporal Technologies Inc
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-08-25 00:00:00.000000000 Z
11
+ date: 2025-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-protobuf
@@ -156,6 +156,7 @@ files:
156
156
  - lib/temporalio/converters/payload_converter/json_plain.rb
157
157
  - lib/temporalio/converters/payload_converter/json_protobuf.rb
158
158
  - lib/temporalio/converters/raw_value.rb
159
+ - lib/temporalio/env_config.rb
159
160
  - lib/temporalio/error.rb
160
161
  - lib/temporalio/error/failure.rb
161
162
  - lib/temporalio/internal.rb