temporalio 1.2.0-aarch64-linux → 1.4.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 (85) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/Gemfile +0 -1
  4. data/Rakefile +12 -13
  5. data/lib/temporalio/api/activity/v1/message.rb +5 -1
  6. data/lib/temporalio/api/callback/v1/message.rb +26 -0
  7. data/lib/temporalio/api/cloud/account/v1/message.rb +4 -1
  8. data/lib/temporalio/api/cloud/auditlog/v1/message.rb +27 -0
  9. data/lib/temporalio/api/cloud/billing/v1/message.rb +30 -0
  10. data/lib/temporalio/api/cloud/cloudservice/v1/request_response.rb +23 -1
  11. data/lib/temporalio/api/cloud/cloudservice/v1/service.rb +2 -1
  12. data/lib/temporalio/api/cloud/namespace/v1/message.rb +16 -2
  13. data/lib/temporalio/api/command/v1/message.rb +1 -1
  14. data/lib/temporalio/api/common/v1/message.rb +5 -1
  15. data/lib/temporalio/api/compute/v1/config.rb +30 -0
  16. data/lib/temporalio/api/compute/v1/provider.rb +23 -0
  17. data/lib/temporalio/api/compute/v1/scaler.rb +23 -0
  18. data/lib/temporalio/api/deployment/v1/message.rb +3 -1
  19. data/lib/temporalio/api/enums/v1/deployment.rb +1 -1
  20. data/lib/temporalio/api/enums/v1/event_type.rb +1 -1
  21. data/lib/temporalio/api/enums/v1/nexus.rb +5 -1
  22. data/lib/temporalio/api/enums/v1/task_queue.rb +1 -1
  23. data/lib/temporalio/api/enums/v1/workflow.rb +1 -1
  24. data/lib/temporalio/api/errordetails/v1/message.rb +2 -1
  25. data/lib/temporalio/api/failure/v1/message.rb +1 -1
  26. data/lib/temporalio/api/history/v1/message.rb +3 -1
  27. data/lib/temporalio/api/namespace/v1/message.rb +1 -1
  28. data/lib/temporalio/api/nexus/v1/message.rb +9 -1
  29. data/lib/temporalio/api/nexusservices/workerservice/v1/request_response.rb +26 -0
  30. data/lib/temporalio/api/payload_visitor.rb +174 -4
  31. data/lib/temporalio/api/protoc_gen_openapiv2/options/annotations.rb +23 -0
  32. data/lib/temporalio/api/protoc_gen_openapiv2/options/openapiv2.rb +48 -0
  33. data/lib/temporalio/api/protometa/v1/annotations.rb +23 -0
  34. data/lib/temporalio/api/sdk/v1/external_storage.rb +21 -0
  35. data/lib/temporalio/api/taskqueue/v1/message.rb +2 -1
  36. data/lib/temporalio/api/worker/v1/message.rb +7 -1
  37. data/lib/temporalio/api/workflow/v1/message.rb +2 -1
  38. data/lib/temporalio/api/workflowservice/v1/request_response.rb +31 -1
  39. data/lib/temporalio/api/workflowservice/v1/service.rb +2 -1
  40. data/lib/temporalio/client/connection/cloud_service.rb +150 -0
  41. data/lib/temporalio/client/connection/workflow_service.rb +195 -0
  42. data/lib/temporalio/client.rb +1 -3
  43. data/lib/temporalio/common_enums.rb +29 -2
  44. data/lib/temporalio/contrib/open_telemetry.rb +59 -13
  45. data/lib/temporalio/converters/failure_converter.rb +30 -0
  46. data/lib/temporalio/converters/payload_converter/composite.rb +4 -2
  47. data/lib/temporalio/env_config.rb +1 -3
  48. data/lib/temporalio/error/failure.rb +66 -0
  49. data/lib/temporalio/internal/bridge/3.3/temporalio_bridge.so +0 -0
  50. data/lib/temporalio/internal/bridge/3.4/temporalio_bridge.so +0 -0
  51. data/lib/temporalio/internal/bridge/4.0/temporalio_bridge.so +0 -0
  52. data/lib/temporalio/internal/bridge/api/activity_task/activity_task.rb +1 -1
  53. data/lib/temporalio/internal/bridge/api/nexus/nexus.rb +1 -1
  54. data/lib/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rb +1 -1
  55. data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +1 -1
  56. data/lib/temporalio/internal/bridge/client.rb +5 -10
  57. data/lib/temporalio/internal/bridge/runtime.rb +6 -12
  58. data/lib/temporalio/internal/bridge/testing.rb +2 -4
  59. data/lib/temporalio/internal/bridge/worker.rb +8 -16
  60. data/lib/temporalio/internal/bridge.rb +2 -2
  61. data/lib/temporalio/internal/client/implementation.rb +1 -1
  62. data/lib/temporalio/internal/proto_utils.rb +7 -5
  63. data/lib/temporalio/internal/worker/workflow_instance/context.rb +16 -1
  64. data/lib/temporalio/internal/worker/workflow_instance/nexus_client.rb +45 -0
  65. data/lib/temporalio/internal/worker/workflow_instance/nexus_operation_handle.rb +51 -0
  66. data/lib/temporalio/internal/worker/workflow_instance/outbound_implementation.rb +71 -1
  67. data/lib/temporalio/internal/worker/workflow_instance.rb +20 -2
  68. data/lib/temporalio/search_attributes.rb +12 -2
  69. data/lib/temporalio/testing/workflow_environment.rb +40 -0
  70. data/lib/temporalio/version.rb +1 -1
  71. data/lib/temporalio/versioning_override.rb +0 -2
  72. data/lib/temporalio/worker/deployment_options.rb +0 -2
  73. data/lib/temporalio/worker/interceptor.rb +29 -0
  74. data/lib/temporalio/worker/workflow_executor/thread_pool.rb +1 -1
  75. data/lib/temporalio/worker/workflow_replayer.rb +1 -3
  76. data/lib/temporalio/worker.rb +9 -8
  77. data/lib/temporalio/worker_deployment_version.rb +0 -2
  78. data/lib/temporalio/workflow/definition.rb +0 -3
  79. data/lib/temporalio/workflow/info.rb +3 -6
  80. data/lib/temporalio/workflow/nexus_client.rb +93 -0
  81. data/lib/temporalio/workflow/nexus_operation_cancellation_type.rb +21 -0
  82. data/lib/temporalio/workflow/nexus_operation_handle.rb +37 -0
  83. data/lib/temporalio/workflow/update_info.rb +1 -2
  84. data/lib/temporalio/workflow.rb +34 -2
  85. metadata +18 -2
