temporalio 1.7.0 → 1.9.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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -0
  3. data/Rakefile +19 -0
  4. data/lib/temporalio/activity/info.rb +0 -3
  5. data/lib/temporalio/client/activity_execution.rb +83 -6
  6. data/lib/temporalio/client/activity_execution_count.rb +0 -4
  7. data/lib/temporalio/client/activity_execution_options.rb +39 -0
  8. data/lib/temporalio/client/activity_execution_status.rb +1 -2
  9. data/lib/temporalio/client/activity_handle.rb +127 -3
  10. data/lib/temporalio/client/activity_id_reference.rb +0 -4
  11. data/lib/temporalio/client/activity_options.rb +113 -0
  12. data/lib/temporalio/client/interceptor.rb +63 -26
  13. data/lib/temporalio/client/pending_activity_state.rb +0 -2
  14. data/lib/temporalio/client.rb +6 -16
  15. data/lib/temporalio/common_enums.rb +0 -4
  16. data/lib/temporalio/error/failure.rb +0 -2
  17. data/lib/temporalio/error.rb +0 -2
  18. data/lib/temporalio/internal/client/implementation.rb +60 -3
  19. data/lib/temporalio/scoped_logger.rb +3 -0
  20. data/lib/temporalio/version.rb +1 -1
  21. data/lib/temporalio/worker/activity_executor/fiber.rb +11 -1
  22. data/rbi/temporalio/client/activity_execution.rbi +28 -1
  23. data/rbi/temporalio/client/activity_execution_options.rbi +58 -0
  24. data/rbi/temporalio/client/activity_execution_status.rbi +1 -0
  25. data/rbi/temporalio/client/activity_handle.rbi +43 -2
  26. data/rbi/temporalio/client/activity_options.rbi +49 -0
  27. data/rbi/temporalio/client/interceptor.rbi +108 -1
  28. data/rbi/temporalio/client.rbi +4 -4
  29. data/sig/temporalio/client/activity_execution.rbs +11 -1
  30. data/sig/temporalio/client/activity_execution_options.rbs +27 -0
  31. data/sig/temporalio/client/activity_execution_status.rbs +1 -0
  32. data/sig/temporalio/client/activity_handle.rbs +23 -1
  33. data/sig/temporalio/client/activity_options.rbs +30 -0
  34. data/sig/temporalio/client/interceptor.rbs +64 -2
  35. data/sig/temporalio/client.rbs +2 -2
  36. data/sig/temporalio/internal/client/implementation.rbs +7 -0
  37. metadata +7 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 268dababab1b3104d90484a92d2b31cf2716c0ccf8e174b86f957d7e78a7dc34
4
- data.tar.gz: 4ac90452d338cda2967b8ab88f9fac481dc92a6ec8aa740be539067c9a5e07da
3
+ metadata.gz: 83bdaf2665c0e0870da1ad032bc014bb2a99970eee632c7349b5ebd35611bea3
4
+ data.tar.gz: 8bd6f029572ee2b46477306283a33480eaea57bf8bdac45ed094bcd6bc2110c8
5
5
  SHA512:
6
- metadata.gz: 1cbb397fdb411c2d869e2deb6cc641e1840d272071e425b58da2d6bca9b39bea69428d6a20da60688325094cf4c8ddc0568033ec57e8772b42ca3594b6477a07
7
- data.tar.gz: b1b91bb6f524008cf4b1c40d29c6e92c8e3bc22addf949c6b12aedd631e0314ea65770853f9a0076016a9540f10bb2e22a4170e606defd934187a1fcc9783774
6
+ metadata.gz: bc6cad44f81d64124fb61c16605f011ebace9a6121ef8e7d63b81dd88e4050da7e5aac376e326679c6d4da2f44d1a3a3fdcc4a5c21fd8335a3c5f22d40eeb27b
7
+ data.tar.gz: a04e3cebf85f26728de6445268cd3f88adc3614f4c02bc9bae3e05a566f2a0848cb6a8d61eba595d14eb651f6db5c89b471ef3fb4f71ad98e0d47591a2599dbf
data/README.md CHANGED
@@ -1491,6 +1491,14 @@ E.g. show all test names while executing:
1491
1491
 
