temporalio 1.4.0 → 1.5.0

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.
@@ -3,6 +3,7 @@
3
3
  require 'google/protobuf/well_known_types'
4
4
  require 'logger'
5
5
  require 'temporalio/api'
6
+ require 'temporalio/client/activity_handle'
6
7
  require 'temporalio/client/async_activity_handle'
7
8
  require 'temporalio/client/connection'
8
9
  require 'temporalio/client/interceptor'
@@ -95,6 +96,9 @@ module Temporalio
95
96
  # @param runtime [Runtime] Runtime for this client.
96
97
  # @param lazy_connect [Boolean] If true, the client will not connect until the first call is attempted or a worker
97
98
  # is created with it. Lazy clients cannot be used for workers if they have not performed a connection.
99
+ # @param dns_load_balancing [Connection::DnsLoadBalancingOptions, nil] DNS load balancing options for the
100
+ # connection. Default is +nil+ (disabled). Silently disabled when +http_connect_proxy+ is set, since the two are
101
+ # mutually exclusive.
98
102
  #
99
103
  # @return [Client] Connected client.
100
104
  #
@@ -116,7 +120,8 @@ module Temporalio
116
120
  keep_alive: Connection::KeepAliveOptions.new, # Set to nil to disable
117
121
  http_connect_proxy: nil,
118
122
  runtime: Runtime.default,
119
- lazy_connect: false
123
+ lazy_connect: false,
124
+ dns_load_balancing: nil
120
125
  )
121
126
  # Prepare connection. The connection var is needed here so it can be used in callback for plugin.
122
127
  base_connection = nil
@@ -162,6 +167,7 @@ module Temporalio
162
167
  http_connect_proxy:,
163
168
  runtime:,
164
169
  lazy_connect:,
170
+ dns_load_balancing:,
165
171
  around_connect: # steep:ignore
166
172
  )
167
173
 
@@ -473,6 +479,209 @@ module Temporalio
473
479
  )
474
480
  end
475
481
 