@@ -22,8 +22,7 @@ module Temporalio
22
22
  :log_format,
23
23
  :log_level,
24
24
  :extra_args,
25
- :download_ttl, # Optional
26
- keyword_init: true
25
+ :download_ttl # Optional
27
26
  )
28
27
 
29
28
  StartTestServerOptions = Struct.new(
@@ -34,8 +33,7 @@ module Temporalio
34
33
  :download_dest_dir, # Optional
35
34
  :port, # Optional
36
35
  :extra_args,
37
- :download_ttl, # Optional
38
- keyword_init: true
36
+ :download_ttl # Optional
39
37
  )
40
38
 
41
39
  def self.start_dev_server(runtime, options)
@@ -28,22 +28,19 @@ module Temporalio
28
28
  :nondeterminism_as_workflow_fail,
29
29
  :nondeterminism_as_workflow_fail_for_types,
30
30
  :deployment_options,
31
- :plugins,
32
- keyword_init: true
31
+ :plugins
33
32
  )
34
33
 
35
34
  TunerOptions = Struct.new(
36
35
  :workflow_slot_supplier,
37
36
  :activity_slot_supplier,
38
- :local_activity_slot_supplier,
39
- keyword_init: true
37
+ :local_activity_slot_supplier
40
38
  )
41
39
 
42
40
  TunerSlotSupplierOptions = Struct.new(
43
41
  :fixed_size,
44
42
  :resource_based,
45
- :custom,
46
- keyword_init: true
43
+ :custom
47
44
  )
48
45
 
49
46
  TunerResourceBasedSlotSupplierOptions = Struct.new(
@@ -51,33 +48,28 @@ module Temporalio
51
48
  :target_cpu_usage,
52
49
  :min_slots,
53
50
  :max_slots,
54
- :ramp_throttle,
55
- keyword_init: true
51
+ :ramp_throttle
56
52
  )
57
53
 
58
54
  WorkerDeploymentVersion = Struct.new(
59
55
  :deployment_name,
60
- :build_id,
61
- keyword_init: true
56
+ :build_id
62
57
  )
63
58
 
64
59
  DeploymentOptions = Struct.new(
65
60
  :version,
66
61
  :use_worker_versioning,
67
- :default_versioning_behavior,
68
- keyword_init: true
62
+ :default_versioning_behavior
69
63
  )
70
64
 
71
65
  PollerBehaviorSimpleMaximum = Struct.new(
72
- :simple_maximum,
73
- keyword_init: true
66
+ :simple_maximum
74
67
  )
75
68
 