1492
1492
  bundle exec rake test TESTOPTS="--verbose"
1493
1493
 
1494
+ To list source tests excluded from Cloud, grouped by reason and note:
1495
+
1496
+ bundle exec rake test:cloud_inventory
1497
+
1498
+ To run the Cloud-eligible suite against an envconfig-defined server:
1499
+
1500
+ bundle exec rake test:cloud
1501
+
1494
1502
  ### Code Formatting and Type Checking
1495
1503
 
1496
1504
  This project uses `rubocop`:
data/Rakefile CHANGED
@@ -27,6 +27,25 @@ Rake::TestTask.new(:test) do |t|
27
27
  t.test_files = FileList['test/**/*_test.rb', 'extra/release/test/**/*_test.rb']
28
28
  end
29
29
 
30
+ namespace :test do
31
+ desc 'List tests excluded from Temporal Cloud by reason'
32
+ task :cloud_inventory do
33
+ ENV['TESTOPTS'] = [
34
+ ENV.fetch('TESTOPTS', nil),
35
+ '--cloud-inventory',
36
+ '--name=/CloudTestInventoryTest#test_report/'
37
+ ].compact.join(' ')
38
+ Rake::Task[:test].invoke
39
+ end
40
+
41
+ desc 'Run tests eligible for Temporal Cloud using envconfig'
42
+ task :cloud do
43
+ ENV['TEMPORAL_TEST_ENV_CONFIG_SERVER'] = '1'
44
+ ENV['TESTOPTS'] = [ENV.fetch('TESTOPTS', nil), '--cloud'].compact.join(' ')
45
+ Rake::Task[:test].invoke
46
+ end
47
+ end
48
+
30
49
  require 'rubocop/rake_task'
31
50
 
32
51
  RuboCop::RakeTask.new
@@ -35,7 +35,6 @@ module Temporalio
35
35
  # @return [String] ID for the activity.
36
36
  # @!attribute activity_run_id
37
37
  # @return [String, nil] Run ID for a standalone activity execution. nil for activities scheduled from a workflow.
38
- # WARNING: Standalone Activities are experimental.
39
38
  # @!attribute activity_type
40
39
  # @return [String] Type name for the activity.
41
40
  # @!attribute attempt
@@ -85,8 +84,6 @@ module Temporalio
85
84
  # class or it may break in incompatible ways.
86
85
  class Info
87
86
  # @return [Boolean] True if this activity was scheduled by a workflow execution; false for standalone activities.
88
- #
89
- # WARNING: Standalone Activities are experimental.
90
87
  def in_workflow?
91
88
  !workflow_id.nil?
92
89
  end
@@ -13,8 +13,6 @@ module Temporalio
13
13
  class Client
14
14
  # Info for a standalone activity execution. Returned by list_activities; extended by {Description}
15
15
  # for describe results.
16
- #
17
- # WARNING: Standalone Activities are experimental.
18
16
  class ActivityExecution
19
17
  # @return [Api::Activity::V1::ActivityExecutionListInfo, Api::Activity::V1::ActivityExecutionInfo]
20
18
  # Underlying protobuf info.
@@ -46,6 +44,12 @@ module Temporalio
46
44
  Internal::ProtoUtils.timestamp_to_time(@raw_info.schedule_time)
47
45
  end
48
46
 
47
+ # @return [Time, nil] When the first activity task was made available for dispatch. Equals
48
+ # schedule_time + start_delay; equal to schedule_time when no start delay is set.
49
+ def execution_time
50
+ Internal::ProtoUtils.timestamp_to_time(@raw_info.execution_time)
51
+ end
52
+
49
53
  # @return [Time, nil] When the activity reached a terminal state.
50
54
  def close_time
51
55
  Internal::ProtoUtils.timestamp_to_time(@raw_info.close_time)
@@ -72,8 +76,6 @@ module Temporalio
72
76
  end
73
77
 
74
78
  # Rich description of a standalone activity execution; returned by {ActivityHandle#describe}.
75
- #
76
- # WARNING: Standalone Activities are experimental.
77
79
  class Description < ActivityExecution
78
80
  # @return [Api::WorkflowService::V1::DescribeActivityExecutionResponse] Underlying protobuf response.
79
81
  attr_reader :raw_description
