temporalio 1.1.0-aarch64-linux → 1.3.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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +6 -4
  3. data/lib/temporalio/activity/definition.rb +6 -1
  4. data/lib/temporalio/api/activity/v1/message.rb +11 -2
  5. data/lib/temporalio/api/command/v1/message.rb +1 -1
  6. data/lib/temporalio/api/common/v1/message.rb +2 -1
  7. data/lib/temporalio/api/deployment/v1/message.rb +2 -1
  8. data/lib/temporalio/api/enums/v1/activity.rb +23 -0
  9. data/lib/temporalio/api/enums/v1/event_type.rb +1 -1
  10. data/lib/temporalio/api/enums/v1/failed_cause.rb +1 -1
  11. data/lib/temporalio/api/enums/v1/task_queue.rb +2 -1
  12. data/lib/temporalio/api/enums/v1/workflow.rb +3 -1
  13. data/lib/temporalio/api/errordetails/v1/message.rb +2 -1
  14. data/lib/temporalio/api/history/v1/message.rb +3 -1
  15. data/lib/temporalio/api/namespace/v1/message.rb +2 -1
  16. data/lib/temporalio/api/nexus/v1/message.rb +1 -1
  17. data/lib/temporalio/api/operatorservice/v1/request_response.rb +1 -1
  18. data/lib/temporalio/api/payload_visitor.rb +64 -0
  19. data/lib/temporalio/api/taskqueue/v1/message.rb +1 -1
  20. data/lib/temporalio/api/worker/v1/message.rb +1 -1
  21. data/lib/temporalio/api/workflow/v1/message.rb +2 -1
  22. data/lib/temporalio/api/workflowservice/v1/request_response.rb +23 -1
  23. data/lib/temporalio/api/workflowservice/v1/service.rb +1 -1
  24. data/lib/temporalio/client/connection/workflow_service.rb +150 -0
  25. data/lib/temporalio/client/connection.rb +17 -3
  26. data/lib/temporalio/client/plugin.rb +42 -0
  27. data/lib/temporalio/client.rb +82 -15
  28. data/lib/temporalio/common_enums.rb +0 -2
  29. data/lib/temporalio/contrib/open_telemetry.rb +21 -0
  30. data/lib/temporalio/converters/failure_converter.rb +30 -0
  31. data/lib/temporalio/converters/payload_converter/binary_protobuf.rb +4 -1
  32. data/lib/temporalio/converters/payload_converter/json_protobuf.rb +4 -1
  33. data/lib/temporalio/env_config.rb +3 -14
  34. data/lib/temporalio/error/failure.rb +66 -0
  35. data/lib/temporalio/internal/bridge/3.3/temporalio_bridge.so +0 -0
  36. data/lib/temporalio/internal/bridge/3.4/temporalio_bridge.so +0 -0
  37. data/lib/temporalio/internal/bridge/{3.2 → 4.0}/temporalio_bridge.so +0 -0
  38. data/lib/temporalio/internal/bridge/api/core_interface.rb +3 -1
  39. data/lib/temporalio/internal/bridge/api/nexus/nexus.rb +2 -1
  40. data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +1 -1
  41. data/lib/temporalio/internal/bridge/worker.rb +1 -0
  42. data/lib/temporalio/internal/worker/workflow_instance/context.rb +9 -0
  43. data/lib/temporalio/internal/worker/workflow_instance/externally_immutable_hash.rb +1 -1
  44. data/lib/temporalio/internal/worker/workflow_instance/handler_hash.rb +1 -1
  45. data/lib/temporalio/internal/worker/workflow_instance/illegal_call_tracer.rb +8 -4
  46. data/lib/temporalio/internal/worker/workflow_instance/nexus_client.rb +42 -0
  47. data/lib/temporalio/internal/worker/workflow_instance/nexus_operation_handle.rb +51 -0
  48. data/lib/temporalio/internal/worker/workflow_instance/outbound_implementation.rb +100 -11
  49. data/lib/temporalio/internal/worker/workflow_instance/replay_safe_logger.rb +2 -1
  50. data/lib/temporalio/internal/worker/workflow_instance/replay_safe_metric.rb +2 -1
  51. data/lib/temporalio/internal/worker/workflow_instance/scheduler.rb +10 -1
  52. data/lib/temporalio/internal/worker/workflow_instance.rb +26 -11
  53. data/lib/temporalio/simple_plugin.rb +192 -0
  54. data/lib/temporalio/testing/workflow_environment.rb +40 -0
  55. data/lib/temporalio/version.rb +1 -1
  56. data/lib/temporalio/versioning_override.rb +0 -2
  57. data/lib/temporalio/worker/deployment_options.rb +0 -2
  58. data/lib/temporalio/worker/interceptor.rb +27 -0
  59. data/lib/temporalio/worker/plugin.rb +88 -0
  60. data/lib/temporalio/worker/workflow_executor/thread_pool.rb +1 -1
  61. data/lib/temporalio/worker/workflow_replayer.rb +28 -5
  62. data/lib/temporalio/worker.rb +116 -43
  63. data/lib/temporalio/worker_deployment_version.rb +0 -2
  64. data/lib/temporalio/workflow/definition.rb +3 -4
  65. data/lib/temporalio/workflow/nexus_client.rb +81 -0
  66. data/lib/temporalio/workflow/nexus_operation_cancellation_type.rb +21 -0
  67. data/lib/temporalio/workflow/nexus_operation_handle.rb +37 -0
  68. data/lib/temporalio/workflow.rb +22 -1
  69. data/temporalio.gemspec +1 -1
  70. metadata +14 -5