76
69
  PollerBehaviorAutoscaling = Struct.new(
77
70
  :minimum,
78
71
  :maximum,
79
- :initial,
80
- keyword_init: true
72
+ :initial
81
73
  )
82
74
 
83
75
  def self.finalize_shutdown_all(workers)
@@ -25,11 +25,11 @@ module Temporalio
25
25
  'see https://github.com/temporalio/sdk-ruby/issues/162'
26
26
  end
27
27
 
28
- def self.fibers_supported # rubocop:disable Naming/PredicateMethod
28
+ def self.fibers_supported
29
29
  # We do not allow fibers on < 3.3 due to a bug we still need to dig
30
30
  # into: https://github.com/temporalio/sdk-ruby/issues/162
31
31
  major, minor = RUBY_VERSION.split('.').take(2).map(&:to_i)
32
- !major.nil? && major >= 3 && !minor.nil? && minor >= 3
32
+ !major.nil? && !minor.nil? && (major > 3 || (major == 3 && minor >= 3))
33
33
  end
34
34
  end
35
35
  end
@@ -228,7 +228,7 @@ module Temporalio
228
228
  if details
229
229
  e = Error::WorkflowAlreadyStartedError.new(
230
230
  workflow_id: start_options.id,
231
- workflow_type: start_req.workflow_type,
231
+ workflow_type: start_req.workflow_type.name,
232
232
  run_id: details.run_id
233
233
  )
234
234
  end
@@ -53,7 +53,9 @@ module Temporalio
53
53
  def self.memo_from_proto(memo, converter)
54
54
  return nil if memo.nil? || memo.fields.size.zero? # rubocop:disable Style/ZeroLengthPredicate -- Google Maps don't have empty
55
55
 
56
- memo.fields.each_with_object({}) { |(key, val), h| h[key] = converter.from_payload(val) } # rubocop:disable Style/HashTransformValues
56
+ h = {}
57
+ memo.fields.each { |key, val| h[key] = converter.from_payload(val) }
58
+ h
57
59
  end
58
60
 
59
61
  def self.headers_to_proto(headers, converter)
@@ -75,10 +77,10 @@ module Temporalio
75
77
  def self.headers_from_proto_map(headers, converter)
76
78
  return nil if headers.nil? || headers.size.zero? # rubocop:disable Style/ZeroLengthPredicate -- Google Maps don't have empty
77
79
 
78
- headers.each_with_object({}) do |(key, val), h| # rubocop:disable Style/HashTransformValues
79
- # @type var h: Hash[String, Object?]
80
- h[key] = converter.from_payload(val)
81
- end
80
+ # @type var h: Hash[String, Object?]
81
+ h = {}
82
+ headers.each { |key, val| h[key] = converter.from_payload(val) }
83
+ h
82
84
  end
83
85
 
84
86
  def self.string_or(str, default = nil)
@@ -6,6 +6,7 @@ require 'temporalio/internal/bridge/api'
6
6
  require 'temporalio/internal/proto_utils'
7
7
  require 'temporalio/internal/worker/workflow_instance'
8
8
  require 'temporalio/internal/worker/workflow_instance/external_workflow_handle'
9
+ require 'temporalio/internal/worker/workflow_instance/nexus_client'
9
10
  require 'temporalio/worker/interceptor'
10
11
  require 'temporalio/workflow'
11
12
 
@@ -32,6 +33,18 @@ module Temporalio
32
33
  @instance.continue_as_new_suggested
33
34
  end
34
35
 
36
+ def create_nexus_client(endpoint:, service:)
37
+ NexusClient.new(endpoint:, service:, outbound: @outbound)
38
+ end
39
+
40
+ def suggest_continue_as_new_reasons
41
+ @instance.suggest_continue_as_new_reasons
42
+ end
43
+
44
+ def target_worker_deployment_version_changed?
45
+ @instance.target_worker_deployment_version_changed
46
+ end
47
+
35
48
  def current_details
36
49
  @instance.current_details || ''
37
50
  end