482
+ # Get a handle for an existing standalone activity. Useful when the activity was started elsewhere
483
+ # (a different process, or by another client) and you have only its ID.
484
+ #
485
+ # WARNING: Standalone Activities are experimental.
486
+ #
487
+ # @param activity_id [String] ID for the activity.
488
+ # @param activity_run_id [String, nil] Run ID for the activity execution. If nil, operations target the
489
+ # latest run of the given activity ID.
490
+ # @param result_hint [Object, nil] Converter hint for the activity's result. Set this when you know what
491
+ # type the activity returns so {ActivityHandle#result}'s deserialization uses the right hint.
492
+ #
493
+ # @return [ActivityHandle] The activity handle.
494
+ def activity_handle(activity_id, activity_run_id: nil, result_hint: nil)
495
+ ActivityHandle.new(client: self, id: activity_id, run_id: activity_run_id, result_hint:)
496
+ end
497
+
498
+ # Start a standalone activity execution and return its handle.
499
+ #
500
+ # WARNING: Standalone Activities are experimental.
501
+ #
502
+ # @param activity [Class<Activity::Definition>, Activity::Definition, Activity::Definition::Info, Symbol, String]
503
+ # Activity definition, definition class or activity name.
504
+ # @param args [Array<Object>] Arguments to the activity.
505
+ # @param id [String] Unique identifier for the activity execution.
506
+ # @param task_queue [String] Task queue to run the activity on.
507
+ # @param schedule_to_close_timeout [Float, nil] Schedule-to-close timeout in seconds. Either this or
508
+ # `start_to_close_timeout` must be specified.
509
+ # @param schedule_to_start_timeout [Float, nil] Schedule-to-start timeout in seconds.
510
+ # @param start_to_close_timeout [Float, nil] Start-to-close timeout in seconds. Either this or
511
+ # `schedule_to_close_timeout` must be specified.
512
+ # @param heartbeat_timeout [Float, nil] Heartbeat timeout in seconds.
513
+ # @param id_reuse_policy [ActivityIDReusePolicy] Controls behavior when an activity with the same ID
514
+ # was previously run and has reached a terminal state. Defaults to `ALLOW_DUPLICATE`.
515
+ # @param id_conflict_policy [ActivityIDConflictPolicy] Controls behavior when an activity with the same ID
516
+ # is currently running. Defaults to `FAIL` (reject the start attempt).
517
+ # @param retry_policy [RetryPolicy, nil] Retry policy for the activity.
518
+ # @param search_attributes [SearchAttributes, nil] Search attributes for the activity.
519
+ # @param static_summary [String, nil] Fixed single-line summary for this activity execution.
520
+ # @param static_details [String, nil] Fixed details for this activity execution. May be in markdown format.
521
+ # @param priority [Priority] Priority for the activity. This is currently experimental.
522
+ # @param start_delay [Float, nil] Time (in seconds) to wait before dispatching the first activity task. This delay
523
+ # is not applied to retry attempts. `nil` or `0` means no delay. Negative values raise `ArgumentError`.
524
+ # This is currently experimental.
525
+ # @param arg_hints [Array<Object>, nil] Argument hints.
526
+ # @param result_hint [Object, nil] Result hint.
527
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
528
+ #
529
+ # @return [ActivityHandle] Handle to the started activity.
530
+ # @raise [Error::ActivityAlreadyStartedError] Activity already exists with this ID.
531
+ # @raise [Error::RPCError] RPC error from call.
532
+ def start_activity(
533
+ activity,
534
+ *args,
535
+ id:,
536
+ task_queue:,
537
+ schedule_to_close_timeout: nil,
538
+ schedule_to_start_timeout: nil,
539
+ start_to_close_timeout: nil,
540
+ heartbeat_timeout: nil,
541
+ id_reuse_policy: ActivityIDReusePolicy::ALLOW_DUPLICATE,
542
+ id_conflict_policy: ActivityIDConflictPolicy::FAIL,
543
+ retry_policy: nil,
544
+ search_attributes: nil,
545
+ static_summary: nil,
546
+ static_details: nil,
547
+ priority: Priority.default,
548
+ start_delay: nil,
549
+ arg_hints: nil,
550
+ result_hint: nil,
551
+ rpc_options: nil
552
+ )
553
+ activity_name, defn_arg_hints, defn_result_hint =
554
+ Activity::Definition::Info._type_and_hints_from_parameter(activity)
555
+ @impl.start_activity(Interceptor::StartActivityInput.new(
556
+ activity: activity_name,
557
+ args:,
558
+ activity_id: id,
559
+ task_queue:,
560
+ schedule_to_close_timeout:,
561
+ schedule_to_start_timeout:,
562
+ start_to_close_timeout:,
563
+ heartbeat_timeout:,
564
+ id_reuse_policy:,
565
+ id_conflict_policy:,
566
+ retry_policy:,
567
+ search_attributes:,
568
+ static_summary:,
569
+ static_details:,
570
+ headers: {},
571
+ priority:,
572
+ start_delay:,
573
+ arg_hints: arg_hints || defn_arg_hints,
574
+ result_hint: result_hint || defn_result_hint,
575
+ rpc_options:
576
+ ))
577
+ end
578
+
579
+ # Start a standalone activity execution and wait for its result. Shortcut for
580
+ # {start_activity} + {ActivityHandle#result}.
581
+ #
582
+ # WARNING: Standalone Activities are experimental.
583
+ #
584
+ # @param activity [Class<Activity::Definition>, Activity::Definition, Activity::Definition::Info, Symbol, String]
585
+ # Activity definition, definition class or activity name.
586
+ # @param args [Array<Object>] Arguments to the activity.
587
+ # @param id [String] Unique identifier for the activity execution.
588
+ # @param task_queue [String] Task queue to run the activity on.
589
+ # @param schedule_to_close_timeout [Float, nil] Schedule-to-close timeout in seconds. Either this or
590
+ # `start_to_close_timeout` must be specified.
591
+ # @param schedule_to_start_timeout [Float, nil] Schedule-to-start timeout in seconds.
592
+ # @param start_to_close_timeout [Float, nil] Start-to-close timeout in seconds. Either this or
593
+ # `schedule_to_close_timeout` must be specified.
594
+ # @param heartbeat_timeout [Float, nil] Heartbeat timeout in seconds.
595
+ # @param id_reuse_policy [ActivityIDReusePolicy] Controls behavior when an activity with the same ID
596
+ # was previously run and has reached a terminal state. Defaults to `ALLOW_DUPLICATE`.
597
+ # @param id_conflict_policy [ActivityIDConflictPolicy] Controls behavior when an activity with the same ID
598
+ # is currently running. Defaults to `FAIL` (reject the start attempt).
599
+ # @param retry_policy [RetryPolicy, nil] Retry policy for the activity.
600
+ # @param search_attributes [SearchAttributes, nil] Search attributes for the activity.
601
+ # @param static_summary [String, nil] Fixed single-line summary for this activity execution.
602
+ # @param static_details [String, nil] Fixed details for this activity execution. May be in markdown format.
603
+ # @param priority [Priority] Priority for the activity. This is currently experimental.
604
+ # @param start_delay [Float, nil] Time (in seconds) to wait before dispatching the first activity task. This delay
605
+ # is not applied to retry attempts. `nil` or `0` means no delay. Negative values raise `ArgumentError`.
606
+ # This is currently experimental.
607
+ # @param arg_hints [Array<Object>, nil] Argument hints.
608
+ # @param result_hint [Object, nil] Result hint.
609
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
610
+ #
611
+ # @return [Object, nil] Successful result of the activity.
612
+ # @raise [Error::ActivityAlreadyStartedError] Activity already exists with this ID.
613
+ # @raise [Error::ActivityFailedError] With `cause` populated from the activity failure.
614
+ # @raise [Error::RPCError] RPC error from call.
615
+ def execute_activity(
616
+ activity,
617
+ *args,
618
+ id:,
619
+ task_queue:,
620
+ schedule_to_close_timeout: nil,
621
+ schedule_to_start_timeout: nil,
622
+ start_to_close_timeout: nil,
623
+ heartbeat_timeout: nil,
624
+ id_reuse_policy: ActivityIDReusePolicy::ALLOW_DUPLICATE,
625
+ id_conflict_policy: ActivityIDConflictPolicy::FAIL,
626
+ retry_policy: nil,
627
+ search_attributes: nil,
628
+ static_summary: nil,
629
+ static_details: nil,
630
+ priority: Priority.default,
631
+ start_delay: nil,
632
+ arg_hints: nil,
633
+ result_hint: nil,
634
+ rpc_options: nil
635
+ )
636
+ start_activity(
637
+ activity,
638
+ *args,
639
+ id:,
640
+ task_queue:,
641
+ schedule_to_close_timeout:,
642
+ schedule_to_start_timeout:,
643
+ start_to_close_timeout:,
644
+ heartbeat_timeout:,
645
+ id_reuse_policy:,
646
+ id_conflict_policy:,
647
+ retry_policy:,
648
+ search_attributes:,
649
+ static_summary:,
650
+ static_details:,
651
+ priority:,
652
+ start_delay:,
653
+ arg_hints:,
654
+ result_hint:,
655
+ rpc_options:
656
+ ).result
657
+ end
658
+
659
+ # List standalone activities matching a visibility query.
660
+ #
661
+ # WARNING: Standalone Activities are experimental.
662
+ #
663
+ # @param query [String] Visibility list filter.
664
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
665
+ #
666
+ # @return [Enumerator<ActivityExecution>] Lazy enumerable of matching activity executions.
667
+ # @raise [Error::RPCError] RPC error from call.
668
+ def list_activities(query, rpc_options: nil)
669
+ @impl.list_activities(Interceptor::ListActivitiesInput.new(query:, rpc_options:))
670
+ end
671
+
672
+ # Count standalone activities matching a visibility query.
673
+ #
674
+ # WARNING: Standalone Activities are experimental.
675
+ #
676
+ # @param query [String] Visibility list filter.
677
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
678
+ #
679
+ # @return [ActivityExecutionCount] Count of activities (with per-group counts if the query had a group-by clause).
680
+ # @raise [Error::RPCError] RPC error from call.
681
+ def count_activities(query, rpc_options: nil)
682
+ @impl.count_activities(Interceptor::CountActivitiesInput.new(query:, rpc_options:))
683
+ end
684
+
476
685
  # Start an update, possibly starting the workflow at the same time if it doesn't exist (depending upon ID conflict