@@ -1425,6 +1425,156 @@ module Temporalio
1425
1425
  rpc_options:
1426
1426
  )
1427
1427
  end
1428
+
1429
+ # Calls WorkflowService.PauseWorkflowExecution API call.
1430
+ #
1431
+ # @param request [Temporalio::Api::WorkflowService::V1::PauseWorkflowExecutionRequest] API request.
1432
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
1433
+ # @return [Temporalio::Api::WorkflowService::V1::PauseWorkflowExecutionResponse] API response.
1434
+ def pause_workflow_execution(request, rpc_options: nil)
1435
+ invoke_rpc(
1436
+ rpc: 'pause_workflow_execution',
1437
+ request_class: Temporalio::Api::WorkflowService::V1::PauseWorkflowExecutionRequest,
1438
+ response_class: Temporalio::Api::WorkflowService::V1::PauseWorkflowExecutionResponse,
1439
+ request:,
1440
+ rpc_options:
1441
+ )
1442
+ end
1443
+
1444
+ # Calls WorkflowService.UnpauseWorkflowExecution API call.
1445
+ #
1446
+ # @param request [Temporalio::Api::WorkflowService::V1::UnpauseWorkflowExecutionRequest] API request.
1447
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
1448
+ # @return [Temporalio::Api::WorkflowService::V1::UnpauseWorkflowExecutionResponse] API response.
1449
+ def unpause_workflow_execution(request, rpc_options: nil)
1450
+ invoke_rpc(
1451
+ rpc: 'unpause_workflow_execution',
1452
+ request_class: Temporalio::Api::WorkflowService::V1::UnpauseWorkflowExecutionRequest,
1453
+ response_class: Temporalio::Api::WorkflowService::V1::UnpauseWorkflowExecutionResponse,
1454
+ request:,
1455
+ rpc_options:
1456
+ )
1457
+ end
1458
+
1459
+ # Calls WorkflowService.StartActivityExecution API call.
1460
+ #
1461
+ # @param request [Temporalio::Api::WorkflowService::V1::StartActivityExecutionRequest] API request.
1462
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
1463
+ # @return [Temporalio::Api::WorkflowService::V1::StartActivityExecutionResponse] API response.
1464
+ def start_activity_execution(request, rpc_options: nil)
1465
+ invoke_rpc(
1466
+ rpc: 'start_activity_execution',
1467
+ request_class: Temporalio::Api::WorkflowService::V1::StartActivityExecutionRequest,
1468
+ response_class: Temporalio::Api::WorkflowService::V1::StartActivityExecutionResponse,
1469
+ request:,
1470
+ rpc_options:
1471
+ )
1472
+ end
1473
+
1474
+ # Calls WorkflowService.DescribeActivityExecution API call.
1475
+ #
1476
+ # @param request [Temporalio::Api::WorkflowService::V1::DescribeActivityExecutionRequest] API request.
1477
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
1478
+ # @return [Temporalio::Api::WorkflowService::V1::DescribeActivityExecutionResponse] API response.
1479
+ def describe_activity_execution(request, rpc_options: nil)
1480
+ invoke_rpc(
1481
+ rpc: 'describe_activity_execution',
1482
+ request_class: Temporalio::Api::WorkflowService::V1::DescribeActivityExecutionRequest,
1483
+ response_class: Temporalio::Api::WorkflowService::V1::DescribeActivityExecutionResponse,
1484
+ request:,
1485
+ rpc_options:
1486
+ )
1487
+ end
1488
+
1489
+ # Calls WorkflowService.PollActivityExecution API call.
1490
+ #
1491
+ # @param request [Temporalio::Api::WorkflowService::V1::PollActivityExecutionRequest] API request.
1492
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
1493
+ # @return [Temporalio::Api::WorkflowService::V1::PollActivityExecutionResponse] API response.
1494
+ def poll_activity_execution(request, rpc_options: nil)
1495
+ invoke_rpc(
1496
+ rpc: 'poll_activity_execution',
1497
+ request_class: Temporalio::Api::WorkflowService::V1::PollActivityExecutionRequest,
1498
+ response_class: Temporalio::Api::WorkflowService::V1::PollActivityExecutionResponse,
1499
+ request:,
1500
+ rpc_options:
1501
+ )
1502
+ end
1503
+
1504
+ # Calls WorkflowService.ListActivityExecutions API call.
1505
+ #
1506
+ # @param request [Temporalio::Api::WorkflowService::V1::ListActivityExecutionsRequest] API request.
1507
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
1508
+ # @return [Temporalio::Api::WorkflowService::V1::ListActivityExecutionsResponse] API response.
1509
+ def list_activity_executions(request, rpc_options: nil)
1510
+ invoke_rpc(
1511
+ rpc: 'list_activity_executions',
1512
+ request_class: Temporalio::Api::WorkflowService::V1::ListActivityExecutionsRequest,
1513
+ response_class: Temporalio::Api::WorkflowService::V1::ListActivityExecutionsResponse,
1514
+ request:,
1515
+ rpc_options:
1516
+ )
1517
+ end
1518
+
1519
+ # Calls WorkflowService.CountActivityExecutions API call.
1520
+ #
1521
+ # @param request [Temporalio::Api::WorkflowService::V1::CountActivityExecutionsRequest] API request.
1522
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
1523
+ # @return [Temporalio::Api::WorkflowService::V1::CountActivityExecutionsResponse] API response.
1524
+ def count_activity_executions(request, rpc_options: nil)
1525
+ invoke_rpc(
1526
+ rpc: 'count_activity_executions',
1527
+ request_class: Temporalio::Api::WorkflowService::V1::CountActivityExecutionsRequest,
1528
+ response_class: Temporalio::Api::WorkflowService::V1::CountActivityExecutionsResponse,
1529
+ request:,
1530
+ rpc_options:
1531
+ )
1532
+ end
1533
+
1534
+ # Calls WorkflowService.RequestCancelActivityExecution API call.
1535
+ #
1536
+ # @param request [Temporalio::Api::WorkflowService::V1::RequestCancelActivityExecutionRequest] API request.
1537
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
1538
+ # @return [Temporalio::Api::WorkflowService::V1::RequestCancelActivityExecutionResponse] API response.
1539
+ def request_cancel_activity_execution(request, rpc_options: nil)
1540
+ invoke_rpc(
1541
+ rpc: 'request_cancel_activity_execution',
1542
+ request_class: Temporalio::Api::WorkflowService::V1::RequestCancelActivityExecutionRequest,
1543
+ response_class: Temporalio::Api::WorkflowService::V1::RequestCancelActivityExecutionResponse,
1544
+ request:,
1545
+ rpc_options:
1546
+ )
1547
+ end
1548
+
1549
+ # Calls WorkflowService.TerminateActivityExecution API call.
1550
+ #
1551
+ # @param request [Temporalio::Api::WorkflowService::V1::TerminateActivityExecutionRequest] API request.
1552
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
1553
+ # @return [Temporalio::Api::WorkflowService::V1::TerminateActivityExecutionResponse] API response.
1554
+ def terminate_activity_execution(request, rpc_options: nil)
1555
+ invoke_rpc(
1556
+ rpc: 'terminate_activity_execution',
1557
+ request_class: Temporalio::Api::WorkflowService::V1::TerminateActivityExecutionRequest,
1558
+ response_class: Temporalio::Api::WorkflowService::V1::TerminateActivityExecutionResponse,
1559
+ request:,
1560
+ rpc_options:
1561
+ )
1562
+ end
1563
+
1564
+ # Calls WorkflowService.DeleteActivityExecution API call.
1565
+ #
1566
+ # @param request [Temporalio::Api::WorkflowService::V1::DeleteActivityExecutionRequest] API request.
1567
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
1568
+ # @return [Temporalio::Api::WorkflowService::V1::DeleteActivityExecutionResponse] API response.
1569
+ def delete_activity_execution(request, rpc_options: nil)
1570
+ invoke_rpc(
1571
+ rpc: 'delete_activity_execution',
1572
+ request_class: Temporalio::Api::WorkflowService::V1::DeleteActivityExecutionRequest,
1573
+ response_class: Temporalio::Api::WorkflowService::V1::DeleteActivityExecutionResponse,
1574
+ request:,
1575
+ rpc_options:
1576
+ )
1577
+ end
1428
1578
  end