@@ -374,7 +387,9 @@ module Temporalio
374
387
  @instance.add_command(
375
388
  Bridge::Api::WorkflowCommands::WorkflowCommand.new(
376
389
  upsert_workflow_search_attributes: Bridge::Api::WorkflowCommands::UpsertWorkflowSearchAttributes.new(
377
- search_attributes: updates.to_h(&:_to_proto_pair)
390
+ search_attributes: Api::Common::V1::SearchAttributes.new(
391
+ indexed_fields: updates.to_h(&:_to_proto_pair)
392
+ )
378
393
  )
379
394
  )
380
395
  )
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'temporalio/workflow'
4
+ require 'temporalio/workflow/nexus_client'
5
+
6
+ module Temporalio
7
+ module Internal
8
+ module Worker
9
+ class WorkflowInstance
10
+ # Implementation of the Nexus client.
11
+ class NexusClient < Workflow::NexusClient
12
+ attr_reader :endpoint, :service
13
+
14
+ def initialize(endpoint:, service:, outbound:) # rubocop:disable Lint/MissingSuper
15
+ @endpoint = endpoint.to_s
16
+ @service = service.to_s
17
+ @outbound = outbound
18
+ end
19
+
20
+ def start_operation(operation, arg, schedule_to_close_timeout: nil, schedule_to_start_timeout: nil,
21
+ start_to_close_timeout: nil, cancellation_type: nil, summary: nil,
22
+ cancellation: Workflow.cancellation, arg_hint: nil, result_hint: nil)
23
+ @outbound.start_nexus_operation(
24
+ Temporalio::Worker::Interceptor::Workflow::StartNexusOperationInput.new(
25
+ endpoint: @endpoint,
26
+ service: @service,
27
+ operation: operation.to_s,
28
+ arg:,
29
+ schedule_to_close_timeout:,
30
+ schedule_to_start_timeout:,
31
+ start_to_close_timeout:,
32
+ cancellation_type:,
33
+ summary:,
34
+ cancellation:,
35
+ arg_hint:,
36
+ result_hint:,
37
+ headers: {}
38
+ )
39
+ )
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'temporalio/cancellation'
4
+ require 'temporalio/workflow'
5
+ require 'temporalio/workflow/nexus_operation_handle'
6
+
7
+ module Temporalio
8
+ module Internal
9
+ module Worker
10
+ class WorkflowInstance
11
+ # Implementation of the Nexus operation handle.
12
+ class NexusOperationHandle < Workflow::NexusOperationHandle
13
+ attr_reader :operation_token, :result_hint
14
+
15
+ def initialize(operation_token:, instance:, cancellation:, cancel_callback_key:, # rubocop:disable Lint/MissingSuper
16
+ result_hint:)
17
+ @operation_token = operation_token
18
+ @instance = instance
19
+ @cancellation = cancellation
20
+ @cancel_callback_key = cancel_callback_key
21
+ @result_hint = result_hint
22
+ @resolution = nil
23
+ end
24
+
25
+ def result(result_hint: nil)
26
+ # Use detached cancellation like child workflow to avoid interrupting result wait
27
+ Workflow.wait_condition(cancellation: Cancellation.new) { @resolution }
28
+
29
+ case @resolution.status
30
+ when :completed
31
+ @instance.payload_converter.from_payload(@resolution.completed, hint: result_hint || @result_hint)
32
+ when :failed
33
+ raise @instance.failure_converter.from_failure(@resolution.failed, @instance.payload_converter)
34
+ when :cancelled
35
+ raise @instance.failure_converter.from_failure(@resolution.cancelled, @instance.payload_converter)
36
+ when :timed_out
37
+ raise @instance.failure_converter.from_failure(@resolution.timed_out, @instance.payload_converter)
38
+ else
39
+ raise "Unrecognized Nexus operation result status: #{@resolution.status}"
40
+ end
41
+ end
42
+
43
+ def _resolve(resolution)
44
+ @cancellation.remove_cancel_callback(@cancel_callback_key)
45
+ @resolution = resolution
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -6,6 +6,7 @@ require 'temporalio/error'
6
6
  require 'temporalio/internal/bridge/api'
7
7
  require 'temporalio/internal/proto_utils'
8
8
  require 'temporalio/internal/worker/workflow_instance'
9
+ require 'temporalio/internal/worker/workflow_instance/nexus_operation_handle'
9
10
  require 'temporalio/worker/interceptor'
10
11
  require 'temporalio/workflow'
11
12
  require 'temporalio/workflow/child_workflow_handle'
@@ -22,6 +23,7 @@ module Temporalio
22
23
  @activity_counter = 0
23
24
  @timer_counter = 0
24
25
  @child_counter = 0
26
+ @nexus_operation_counter = 0
25
27
  @external_signal_counter = 0
26
28
  @external_cancel_counter = 0
27
29
  end
@@ -363,7 +365,7 @@ module Temporalio
363
365
  cron_schedule: input.cron_schedule,
364
366
  headers: ProtoUtils.headers_to_proto_hash(input.headers, @instance.payload_converter),
365
367
  memo: ProtoUtils.memo_to_proto_hash(input.memo, @instance.payload_converter),