@@ -112,7 +114,17 @@ module Temporalio
112
114
  Internal::ProtoUtils.duration_to_seconds(@raw_info.heartbeat_timeout)
113
115
  end
114
116
 
115
- # @return [Boolean] Whether the activity has recorded any heartbeat details.
117
+ # @return [Float, nil] Delay in seconds before the first activity task is made available for
118
+ # dispatch. Not applied to retry attempts.
119
+ def start_delay
120
+ Internal::ProtoUtils.duration_to_seconds(@raw_info.start_delay)
121
+ end
122
+
123
+ # Whether heartbeat details are present on this description. False when the activity
124
+ # recorded none, and also when {ActivityHandle#describe} was called without
125
+ # `include_heartbeat_details:`.
126
+ #
127
+ # @return [Boolean] Whether heartbeat details are present.
116
128
  def has_heartbeat_details? # rubocop:disable Naming/PredicatePrefix
117
129
  !@raw_info.heartbeat_details&.payloads.nil? && !@raw_info.heartbeat_details.payloads.empty?
118
130
  end
@@ -125,6 +137,57 @@ module Temporalio
125
137
  @data_converter.from_payloads(@raw_info.heartbeat_details, hints:)
126
138
  end
127
139
 
140
+ # Whether the activity's input is present. False unless {ActivityHandle#describe} was
141
+ # called with `include_input:`.
142
+ #
143
+ # @return [Boolean] Whether input is present.
144
+ def has_input? # rubocop:disable Naming/PredicatePrefix
145
+ !@raw_description.input.nil?
146
+ end
147
+
148
+ # Deserialized activity input, one element per argument. Empty when no input is present.
149
+ #
150
+ # @param hints [Array<Object>, nil] Hints, if any, to assist conversion.
151
+ # @return [Array<Object>] Converted arguments.
152
+ def input(hints: nil)
153
+ @data_converter.from_payloads(@raw_description.input, hints:)
154
+ end
155
+
156
+ # Whether the activity closed with a successful result. False while the activity is still
157
+ # running, when it closed with a failure, and when {ActivityHandle#describe} was called
158
+ # without `include_outcome:`.
159
+ #
160
+ # @return [Boolean] Whether a result is present.
161
+ def has_result? # rubocop:disable Naming/PredicatePrefix
162
+ @raw_description.outcome&.value == :result
163
+ end
164
+
165
+ # Deserialized result the activity closed with. Nil when no result is present (still
166
+ # running, closed with a failure, or `include_outcome:` was not requested).
167
+ #
168
+ # @param result_hint [Object, nil] Hint, if any, to assist conversion.
169
+ # @return [Object, nil] Converted result.
170
+ def result(result_hint: nil)
171
+ return nil unless has_result?
172
+
173
+ @data_converter.from_payloads(
174
+ @raw_description.outcome.result, hints: Array(result_hint)
175
+ ).first
176
+ end
177
+
178
+ # Failure the activity closed with. Nil when the activity did not close with a failure or
179
+ # when {ActivityHandle#describe} was called without `include_outcome:`.
180
+ #
181
+ # This is the terminal outcome; {#last_failure} is the failure of the most recent attempt,
182
+ # which may be set while the activity is still retrying.
183
+ #
184
+ # @return [Error::Failure, nil] Converted failure.
185
+ def failure
186
+ return nil unless @raw_description.outcome&.value == :failure
187
+
188
+ @data_converter.from_failure(@raw_description.outcome.failure)
189
+ end
190
+
128
191
  # @return [RetryPolicy] Retry policy in effect for this activity.
129
192
  def retry_policy
130
193
  RetryPolicy._from_proto(@raw_info.retry_policy)
@@ -145,6 +208,20 @@ module Temporalio
145
208
  @raw_info.attempt
146
209
  end
147
210
 
211
+ # @return [Integer] Total number of heartbeats recorded across all attempts.
212
+ def total_heartbeat_count
213
+ @raw_info.total_heartbeat_count
214
+ end
215
+
216
+ # Whether a last failure is present on this description. False when the activity has no
217
+ # failed attempt, and also when {ActivityHandle#describe} was called without
218
+ # `include_last_failure:`.
219
+ #
220
+ # @return [Boolean] Whether a last failure is present.
221
+ def has_last_failure? # rubocop:disable Naming/PredicatePrefix
222
+ !@raw_info.last_failure.nil?
223
+ end
224
+
148
225
  # @return [Error::Failure, nil] Failure of the last failed attempt if any.