1429
1579
  end
1430
1580
  end
@@ -169,6 +169,9 @@ module Temporalio
169
169
  # @param lazy_connect [Boolean] If true, there is no connection until the first call is attempted or a worker
170
170
  # is created with it. Clients from lazy connections cannot be used for workers if they have not performed a
171
171
  # connection.
172
+ # @param around_connect [Proc, nil] If present, this proc accepts two values: options and a block. The block must
173
+ # be yielded to only once with the options. The block does not return a meaningful value, nor should
174
+ # around_connect.
172
175
  #
173
176
  # @see Client.connect
174
177
  def initialize(
@@ -181,7 +184,8 @@ module Temporalio
181
184
  keep_alive: KeepAliveOptions.new,
182
185
  http_connect_proxy: nil,
183
186
  runtime: Runtime.default,
184
- lazy_connect: false
187
+ lazy_connect: false,
188
+ around_connect: nil
185
189
  )
186
190
  @options = Options.new(
187
191
  target_host:,
@@ -195,9 +199,19 @@ module Temporalio
195
199
  runtime:,
196
200
  lazy_connect:
197
201
  ).freeze
198
- # Create core client now if not lazy
199
202
  @core_client_mutex = Mutex.new
200
- _core_client unless lazy_connect
203
+ # Create core client now if not lazy, applying around_connect if present
204
+ if around_connect
205
+ # Technically around_connect can never run the block for whatever reason (i.e. plugin returning a mock
206
+ # connection), so we don't enforce it
207
+ around_connect.call(@options) do |options|
208
+ @options = options
209
+ _core_client unless lazy_connect
210
+ nil
211
+ end
212
+ else
213
+ _core_client unless lazy_connect
214
+ end
201
215
  # Create service instances