366
- search_attributes: input.search_attributes&._to_proto_hash,
368
+ search_attributes: input.search_attributes&._to_proto,
367
369
  cancellation_type: input.cancellation_type,
368
370
  priority: input.priority._to_proto
369
371
  ),
@@ -429,6 +431,74 @@ module Temporalio
429
431
  raise "Unknown resolution status: #{resolution.status}"
430
432
  end
431
433
  end
434
+
435
+ def start_nexus_operation(input)
436
+ raise Error::CanceledError, 'Nexus operation canceled before scheduled' if input.cancellation.canceled?
437
+
438
+ # Add the command
439
+ seq = (@nexus_operation_counter += 1)
440
+ @instance.add_command(
441
+ Bridge::Api::WorkflowCommands::WorkflowCommand.new(
442
+ schedule_nexus_operation: Bridge::Api::WorkflowCommands::ScheduleNexusOperation.new(
443
+ seq:,
444
+ endpoint: input.endpoint,
445
+ service: input.service,
446
+ operation: input.operation,
447
+ input: @instance.payload_converter.to_payload(input.arg, hint: input.arg_hint),
448
+ schedule_to_close_timeout: ProtoUtils.seconds_to_duration(input.schedule_to_close_timeout),
449
+ schedule_to_start_timeout: ProtoUtils.seconds_to_duration(input.schedule_to_start_timeout),
450
+ start_to_close_timeout: ProtoUtils.seconds_to_duration(input.start_to_close_timeout),
451
+ nexus_header: input.headers,
452
+ cancellation_type: input.cancellation_type
453
+ ),
454
+ user_metadata: ProtoUtils.to_user_metadata(input.summary, nil, @instance.payload_converter)
455
+ )
456
+ )
457
+
458
+ # Set as pending start
459
+ @instance.pending_nexus_operation_starts[seq] = Fiber.current
460
+
461
+ # Register cancel callback
462
+ cancel_callback_key = input.cancellation.add_cancel_callback do
463
+ # Send cancel if in start or pending
464
+ if @instance.pending_nexus_operation_starts.include?(seq) ||
465
+ @instance.pending_nexus_operations.include?(seq)
466
+ @instance.add_command(
467
+ Bridge::Api::WorkflowCommands::WorkflowCommand.new(
468
+ request_cancel_nexus_operation: Bridge::Api::WorkflowCommands::RequestCancelNexusOperation.new(
469
+ seq:
470
+ )
471
+ )
472
+ )
473
+ end
474
+ end
475
+
476
+ # Wait for start resolution
477
+ resolution = begin
478
+ Fiber.yield
479
+ ensure
480
+ # Remove pending start
481
+ @instance.pending_nexus_operation_starts.delete(seq)
482
+ end
483
+
484
+ # Handle start failure
485
+ if resolution.failed
486
+ input.cancellation.remove_cancel_callback(cancel_callback_key)
487
+ raise @instance.failure_converter.from_failure(resolution.failed, @instance.payload_converter)
488
+ end
489
+
490
+ # Create handle and add to pending operations (result will come via resolve_nexus_operation)
491
+ handle = NexusOperationHandle.new(
492
+ operation_token: resolution.operation_token,
493
+ instance: @instance,
494
+ cancellation: input.cancellation,
495
+ cancel_callback_key:,
496
+ result_hint: input.result_hint
497
+ )
498
+ @instance.pending_nexus_operations[seq] = handle
499
+
500
+ handle
501
+ end
432
502
  end
433
503
  end
434
504
  end
@@ -54,8 +54,11 @@ module Temporalio
54
54
 
55
55
  attr_reader :context, :logger, :info, :scheduler, :disable_eager_activity_execution, :pending_activities,
56
56
  :pending_timers, :pending_child_workflow_starts, :pending_child_workflows,
57
+ :pending_nexus_operation_starts, :pending_nexus_operations,
57
58
  :pending_external_signals, :pending_external_cancels, :in_progress_handlers, :payload_converter,
58
- :failure_converter, :cancellation, :continue_as_new_suggested, :current_deployment_version,
59
+ :failure_converter, :cancellation, :continue_as_new_suggested,
60
+ :suggest_continue_as_new_reasons, :target_worker_deployment_version_changed,
61
+ :current_deployment_version,
59
62
  :current_history_length, :current_history_size, :replaying, :random,
60
63
  :signal_handlers, :query_handlers, :update_handlers, :context_frozen, :assert_valid_local_activity,
61
64
  :in_query_or_validator
@@ -79,6 +82,8 @@ module Temporalio
79
82
  @pending_timers = {} # Keyed by sequence, value is fiber to resume with proto result