149
226
  def last_failure
150
227
  return nil unless @raw_info.last_failure
@@ -199,7 +276,7 @@ module Temporalio
199
276
  end
200
277
 
201
278
  # @return [String, nil] Static user-metadata summary on the activity.
202
- def static_summary
279
+ def summary
203
280
  user_metadata.first
204
281
  end
205
282
 
@@ -3,8 +3,6 @@
3
3
  module Temporalio
4
4
  class Client
5
5
  # Result of a {Client#count_activities} call.
6
- #
7
- # WARNING: Standalone Activities are experimental.
8
6
  class ActivityExecutionCount
9
7
  # @return [Integer] Approximate number of activities matching the query. If the query had a group-by clause,
10
8
  # this is the sum of all the counts in {groups}.
@@ -20,8 +18,6 @@ module Temporalio
20
18
  end
21
19
 
22
20
  # Aggregation group if the activity count query had a group-by clause.
23
- #
24
- # WARNING: Standalone Activities are experimental.
25
21
  class AggregationGroup
26
22
  # @return [Integer] Approximate number of activities matching the query for this group.
27
23
  attr_reader :count
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'temporalio/internal/proto_utils'
4
+ require 'temporalio/priority'
5
+ require 'temporalio/retry_policy'
6
+
7
+ module Temporalio
8
+ class Client
9
+ # The resolved options of a standalone activity execution, as returned by
10
+ # {ActivityHandle#update_options}. Reflects the activity's options as the server resolved them
11
+ # after the update was applied.
12
+ #
13
+ # WARNING: Standalone Activities are experimental.
14
+ ActivityExecutionOptions = Data.define(
15
+ :task_queue,
16
+ :schedule_to_close_timeout,
17
+ :schedule_to_start_timeout,
18
+ :start_to_close_timeout,
19
+ :heartbeat_timeout,
20
+ :retry_policy,
21
+ :priority,
22
+ :start_delay
23
+ ) do
24
+ # @!visibility private
25
+ def self._from_proto(options)
26
+ new(
27
+ task_queue: Internal::ProtoUtils.string_or(options.task_queue&.name, nil),
28
+ schedule_to_close_timeout: Internal::ProtoUtils.duration_to_seconds(options.schedule_to_close_timeout),
29
+ schedule_to_start_timeout: Internal::ProtoUtils.duration_to_seconds(options.schedule_to_start_timeout),
30
+ start_to_close_timeout: Internal::ProtoUtils.duration_to_seconds(options.start_to_close_timeout),
31
+ heartbeat_timeout: Internal::ProtoUtils.duration_to_seconds(options.heartbeat_timeout),
32
+ retry_policy: options.retry_policy ? RetryPolicy._from_proto(options.retry_policy) : nil,
33
+ priority: Priority._from_proto(options.priority),
34
+ start_delay: Internal::ProtoUtils.duration_to_seconds(options.start_delay)
35
+ )
36
+ end
37
+ end
38
+ end
39
+ end
@@ -5,8 +5,6 @@ require 'temporalio/api'
5
5
  module Temporalio
6
6
  class Client
7
7
  # Status of a standalone activity execution.
8
- #
9
- # WARNING: Standalone Activities are experimental.
10
8
  module ActivityExecutionStatus
11
9
  UNSPECIFIED = Api::Enums::V1::ActivityExecutionStatus::ACTIVITY_EXECUTION_STATUS_UNSPECIFIED
12
10
  RUNNING = Api::Enums::V1::ActivityExecutionStatus::ACTIVITY_EXECUTION_STATUS_RUNNING
@@ -15,6 +13,7 @@ module Temporalio
15
13
  CANCELED = Api::Enums::V1::ActivityExecutionStatus::ACTIVITY_EXECUTION_STATUS_CANCELED
16
14
  TERMINATED = Api::Enums::V1::ActivityExecutionStatus::ACTIVITY_EXECUTION_STATUS_TERMINATED