202
216
  @workflow_service = WorkflowService.new(self)
203
217
  @operator_service = OperatorService.new(self)
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Temporalio
4
+ class Client
5
+ # Plugin mixin to include for configuring clients and/or intercepting connect calls.
6
+ #
7
+ # This is a low-level implementation that requires abstract methods herein to be implemented. Many implementers may
8
+ # prefer {SimplePlugin} which includes this.
9
+ #
10
+ # WARNING: Plugins are experimental.
11
+ module Plugin
12
+ # @abstract
13
+ # @return [String] Name of the plugin.
14
+ def name
15
+ raise NotImplementedError
16
+ end
17
+
18
+ # Configure a client.
19
+ #
20
+ # @abstract
21
+ # @param options [Options] Current immutable options set.
22
+ # @return [Options] Options to use, possibly updated from original.
23
+ def configure_client(options)
24
+ raise NotImplementedError
25
+ end
26
+
27
+ # Connect a client.
28
+ #
29
+ # Implementers are expected to delegate to next_call to perform the connection. Note, this does not apply to users
30
+ # explicitly creating connections via {Connection} constructor.
31
+ #
32
+ # @abstract
33
+ # @param options [Connection::Options] Current immutable options set.
34
+ # @param next_call [Proc] Proc for the next plugin in the chain to call. It accepts the options and returns a
35
+ # {Connection}.
36
+ # @return [Connection] Connected connection.
37
+ def connect_client(options, next_call)
38
+ raise NotImplementedError
39
+ end
40
+ end
41
+ end
42
+ end
@@ -6,6 +6,7 @@ require 'temporalio/api'
6
6
  require 'temporalio/client/async_activity_handle'
7
7
  require 'temporalio/client/connection'