80
83
  @pending_child_workflow_starts = {} # Keyed by sequence, value is fiber to resume with proto result
81
84
  @pending_child_workflows = {} # Keyed by sequence, value is ChildWorkflowHandle to resolve with proto result
85
+ @pending_nexus_operation_starts = {} # Keyed by sequence, value is fiber to resume with proto result
86
+ @pending_nexus_operations = {} # Keyed by sequence, value is NexusOperationHandle to resolve with proto result
82
87
  @pending_external_signals = {} # Keyed by sequence, value is fiber to resume with proto result
83
88
  @pending_external_cancels = {} # Keyed by sequence, value is fiber to resume with proto result
84
89
  @buffered_signals = {} # Keyed by signal name, value is array of signal jobs
@@ -89,6 +94,8 @@ module Temporalio
89
94
  @interceptors = details.interceptors
90
95
  @cancellation, @cancellation_proc = Cancellation.new
91
96
  @continue_as_new_suggested = false
97
+ @suggest_continue_as_new_reasons = []
98
+ @target_worker_deployment_version_changed = false
92
99
  @current_history_length = 0
93
100
  @current_history_size = 0
94
101
  @replaying = false
@@ -173,6 +180,8 @@ module Temporalio
173
180
  @commands = []
174
181
  @current_activation_error = nil
175
182
  @continue_as_new_suggested = activation.continue_as_new_suggested
183
+ @suggest_continue_as_new_reasons = activation.suggest_continue_as_new_reasons.map(&:to_i)
184
+ @target_worker_deployment_version_changed = activation.target_worker_deployment_version_changed
176
185
  @current_deployment_version = WorkerDeploymentVersion._from_bridge(
177
186
  activation.deployment_version_for_current_task
178
187
  )
@@ -369,6 +378,14 @@ module Temporalio
369
378
  pending_child_workflows[job.resolve_child_workflow_execution.seq]&._resolve(
370
379
  job.resolve_child_workflow_execution.result
371
380
  )
381
+ when :resolve_nexus_operation_start
382
+ pending_nexus_operation_starts[job.resolve_nexus_operation_start.seq]&.resume(
383
+ job.resolve_nexus_operation_start
384
+ )
385
+ when :resolve_nexus_operation
386
+ pending_nexus_operations[job.resolve_nexus_operation.seq]&._resolve(
387
+ job.resolve_nexus_operation.result
388
+ )
372
389
  when :resolve_signal_external_workflow
373
390
  pending_external_signals[job.resolve_signal_external_workflow.seq]&.resume(
374
391
  job.resolve_signal_external_workflow
@@ -628,7 +645,8 @@ module Temporalio
628
645
  memo: ProtoUtils.memo_to_proto_hash(err.memo, payload_converter),
629
646
  headers: ProtoUtils.headers_to_proto_hash(err.headers, payload_converter),
630
647
  search_attributes: err.search_attributes&._to_proto,
631
- retry_policy: err.retry_policy&._to_proto
648
+ retry_policy: err.retry_policy&._to_proto,
649
+ initial_versioning_behavior: err.initial_versioning_behavior || 0
632
650
  )
633
651
  )
634
652
  )
@@ -58,7 +58,7 @@ module Temporalio
58
58
  when IndexedValueType::TIME
59
59
  raise TypeError, 'Value of TIME key must be a Time' unless value.is_a?(Time)
60
60
  when IndexedValueType::KEYWORD_LIST
61
- unless value.is_a?(Array) && value.all? { |v| v.is_a?(String) }
61
+ unless value.is_a?(Array) && value.all?(String)
62
62
  raise TypeError, 'Value of KEYWORD_LIST key must be an Array of String'
63
63
  end
64
64
  else
@@ -350,7 +350,17 @@ module Temporalio
350
350
  }.freeze
351
351
 
352
352
  # @!visibility private
353
- PROTO_VALUES = PROTO_NAMES.invert.freeze
353
+ # The type metadata is usually in PascalCase (e.g. "KeywordList") but in
354
+ # rare cases may be in SCREAMING_SNAKE_CASE (e.g. "INDEXED_VALUE_TYPE_KEYWORD_LIST").
355
+ PROTO_VALUES = PROTO_NAMES.invert.merge(
356
+ 'INDEXED_VALUE_TYPE_TEXT' => TEXT,
357
+ 'INDEXED_VALUE_TYPE_KEYWORD' => KEYWORD,
358
+ 'INDEXED_VALUE_TYPE_INT' => INTEGER,
359
+ 'INDEXED_VALUE_TYPE_DOUBLE' => FLOAT,
360
+ 'INDEXED_VALUE_TYPE_BOOL' => BOOLEAN,
361
+ 'INDEXED_VALUE_TYPE_DATETIME' => TIME,
362
+ 'INDEXED_VALUE_TYPE_KEYWORD_LIST' => KEYWORD_LIST
363
+ ).freeze
354
364
  end