17
15
  TIMED_OUT = Api::Enums::V1::ActivityExecutionStatus::ACTIVITY_EXECUTION_STATUS_TIMED_OUT
16
+ PAUSED = Api::Enums::V1::ActivityExecutionStatus::ACTIVITY_EXECUTION_STATUS_PAUSED
18
17
  end
19
18
  end
20
19
  end
@@ -2,15 +2,18 @@
2
2
 
3
3
  require 'temporalio/api'
4
4
  require 'temporalio/client/activity_execution'
5
+ require 'temporalio/client/activity_execution_options'
6
+ require 'temporalio/client/activity_options'
5
7
  require 'temporalio/client/interceptor'
6
8
  require 'temporalio/error'
9
+ require 'temporalio/internal/proto_utils'
10
+ require 'temporalio/priority'
11
+ require 'temporalio/retry_policy'
7
12
 
8
13
  module Temporalio
9
14
  class Client
10
15
  # Handle for interacting with a standalone activity. Usually created via {Client.activity_handle}
11
16
  # or {Client#start_activity}.
12
- #
13
- # WARNING: Standalone Activities are experimental.
14
17
  class ActivityHandle
15
18
  # @return [String] ID for the activity.
16
19
  attr_reader :id
@@ -55,15 +58,35 @@ module Temporalio
55
58
 
56
59
  # Describe the activity.
57
60
  #
61
+ # The payload-bearing fields are opt-in because they can be arbitrarily large; request them
62
+ # only when needed. Each has a corresponding predicate on the returned description that
63
+ # reports whether the server supplied it.
64
+ #
65
+ # @param include_input [Boolean] If true and the activity received input, include the input.
66
+ # @param include_outcome [Boolean] If true and the activity is closed, include the outcome.
67
+ # @param include_heartbeat_details [Boolean] If true and the activity recorded heartbeat
68
+ # details, include them.
69
+ # @param include_last_failure [Boolean] If true and the activity has a failed attempt, include
70
+ # the last failure.
58
71
  # @param rpc_options [RPCOptions, nil] Advanced RPC options.
59
72
  #
60
73
  # @return [ActivityExecution::Description] Activity description.
61
74
  # @raise [Error::RPCError] RPC error from call.
62
- def describe(rpc_options: nil)
75
+ def describe(
76
+ include_input: false,
77
+ include_outcome: false,
78
+ include_heartbeat_details: false,
79
+ include_last_failure: false,
80
+ rpc_options: nil
81
+ )
63
82
  @client._impl.describe_activity(
64
83
  Interceptor::DescribeActivityInput.new(
65
84
  activity_id: id,
66
85
  activity_run_id: run_id,
86
+ include_input:,
87
+ include_outcome:,
88
+ include_heartbeat_details:,
89
+ include_last_failure:,
67
90
  rpc_options:
68
91
  )
69
92
  )
@@ -103,6 +126,107 @@ module Temporalio
103
126
  nil
104
127
  end
105
128
 