8
8
  require 'temporalio/client/interceptor'
9
+ require 'temporalio/client/plugin'
9
10
  require 'temporalio/client/schedule'
10
11
  require 'temporalio/client/schedule_handle'
11
12
  require 'temporalio/client/with_start_workflow_operation'
@@ -42,6 +43,7 @@ module Temporalio
42
43
  :connection,
43
44
  :namespace,
44
45
  :data_converter,
46
+ :plugins,
45
47
  :interceptors,
46
48
  :logger,
47
49
  :default_workflow_query_reject_condition
@@ -70,6 +72,9 @@ module Temporalio
70
72
  # @param tls [Boolean, Connection::TLSOptions] If false, do not use TLS. If true, use system default TLS options. If
71
73
  # TLS options are present, those TLS options will be used.
72
74
  # @param data_converter [Converters::DataConverter] Data converter to use for all data conversions to/from payloads.
75
+ # @param plugins [Array<Plugin>] Plugins to use for configuring clients and intercepting connection. Any plugins
76
+ # that also include {Worker::Plugin} will automatically be applied to the worker and should not be configured
77
+ # explicitly on the worker. WARNING: Plugins are experimental.
73
78
  # @param interceptors [Array<Interceptor>] Set of interceptors that are chained together to allow intercepting of
74
79
  # client calls. The earlier interceptors wrap the later ones. Any interceptors that also implement worker
75
80
  # interceptor will be used as worker interceptors too so they should not be given separately when creating a
@@ -101,6 +106,7 @@ module Temporalio
101
106
  api_key: nil,
102
107
  tls: nil,
103
108
  data_converter: Converters::DataConverter.default,
109
+ plugins: [],
104
110
  interceptors: [],
105
111
  logger: Logger.new($stdout, level: Logger::WARN),
106
112
  default_workflow_query_reject_condition: nil,
@@ -112,27 +118,78 @@ module Temporalio
112
118
  runtime: Runtime.default,
113
119
  lazy_connect: false
114
120
  )
121
+ # Prepare connection. The connection var is needed here so it can be used in callback for plugin.
122
+ base_connection = nil
123
+ final_connection = nil
124
+ around_connect = if plugins.any?
125
+ _validate_plugins!(plugins)
126
+ # For plugins, we have to do an around_connect approach with Connection where we provide a
127
+ # no-return-value proc that is invoked with the built options and yields newly built options.
128
+ # The connection will have been created before, but we allow plugins to return a
129
+ # different/extended connection, possibly avoiding actual connection altogether.
130
+ proc do |options, &block|
131
+ # Steep simply can't comprehend these advanced inline procs
132
+ # steep:ignore:start
133
+
134
+ # Root next call
135
+ next_call_called = false
136
+ next_call = proc do |options|
137
+ raise 'next_call called more than once' if next_call_called
138
+
139
+ next_call_called = true
140
+ block&.call(options)
141
+ base_connection
142
+ end
143
+ # Go backwards, building up new next_call invocations on plugins
144
+ next_call = plugins.reverse_each.reduce(next_call) do |next_call, plugin|
145
+ proc { |options| plugin.connect_client(options, next_call) }
146
+ end
147
+ # Do call
148
+ final_connection = next_call.call(options)
149
+
150
+ # steep:ignore:end
151
+ end
152
+ end
153
+ # Now create connection
154
+ base_connection = Connection.new(
155
+ target_host:,
156
+ api_key:,
157
+ tls:,
158
+ rpc_metadata:,
159
+ rpc_retry:,
160
+ identity:,
161
+ keep_alive:,
162
+ http_connect_proxy:,
163
+ runtime:,
164
+ lazy_connect:,
165
+ around_connect: # steep:ignore
166
+ )
167
+
168
+ # Create client
115
169
  Client.new(
116
- connection: Connection.new(
117
- target_host:,
118
- api_key:,
119
- tls:,
120
- rpc_metadata:,
121
- rpc_retry:,
122
- identity:,
123
- keep_alive:,
124
- http_connect_proxy:,
125
- runtime:,
126
- lazy_connect:
127
- ),
170
+ connection: final_connection || base_connection,
128
171
  namespace:,
129
172
  data_converter:,
173
+ plugins:,
130
174
  interceptors:,
131
175
  logger:,
132
176
  default_workflow_query_reject_condition:
133
177
  )
134
178
  end
135
179
 