477
686
  # policy). Note that in some cases this may fail but the workflow will still be started, and the handle can then be
478
687
  # retrieved on the start workflow operation.
@@ -50,6 +50,22 @@ module Temporalio
50
50
  # workflow code.
51
51
  AUTO_UPGRADE =
52
52
  Api::Enums::V1::ContinueAsNewVersioningBehavior::CONTINUE_AS_NEW_VERSIONING_BEHAVIOR_AUTO_UPGRADE
53
+ # Use the Ramping Version of the workflow's task queue at start time, regardless of the workflow's
54
+ # Target Version (according to f(workflow_id, ramp_percentage)). After the first workflow task completes,
55
+ # the workflow will use whatever Versioning Behavior it is annotated with. If there is no Ramping
56
+ # Version by the time that the first workflow task is dispatched, it will be sent to the Current Version.
57
+ #
58
+ # It is highly discouraged to use this if the workflow is annotated with AutoUpgrade behavior, because
59
+ # this setting ONLY applies to the first task of the workflow. If, after the first task, the workflow
60
+ # is AutoUpgrade, it will behave like a normal AutoUpgrade workflow and go to the Target Version, which
61
+ # may be the Current Version instead of the Ramping Version.
62
+ #
63
+ # Note that if the workflow being continued has a Pinned override, that override will be inherited by the
64
+ # new workflow run regardless of the ContinueAsNewVersioningBehavior specified in the continue-as-new
65
+ # command. Versioning Override always takes precedence until it's removed manually via
66
+ # UpdateWorkflowExecutionOptions.
67
+ USE_RAMPING_VERSION =
68
+ Api::Enums::V1::ContinueAsNewVersioningBehavior::CONTINUE_AS_NEW_VERSIONING_BEHAVIOR_USE_RAMPING_VERSION
53
69
  end