129
+ # Pause the activity. A paused activity is not scheduled or retried until it is unpaused via
130
+ # {#unpause}.
131
+ #
132
+ # WARNING: Standalone Activities are experimental.
133
+ #
134
+ # @param reason [String, nil] Optional reason recorded on the server.
135
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
136
+ # @raise [Error::RPCError] RPC error from call.
137
+ def pause(reason = nil, rpc_options: nil)
138
+ @client._impl.pause_activity(
139
+ Interceptor::PauseActivityInput.new(
140
+ activity_id: id,
141
+ activity_run_id: run_id,
142
+ reason:,
143
+ rpc_options:
144
+ )
145
+ )
146
+ nil
147
+ end
148
+
149
+ # Unpause the activity, allowing it to be scheduled or retried again.
150
+ #
151
+ # WARNING: Standalone Activities are experimental.
152
+ #
153
+ # @param reason [String, nil] Optional reason recorded on the server.
154
+ # @param jitter [Float, nil] If set, the activity will start at a random time within this
155
+ # duration (in seconds).
156
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
157
+ # @raise [Error::RPCError] RPC error from call.
158
+ def unpause(reason: nil, jitter: nil, rpc_options: nil)
159
+ @client._impl.unpause_activity(
160
+ Interceptor::UnpauseActivityInput.new(
161
+ activity_id: id,
162
+ activity_run_id: run_id,
163
+ reason:,
164
+ jitter:,
165
+ rpc_options:
166
+ )
167
+ )
168
+ nil
169
+ end
170
+
171
+ # Update the activity's options. Only the options named by `updates` are changed; anything
172
+ # not named is left as-is.
173
+ #
174
+ # Updates are created from the keys on {ActivityOptions}, via {ActivityOptions::Key#value_set}
175
+ # to set an option or {ActivityOptions::Key#value_unset} to clear it.
176
+ #
177
+ # WARNING: Standalone Activities are experimental.
178
+ #
179
+ # @param updates [Array<ActivityOptions::Update>] The option updates to apply. At least one is
180
+ # required unless `restore_original` is true. Each option may be named at most once.
181
+ # @param restore_original [Boolean] If true, restore the options to the originals the activity
182
+ # was created with. Mutually exclusive with any update.
183
+ # @param rpc_options [RPCOptions, nil] Advanced RPC options.
184
+ #
185
+ # @return [ActivityExecutionOptions] The activity options after the update.
186
+ #
187
+ # @raise [ArgumentError] If a non-update is given, if `restore_original` is combined with any
188
+ # update, if no update is provided and `restore_original` is false, or if the same option is
189
+ # named more than once.
190
+ # @raise [Error::RPCError] RPC error from call.
191
+ def update_options(*updates, restore_original: false, rpc_options: nil)
192
+ unless updates.all?(ActivityOptions::Update)
193
+ raise ArgumentError,
194
+ 'Updates must be created via ActivityOptions::Key#value_set or #value_unset'
195
+ end
196
+
197
+ if restore_original && !updates.empty?
198
+ raise ArgumentError, 'restore_original cannot be combined with any option update'
199
+ elsif !restore_original && updates.empty?
200
+ raise ArgumentError,
201
+ 'At least one option update must be given, or restore_original must be used'
202
+ end
203
+
204
+ by_path = updates.each_with_object({}) do |update, acc|
205
+ name = update.key.name
206
+ raise ArgumentError, "More than one update given for option #{name}" if acc.key?(name)
207
+
208
+ acc[name] = update
209
+ end
210
+
211
+ proto = Api::Activity::V1::ActivityOptions.new
212
+ by_path.each_value do |update|
213
+ # An unset update names its path but leaves the field absent, which is how the server is
214
+ # told to clear the option rather than set it to a value.
215
+ update.key._apply(proto, update.value) unless update.value.nil?
216
+ end
217
+
218
+ @client._impl.update_activity_options(
219
+ Interceptor::UpdateActivityOptionsInput.new(
220
+ activity_id: id,
221
+ activity_run_id: run_id,
222
+ activity_options: proto,
223
+ update_mask: Google::Protobuf::FieldMask.new(paths: by_path.keys),
224
+ restore_original:,
225
+ rpc_options:
226
+ )
227
+ )
228
+ end
229
+
106
230
  private
107
231
 
108
232
  def _process_outcome(outcome, hint)
@@ -29,8 +29,6 @@ module Temporalio
29
29
 
30
30
  # Construct a standalone activity reference.
31
31
  #
32
- # WARNING: Standalone Activities are experimental.
33
- #
34
32
  # @param activity_id [String] ID for the activity.
35
33
  # @param activity_run_id [String, nil] Run ID for the activity execution. nil targets the latest run.
36
34
  # @return [ActivityIDReference] A reference suitable for {Client#async_activity_handle}.
@@ -57,8 +55,6 @@ module Temporalio
57
55
  end
58
56
 
59
57
  # @return [Boolean] True if this reference is the standalone-form (activity_run_id without workflow_id).
60
- #
61
- # WARNING: Standalone Activities are experimental.
62
58
  def standalone?
63
59
  @workflow_id.nil?