180
+ # @!visibility private
181
+ def self._validate_plugins!(plugins)
182
+ plugins.each do |plugin|
183
+ raise ArgumentError, "#{plugin.class} does not implement Client::Plugin" unless plugin.is_a?(Plugin)
184
+
185
+ # Validate plugin has implemented expected methods
186
+ missing = Plugin.instance_methods(false).select { |m| plugin.method(m).owner == Plugin }
187
+ unless missing.empty?
188
+ raise ArgumentError, "#{plugin.class} missing the following client plugin method(s): #{missing.join(', ')}"
189
+ end
190
+ end
191
+ end
192
+
136
193
  # @return [Options] Frozen options for this client which has the same attributes as {initialize}.
137
194
  attr_reader :options
138
195
 
@@ -143,6 +200,9 @@ module Temporalio
143
200
  # @param connection [Connection] Existing connection to create a client from.
144
201
  # @param namespace [String] Namespace to use for client calls.
145
202
  # @param data_converter [Converters::DataConverter] Data converter to use for all data conversions to/from payloads.
203
+ # @param plugins [Array<Plugin>] Plugins to use for configuring clients. Any plugins that also include
204
+ # {Worker::Plugin} will automatically be applied to the worker and should not be configured explicitly on the
205
+ # worker. WARNING: Plugins are experimental.
146
206
  # @param interceptors [Array<Interceptor>] Set of interceptors that are chained together to allow intercepting of
147
207
  # client calls. The earlier interceptors wrap the later ones. Any interceptors that also implement worker
148
208
  # interceptor will be used as worker interceptors too so they should not be given separately when creating a
@@ -157,6 +217,7 @@ module Temporalio
157
217
  connection:,
158
218
  namespace:,
159
219
  data_converter: DataConverter.default,
220
+ plugins: [],
160
221
  interceptors: [],
161
222
  logger: Logger.new($stdout, level: Logger::WARN),
162
223
  default_workflow_query_reject_condition: nil
@@ -165,12 +226,20 @@ module Temporalio
165
226
  connection:,
166
227
  namespace:,
167
228
  data_converter:,
229
+ plugins:,
168
230
  interceptors:,
169
231
  logger:,
170
232
  default_workflow_query_reject_condition:
171
233
  ).freeze
234
+
235
+ # Apply plugins
236
+ Client._validate_plugins!(plugins)
237
+ @options = plugins.reduce(@options) { |options, plugin| plugin.configure_client(options) }
238
+
172
239
  # Initialize interceptors
173
- @impl = interceptors.reverse_each.reduce(Internal::Client::Implementation.new(self)) do |acc, int| # steep:ignore
240
+ @impl = @options.interceptors.reverse_each.reduce(
241
+ Internal::Client::Implementation.new(self)
242
+ ) do |acc, int| # steep:ignore
174
243
  int.intercept_client(acc)
175
244
  end
176
245
  end
@@ -229,7 +298,6 @@ module Temporalio
229
298
  # @param request_eager_start [Boolean] Potentially reduce the latency to start this workflow by encouraging the
230
299
  # server to start it on a local worker running with this same client. This is currently experimental.
231
300
  # @param versioning_override [VersioningOverride, nil] Override the version of the workflow.
232
- # This is currently experimental.
233
301
  # @param priority [Priority] Priority of the workflow. This is currently experimental.
234
302
  # @param arg_hints [Array<Object>, nil] Overrides converter hints for arguments if any. If unset/nil and the
235
303
  # workflow definition has arg hints, those are used by default.
@@ -323,7 +391,6 @@ module Temporalio
323
391
  # @param request_eager_start [Boolean] Potentially reduce the latency to start this workflow by encouraging the
324
392
  # server to start it on a local worker running with this same client. This is currently experimental.
325
393
  # @param versioning_override [VersioningOverride, nil] Override the version of the workflow.
326
- # This is currently experimental.
327
394
  # @param priority [Priority] Priority for the workflow. This is currently experimental.
328
395
  # @param arg_hints [Array<Object>, nil] Overrides converter hints for arguments if any. If unset/nil and the
329
396
  # workflow definition has arg hints, those are used by default.
@@ -40,8 +40,6 @@ module Temporalio
40
40
  end
41
41
 
42
42
  # Specifies when a workflow might move from a worker of one Build Id to another.
43
- #
44
- # WARNING: Experimental API.
45
43
  module VersioningBehavior