54
70
 
55
71
  # Specifies why the server suggests continue-as-new. This is currently experimental.
@@ -68,6 +84,34 @@ module Temporalio
68
84
  Api::Enums::V1::SuggestContinueAsNewReason::SUGGEST_CONTINUE_AS_NEW_REASON_TOO_MANY_UPDATES
69
85
  end
70
86
 
87
+ # Controls behavior when an activity with the same ID was previously run and is now closed.
88
+ #
89
+ # WARNING: Standalone Activities are experimental.
90
+ #
91
+ # @see https://docs.temporal.io/activities
92
+ module ActivityIDReusePolicy
93
+ # Always allow starting an activity using the same activity ID.
94
+ ALLOW_DUPLICATE = Api::Enums::V1::ActivityIdReusePolicy::ACTIVITY_ID_REUSE_POLICY_ALLOW_DUPLICATE
95
+ # Allow starting an activity using the same ID only when the last activity execution was not successful.
96
+ ALLOW_DUPLICATE_FAILED_ONLY =
97
+ Api::Enums::V1::ActivityIdReusePolicy::ACTIVITY_ID_REUSE_POLICY_ALLOW_DUPLICATE_FAILED_ONLY
98
+ # Do not permit re-use of the ID for this activity. Future start requests could potentially change the policy,
99
+ # allowing re-use of the ID.
100
+ REJECT_DUPLICATE = Api::Enums::V1::ActivityIdReusePolicy::ACTIVITY_ID_REUSE_POLICY_REJECT_DUPLICATE
101
+ end
102
+
103
+ # Controls behavior when an activity with the same ID is currently running.
104
+ #
105
+ # WARNING: Standalone Activities are experimental.
106
+ #
107
+ # @see https://docs.temporal.io/activities
108
+ module ActivityIDConflictPolicy
109
+ # Don't start a new activity; instead fail with already-started error.
110
+ FAIL = Api::Enums::V1::ActivityIdConflictPolicy::ACTIVITY_ID_CONFLICT_POLICY_FAIL
111
+ # Don't start a new activity; instead return a handle for the running activity.
112
+ USE_EXISTING = Api::Enums::V1::ActivityIdConflictPolicy::ACTIVITY_ID_CONFLICT_POLICY_USE_EXISTING
113
+ end
114
+
71
115
  # Specifies when a workflow might move from a worker of one Build Id to another.