355
365
  end
356
366
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'delegate'
4
4
  require 'temporalio/api'
5
+ require 'temporalio/api/operatorservice/v1/request_response'
5
6
  require 'temporalio/api/testservice/v1/request_response'
6
7
  require 'temporalio/client'
7
8
  require 'temporalio/client/connection/test_service'
@@ -264,6 +265,45 @@ module Temporalio
264
265
  Time.now
265
266
  end
266
267
 
268
+ # Create Nexus endpoint on this test environment.
269
+ #
270
+ # WARNING: Nexus support is experimental.
271
+ #
272
+ # @param name [String] Endpoint name.
273
+ # @param task_queue [String] Task queue for the endpoint.
274
+ # @return [Temporalio::Api::Nexus::V1::Endpoint] Created endpoint.
275
+ def create_nexus_endpoint(name:, task_queue:)
276
+ resp = client.connection.operator_service.create_nexus_endpoint(
277
+ Temporalio::Api::OperatorService::V1::CreateNexusEndpointRequest.new(
278
+ spec: Temporalio::Api::Nexus::V1::EndpointSpec.new(
279
+ name:,
280
+ target: Temporalio::Api::Nexus::V1::EndpointTarget.new(
281
+ worker: Temporalio::Api::Nexus::V1::EndpointTarget::Worker.new(
282
+ namespace: client.namespace,
283
+ task_queue:
284
+ )
285
+ )
286
+ )
287
+ )
288
+ )
289
+ resp.endpoint
290
+ end
291
+
292
+ # Delete Nexus endpoint on this test environment.
293
+ #
294
+ # WARNING: Nexus support is experimental.
295
+ #
296
+ # @param endpoint [Temporalio::Api::Nexus::V1::Endpoint] Endpoint to delete.
297
+ def delete_nexus_endpoint(endpoint)
298
+ client.connection.operator_service.delete_nexus_endpoint(
299
+ Temporalio::Api::OperatorService::V1::DeleteNexusEndpointRequest.new(
300
+ id: endpoint.id,
301
+ version: endpoint.version
302
+ )
303
+ )
304
+ nil
305
+ end
306
+
267
307
  # Run a block with automatic time skipping disabled. This just runs the block for environments that don't support
268
308
  # time skipping.
269
309
  #
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Temporalio
4
- VERSION = '1.2.0'
4
+ VERSION = '1.4.0'
5
5
  end
@@ -5,8 +5,6 @@ require 'temporalio/worker_deployment_version'
5
5
  module Temporalio
6
6
  # Base class for version overrides that can be provided in start workflow options.
7
7
  # Used to control the versioning behavior of workflows started with this override.
8
- #
9
- # WARNING: Experimental API.
10
8
  class VersioningOverride
11
9
  # @!visibility private
12
10
  def _to_proto
@@ -13,8 +13,6 @@ module Temporalio
13
13
 
14
14
  # Options for configuring the Worker Versioning feature.
15
15
  #
16
- # WARNING: Deployment-based versioning is experimental and APIs may change.
17
- #
18
16
  # @!attribute version
19
17
  # @return [WorkerDeploymentVersion] The worker deployment version.
20
18
  # @!attribute use_worker_versioning
@@ -300,6 +300,25 @@ module Temporalio
300
300
  :headers
301
301
  )
302
302
 
303
+ # Input for {Outbound.start_nexus_operation}.
304
+ #
305
+ # WARNING: Nexus support is experimental.
306
+ StartNexusOperationInput = Data.define(
307
+ :endpoint,
308
+ :service,
309
+ :operation,
310
+ :arg,
311
+ :schedule_to_close_timeout,
312
+ :schedule_to_start_timeout,
313
+ :start_to_close_timeout,
314
+ :cancellation_type,
315
+ :summary,
316
+ :cancellation,
317
+ :arg_hint,
318
+ :result_hint,
319
+ :headers
320
+ )
321
+
303
322
  # Outbound interceptor for intercepting outbound workflow calls. This should be extended by users needing to
304
323
  # intercept workflow calls.
305
324
  class Outbound
@@ -371,6 +390,16 @@ module Temporalio
371
390
  def start_child_workflow(input)
372
391
  @next_interceptor.start_child_workflow(input)
373
392
  end