46
44
  # Unspecified versioning behavior. By default, workers opting into worker versioning will
47
45
  # be required to specify a behavior.
@@ -67,6 +67,11 @@ module Temporalio
67
67
  headers[@header_key] = carrier unless carrier.empty?
68
68
  end
69
69
 
70
+ # @!visibility private
71
+ def _propagator
72
+ @propagator
73
+ end
74
+
70
75
  # @!visibility private
71
76
  def _attach_context(headers)
72
77
  context = _context_from_headers(headers)
@@ -402,6 +407,22 @@ module Temporalio
402
407
  super
403
408
  end
404
409
 
410
+ # @!visibility private
411
+ def start_nexus_operation(input)
412
+ # Nexus headers are string-to-string maps (not payload-based like activity/workflow headers)
413
+ # so we inject the tracing context directly into the headers instead of nesting under a key
414
+ span = Workflow.completed_span("StartNexusOperation:#{input.service}/#{input.operation}", kind: :client)
415
+ Temporalio::Workflow::Unsafe.durable_scheduler_disabled do
416
+ if span
417
+ @root._propagator.inject(
418
+ input.headers,
419
+ context: ::OpenTelemetry::Trace.context_with_span(span)
420
+ )
421
+ end
422
+ end
423
+ super
424
+ end
425
+
405
426
  # @!visibility private
406
427
  def _apply_span_to_headers(headers, span)
407
428
  # See WorkflowInbound#_attach_context comments for why we have to disable scheduler even for these simple
@@ -84,6 +84,18 @@ module Temporalio
84
84
  started_event_id: error.started_event_id,
85
85
  retry_state: error.retry_state
86
86
  )
87
+ when Error::NexusOperationError
88
+ failure.nexus_operation_execution_failure_info = Api::Failure::V1::NexusOperationFailureInfo.new(
89
+ endpoint: error.endpoint,
90
+ service: error.service,
91
+ operation: error.operation,
92
+ operation_token: error.operation_token || ''
93
+ )
94
+ when Error::NexusHandlerError
95
+ failure.nexus_handler_failure_info = Api::Failure::V1::NexusHandlerFailureInfo.new(
96
+ type: error.error_type.to_s,
97
+ retry_behavior: error.retry_behavior
98
+ )
87
99
  else
88
100
  failure.application_failure_info = Api::Failure::V1::ApplicationFailureInfo.new(
89
101
  type: error.class.name.to_s.split('::').last
@@ -190,6 +202,24 @@ module Temporalio
190
202
  zero_means_nil: true
191
203
  )
192
204
  )
205
+ elsif failure.nexus_operation_execution_failure_info
206
+ token = failure.nexus_operation_execution_failure_info.operation_token
207
+ Error::NexusOperationError.new(
208
+ Internal::ProtoUtils.string_or(failure.message, 'Nexus operation error'),
209
+ endpoint: failure.nexus_operation_execution_failure_info.endpoint,
210
+ service: failure.nexus_operation_execution_failure_info.service,
211
+ operation: failure.nexus_operation_execution_failure_info.operation,
212
+ operation_token: token.empty? ? nil : token
213
+ )
214
+ elsif failure.nexus_handler_failure_info
215
+ Error::NexusHandlerError.new(
216
+ Internal::ProtoUtils.string_or(failure.message, 'Nexus handler error'),
217
+ error_type: failure.nexus_handler_failure_info.type,
218
+ retry_behavior: Internal::ProtoUtils.enum_to_int(
219
+ Api::Enums::V1::NexusHandlerErrorRetryBehavior,
220
+ failure.nexus_handler_failure_info.retry_behavior
221
+ )
222
+ )
193
223
  else
194
224
  Error::Failure.new(Internal::ProtoUtils.string_or(failure.message, 'Failure error'))
195
225
  end
@@ -22,7 +22,10 @@ module Temporalio
22
22
 
23
23
  # @type var value: Google::Protobuf::MessageExts
24
24
  Api::Common::V1::Payload.new(
25
- metadata: { 'encoding' => ENCODING, 'messageType' => value.class.descriptor.name },
25
+ metadata: {
26
+ 'encoding' => ENCODING,
27
+ 'messageType' => value.class.descriptor.name # steep:ignore NoMethod
28
+ },
26
29
  data: value.to_proto
27
30
  )
28
31
  end