72
116
  module VersioningBehavior
73
117
  # Unspecified versioning behavior. By default, workers opting into worker versioning will
@@ -29,6 +29,28 @@ module Temporalio
29
29
  end
30
30
  end
31
31
 
32
+ # Error raised by a client when a standalone activity execution has already started.
33
+ #
34
+ # WARNING: Standalone Activities are experimental.
35
+ class ActivityAlreadyStartedError < Failure
36
+ # @return [String] ID of the already-started activity.
37
+ attr_reader :activity_id
38
+
39
+ # @return [String] Activity type name of the already-started activity.
40
+ attr_reader :activity_type
41
+
42
+ # @return [String, nil] Run ID of the already-started activity if known.
43
+ attr_reader :activity_run_id
44
+
45
+ # @!visibility private
46
+ def initialize(activity_id:, activity_type:, activity_run_id:)
47
+ super('Activity execution already started')
48
+ @activity_id = activity_id
49
+ @activity_type = activity_type
50
+ @activity_run_id = activity_run_id
51
+ end
52
+ end
53
+
32
54
  # Error raised during workflow/activity execution.
33
55
  class ApplicationError < Failure
34
56
  # @return [Array<Object, nil>] User-defined details on the error.
@@ -40,6 +40,17 @@ module Temporalio
40
40
  end
41
41
  end
42
42
 
43
+ # Error returned from {Client::ActivityHandle#result} when the activity did not complete successfully.
44
+ # The specific activity failure can be accessed via `cause`.
45
+ #
46
+ # WARNING: Standalone Activities are experimental.
47
+ class ActivityFailedError < Error
48
+ # @!visibility private
49
+ def initialize(message = 'Activity execution failed')
50
+ super
51
+ end
52
+ end
53
+
43
54
  # Error that occurs when a workflow was continued as new.
44
55
  class WorkflowContinuedAsNewError < Error
45
56
  # @return [String] New execution run ID the workflow continued to.
@@ -16,7 +16,8 @@ module Temporalio
16
16
  :tls, # Optional
17
17
  :rpc_retry,
18
18
  :keep_alive, # Optional
19
- :http_connect_proxy # Optional
19
+ :http_connect_proxy, # Optional
20
+ :dns_load_balancing # Optional
20
21
  )
21
22
 
22
23
  TLSOptions = Struct.new(
@@ -46,6 +47,10 @@ module Temporalio
46
47
  :basic_auth_pass # Optional
47
48
  )
48
49
 
50
+ DnsLoadBalancingOptions = Struct.new(
51
+ :resolution_interval
52
+ )
53
+
49
54
  def self.new(runtime, options)
50
55
  queue = Queue.new
51
56
  async_new(runtime, options, queue)