393
+
394
+ # Start Nexus operation.
395
+ #
396
+ # WARNING: Nexus support is experimental.
397
+ #
398
+ # @param input [StartNexusOperationInput] Input.
399
+ # @return [Workflow::NexusOperationHandle] Nexus operation handle.
400
+ def start_nexus_operation(input)
401
+ @next_interceptor.start_nexus_operation(input)
402
+ end
374
403
  end
375
404
  end
376
405
  end
@@ -49,7 +49,7 @@ module Temporalio
49
49
  # If not found, get a new one either by creating if not enough or find the one with the fewest.
50
50
  new_worker = if @workers.size < @max_threads
51
51
  created_worker = Worker.new(self)
52
- @workers << Worker.new(self)
52
+ @workers << created_worker
53
53
  created_worker
54
54
  else
55
55
  @workers.min_by(&:workflow_count)
@@ -258,9 +258,7 @@ module Temporalio
258
258
  logger: options.logger,
259
259
  data_converter: options.data_converter,
260
260
  metric_meter: options.runtime.metric_meter,
261
- workflow_interceptors: options.interceptors.select do |i|
262
- i.is_a?(Interceptor::Workflow)
263
- end,
261
+ workflow_interceptors: options.interceptors.grep(Interceptor::Workflow),
264
262
  disable_eager_activity_execution: false,
265
263
  illegal_workflow_calls: options.illegal_workflow_calls,
266
264
  workflow_failure_exception_types: options.workflow_failure_exception_types,
@@ -163,7 +163,7 @@ module Temporalio
163
163
  )
164
164
  # Confirm there is at least one and they are all workers
165
165
  raise ArgumentError, 'At least one worker required' if workers.empty?
166
- raise ArgumentError, 'Not all parameters are workers' unless workers.all? { |w| w.is_a?(Worker) }
166
+ raise ArgumentError, 'Not all parameters are workers' unless workers.all?(Worker)
167
167
 
168
168
  Internal::Bridge.assert_fiber_compatibility!
169
169
 
@@ -425,7 +425,6 @@ module Temporalio
425
425
  # scheduler will fail. Instead of setting this to true, users are encouraged to use {Workflow::Unsafe.io_enabled}
426
426
  # with a block for narrower enabling of IO.
427
427
  # @param deployment_options [DeploymentOptions, nil] Deployment options for the worker.
428
- # WARNING: This is an experimental feature and may change in the future.
429
428
  # @param workflow_task_poller_behavior [PollerBehavior] Specify the behavior of workflow task
430
429
  # polling. Defaults to a 5-poller maximum.
431
430
  # @param activity_task_poller_behavior [PollerBehavior] Specify the behavior of activity task
@@ -515,6 +514,12 @@ module Temporalio
515
514
  raise ArgumentError, 'Must have at least one activity or workflow'
516
515
  end
517
516
 
517
+ if !@options.deployment_options.use_worker_versioning &&
518
+ @options.deployment_options.default_versioning_behavior != VersioningBehavior::UNSPECIFIED
519
+ raise ArgumentError,
520
+ 'default_versioning_behavior must be UNSPECIFIED when use_worker_versioning is false'
521
+ end
522
+
518
523
  should_enforce_versioning_behavior =
519
524
  @options.deployment_options.use_worker_versioning &&
520
525
  @options.deployment_options.default_versioning_behavior == VersioningBehavior::UNSPECIFIED
@@ -559,12 +564,8 @@ module Temporalio
559
564
  )
560
565
 
561
566
  # Collect interceptors from client and params
562
- @activity_interceptors = (@options.client.options.interceptors + @options.interceptors).select do |i|
563
- i.is_a?(Interceptor::Activity)
564
- end
565
- @workflow_interceptors = (@options.client.options.interceptors + @options.interceptors).select do |i|
566
- i.is_a?(Interceptor::Workflow)
567
- end
567
+ @activity_interceptors = (@options.client.options.interceptors + @options.interceptors).grep(Interceptor::Activity)
568
+ @workflow_interceptors = (@options.client.options.interceptors + @options.interceptors).grep(Interceptor::Workflow)
568
569
 
569
570
  # Cancellation for the whole worker
570
571
  @worker_shutdown_cancellation = Cancellation.new
@@ -9,8 +9,6 @@ module Temporalio
9
9
  )
10
10
 
11
11
  # Represents the version of a specific worker deployment.
12
- #
13
- # WARNING: Experimental API.
14
12
  class WorkerDeploymentVersion
15
13
  # Parse a version from a canonical string, which must be in the format
16
14
  # `<deployment_name>.<build_id>`. Deployment name must not have a `.` in it.