@@ -21,7 +21,10 @@ module Temporalio
21
21
  return nil unless value.is_a?(Google::Protobuf::MessageExts)
22
22
 
23
23
  Api::Common::V1::Payload.new(
24
- metadata: { 'encoding' => ENCODING, 'messageType' => value.class.descriptor.name },
24
+ metadata: {
25
+ 'encoding' => ENCODING,
26
+ 'messageType' => value.class.descriptor.name # steep:ignore NoMethod
27
+ },
25
28
  data: value.to_json.b
26
29
  )
27
30
  end
@@ -4,9 +4,7 @@ require 'pathname'
4
4
  require 'temporalio/internal/bridge'
5
5
 
6
6
  module Temporalio
7
- # Environment and file-based configuration for Temporal clients
8
- #
9
- # WARNING: Experimental API.
7
+ # Environment and file-based configuration for Temporal clients.
10
8
  module EnvConfig
11
9
  # This module provides utilities to load Temporal client configuration from TOML files
12
10
  # and environment variables.
@@ -180,13 +178,7 @@ module Temporalio
180
178
  path, data = EnvConfig._source_to_path_and_data(config_source)
181
179
 
182
180
  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 || {}
181
+ profile, path, data, disable_file, disable_env, config_file_strict, override_env_vars
190
182
  )
191
183
 
192
184
  from_h(raw_profile)
@@ -272,10 +264,7 @@ module Temporalio
272
264
  path, data = EnvConfig._source_to_path_and_data(config_source)
273
265
 
274
266
  loaded_profiles = Internal::Bridge::EnvConfig.load_client_config(
275
- path,
276
- data,
277
- config_file_strict,
278
- override_env_vars || {}
267
+ path, data, config_file_strict, override_env_vars
279
268
  )
280
269
 
281
270
  from_h(loaded_profiles)
@@ -233,5 +233,71 @@ module Temporalio
233
233
  @retry_state = retry_state
234
234
  end
235
235
  end
236
+
237
+ # Error raised on Nexus operation failure.
238
+ #
239
+ # WARNING: Nexus support is experimental.
240
+ class NexusOperationError < Failure
241
+ # @return [String] Nexus endpoint.
242
+ attr_reader :endpoint
243
+ # @return [String] Nexus service.
244
+ attr_reader :service
245
+ # @return [String] Nexus operation.
246
+ attr_reader :operation
247
+ # @return [String, nil] Operation token for async operations.
248
+ attr_reader :operation_token
249
+
250
+ # @!visibility private
251
+ def initialize(
252
+ message,
253
+ endpoint:,
254
+ service:,
255
+ operation:,
256
+ operation_token:
257
+ )
258
+ super(message)
259
+ @endpoint = endpoint
260
+ @service = service
261
+ @operation = operation
262
+ @operation_token = operation_token
263
+ end
264
+ end
265
+
266
+ # Error raised from a Nexus handler.
267
+ #
268
+ # WARNING: Nexus support is experimental.
269
+ class NexusHandlerError < Failure
270
+ # @return [Symbol] Error type from the handler.
271
+ attr_reader :error_type
272
+
273
+ # @return [RetryBehavior] Retry behavior for the error.
274
+ attr_reader :retry_behavior
275
+
276
+ # @!visibility private
277
+ def initialize(
278
+ message,
279
+ error_type:,
280
+ retry_behavior:
281
+ )
282
+ super(message)
283
+ @error_type = error_type.to_sym
284
+ @retry_behavior = retry_behavior
285
+ end
286
+
287
+ # Nexus handler error retry behavior.
288
+ module RetryBehavior
289
+ # Unspecified retry behavior.
290
+ UNSPECIFIED =
291
+ Api::Enums::V1::NexusHandlerErrorRetryBehavior::NEXUS_HANDLER_ERROR_RETRY_BEHAVIOR_UNSPECIFIED
292
+
293
+ # Retryable error.
294
+ RETRYABLE =
295
+ Api::Enums::V1::NexusHandlerErrorRetryBehavior::NEXUS_HANDLER_ERROR_RETRY_BEHAVIOR_RETRYABLE
296
+
297
+ # Non-retryable error.
298
+ NON_RETRYABLE =
299
+ Api::Enums::V1::NexusHandlerErrorRetryBehavior::NEXUS_HANDLER_ERROR_RETRY_BEHAVIOR_NON_RETRYABLE
300
+ end
301
+ end
236
302
  end
237
303
  end