64
60
  end
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'temporalio/api'
4
+ require 'temporalio/internal/proto_utils'
5
+
6
+ module Temporalio
7
+ class Client
8
+ # The activity options that {ActivityHandle#update_options} can change.
9
+ #
10
+ # Updates are created from the keys below, via {Key#value_set} to set an option or
11
+ # {Key#value_unset} to clear it. An option with no update is left untouched.
12
+ #
13
+ # WARNING: Standalone Activities are experimental.
14
+ module ActivityOptions
15
+ # Typed key for one updatable activity option. Use the keys on {ActivityOptions} rather than
16
+ # constructing these directly.
17
+ class Key
18
+ # @return [String] Field-mask path this key updates.
19
+ attr_reader :name
20
+
21
+ # @!visibility private
22
+ def initialize(name, &to_proto)
23
+ @name = name
24
+ @to_proto = to_proto
25
+ freeze
26
+ end
27
+
28
+ # Create an update that sets this option to the given value.
29
+ #
30
+ # @param value [Object] Value to set. Cannot be nil.
31
+ # @return [Update] Created update.
32
+ def value_set(value)
33
+ raise ArgumentError, 'Value cannot be nil, use value_unset' if value.nil?
34
+
35
+ Update.new(self, value)
36
+ end
37
+
38
+ # Create an update that clears this option server-side.
39
+ #
40
+ # @return [Update] Created update.
41
+ def value_unset
42
+ Update.new(self, nil)
43
+ end
44
+
45
+ # @!visibility private
46
+ def _apply(proto, value)
47
+ @to_proto.call(proto, value)
48
+ end
49
+ end
50
+
51
+ # A single change to an activity's options that can be separately applied.
52
+ class Update
53
+ # @return [Key] Key this update applies to.
54
+ attr_reader :key
55
+
56
+ # @return [Object, nil] Value to set, or `nil` to clear the option.
57
+ attr_reader :value
58
+
59
+ # Create an update. Users may find it easier to use {Key#value_set} and {Key#value_unset}.
60
+ #
61
+ # @param key [Key] Key to update.
62
+ # @param value [Object, nil] Value to set, or nil to clear the option.
63
+ def initialize(key, value)
64
+ raise ArgumentError, 'Key must be a key' unless key.is_a?(Key)
65
+
66
+ @key = key
67
+ @value = value
68
+ freeze
69
+ end
70
+ end
71
+
72
+ # @return [Key] New task queue.
73
+ TASK_QUEUE = Key.new('task_queue.name') do |proto, value|
74
+ proto.task_queue = Api::TaskQueue::V1::TaskQueue.new(name: value.to_s)
75
+ end
76
+
77
+ # @return [Key] New schedule-to-close timeout in seconds.
78
+ SCHEDULE_TO_CLOSE_TIMEOUT = Key.new('schedule_to_close_timeout') do |proto, value|
79
+ proto.schedule_to_close_timeout = Internal::ProtoUtils.seconds_to_duration(value)
80
+ end
81
+
82
+ # @return [Key] New schedule-to-start timeout in seconds.
83
+ SCHEDULE_TO_START_TIMEOUT = Key.new('schedule_to_start_timeout') do |proto, value|
84
+ proto.schedule_to_start_timeout = Internal::ProtoUtils.seconds_to_duration(value)
85
+ end
86
+
87
+ # @return [Key] New start-to-close timeout in seconds.
88
+ START_TO_CLOSE_TIMEOUT = Key.new('start_to_close_timeout') do |proto, value|
89
+ proto.start_to_close_timeout = Internal::ProtoUtils.seconds_to_duration(value)
90
+ end
91
+
92
+ # @return [Key] New heartbeat timeout in seconds.
93
+ HEARTBEAT_TIMEOUT = Key.new('heartbeat_timeout') do |proto, value|
94
+ proto.heartbeat_timeout = Internal::ProtoUtils.seconds_to_duration(value)
95
+ end
96
+
97
+ # @return [Key] New start delay in seconds.
98
+ START_DELAY = Key.new('start_delay') do |proto, value|
99
+ proto.start_delay = Internal::ProtoUtils.seconds_to_duration(value)
100
+ end
101
+
102
+ # @return [Key] New retry policy.
103
+ RETRY_POLICY = Key.new('retry_policy') do |proto, value|
104
+ proto.retry_policy = value._to_proto
105
+ end
106
+
107
+ # @return [Key] New priority.
108
+ PRIORITY = Key.new('priority') do |proto, value|
109
+ proto.priority = value._to_proto
110
+ end
111
+ end
112
+ end
113
+ end