temporalio 0.3.0-x86_64-linux-musl → 0.5.0-x86_64-linux-musl

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 (149) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -1
  3. data/Gemfile +4 -0
  4. data/Rakefile +1 -1
  5. data/lib/temporalio/activity/cancellation_details.rb +58 -0
  6. data/lib/temporalio/activity/context.rb +17 -1
  7. data/lib/temporalio/activity/definition.rb +45 -4
  8. data/lib/temporalio/activity/info.rb +28 -4
  9. data/lib/temporalio/activity.rb +2 -0
  10. data/lib/temporalio/api/activity/v1/message.rb +1 -1
  11. data/lib/temporalio/api/batch/v1/message.rb +9 -2
  12. data/lib/temporalio/api/cloud/account/v1/message.rb +1 -1
  13. data/lib/temporalio/api/cloud/cloudservice/v1/request_response.rb +11 -2
  14. data/lib/temporalio/api/cloud/cloudservice/v1/service.rb +2 -2
  15. data/lib/temporalio/api/cloud/identity/v1/message.rb +7 -2
  16. data/lib/temporalio/api/cloud/namespace/v1/message.rb +6 -2
  17. data/lib/temporalio/api/cloud/nexus/v1/message.rb +3 -2
  18. data/lib/temporalio/api/cloud/operation/v1/message.rb +1 -1
  19. data/lib/temporalio/api/cloud/region/v1/message.rb +1 -1
  20. data/lib/temporalio/api/cloud/resource/v1/message.rb +1 -1
  21. data/lib/temporalio/api/cloud/sink/v1/message.rb +1 -1
  22. data/lib/temporalio/api/cloud/usage/v1/message.rb +1 -1
  23. data/lib/temporalio/api/command/v1/message.rb +2 -2
  24. data/lib/temporalio/api/common/v1/grpc_status.rb +1 -1
  25. data/lib/temporalio/api/common/v1/message.rb +4 -2
  26. data/lib/temporalio/api/deployment/v1/message.rb +39 -0
  27. data/lib/temporalio/api/enums/v1/batch_operation.rb +2 -2
  28. data/lib/temporalio/api/enums/v1/command_type.rb +1 -1
  29. data/lib/temporalio/api/enums/v1/common.rb +5 -2
  30. data/lib/temporalio/api/enums/v1/deployment.rb +24 -0
  31. data/lib/temporalio/api/enums/v1/event_type.rb +2 -2
  32. data/lib/temporalio/api/enums/v1/failed_cause.rb +2 -2
  33. data/lib/temporalio/api/enums/v1/namespace.rb +1 -1
  34. data/lib/temporalio/api/enums/v1/nexus.rb +21 -0
  35. data/lib/temporalio/api/enums/v1/query.rb +1 -1
  36. data/lib/temporalio/api/enums/v1/reset.rb +2 -2
  37. data/lib/temporalio/api/enums/v1/schedule.rb +1 -1
  38. data/lib/temporalio/api/enums/v1/task_queue.rb +1 -1
  39. data/lib/temporalio/api/enums/v1/update.rb +1 -1
  40. data/lib/temporalio/api/enums/v1/workflow.rb +3 -2
  41. data/lib/temporalio/api/errordetails/v1/message.rb +4 -2
  42. data/lib/temporalio/api/export/v1/message.rb +1 -1
  43. data/lib/temporalio/api/failure/v1/message.rb +5 -2
  44. data/lib/temporalio/api/filter/v1/message.rb +1 -1
  45. data/lib/temporalio/api/history/v1/message.rb +6 -2
  46. data/lib/temporalio/api/namespace/v1/message.rb +1 -1
  47. data/lib/temporalio/api/nexus/v1/message.rb +3 -2
  48. data/lib/temporalio/api/operatorservice/v1/request_response.rb +1 -1
  49. data/lib/temporalio/api/operatorservice/v1/service.rb +1 -1
  50. data/lib/temporalio/api/payload_visitor.rb +162 -7
  51. data/lib/temporalio/api/protocol/v1/message.rb +1 -1
  52. data/lib/temporalio/api/query/v1/message.rb +3 -2
  53. data/lib/temporalio/api/replication/v1/message.rb +1 -1
  54. data/lib/temporalio/api/rules/v1/message.rb +27 -0
  55. data/lib/temporalio/api/schedule/v1/message.rb +2 -2
  56. data/lib/temporalio/api/sdk/v1/enhanced_stack_trace.rb +1 -1
  57. data/lib/temporalio/api/sdk/v1/task_complete_metadata.rb +1 -1
  58. data/lib/temporalio/api/sdk/v1/user_metadata.rb +1 -1
  59. data/lib/temporalio/api/sdk/v1/workflow_metadata.rb +1 -1
  60. data/lib/temporalio/api/taskqueue/v1/message.rb +5 -2
  61. data/lib/temporalio/api/testservice/v1/request_response.rb +1 -1
  62. data/lib/temporalio/api/testservice/v1/service.rb +1 -1
  63. data/lib/temporalio/api/update/v1/message.rb +1 -1
  64. data/lib/temporalio/api/version/v1/message.rb +1 -1
  65. data/lib/temporalio/api/worker/v1/message.rb +30 -0
  66. data/lib/temporalio/api/workflow/v1/message.rb +22 -2
  67. data/lib/temporalio/api/workflowservice/v1/request_response.rb +58 -12
  68. data/lib/temporalio/api/workflowservice/v1/service.rb +2 -2
  69. data/lib/temporalio/api.rb +1 -0
  70. data/lib/temporalio/client/async_activity_handle.rb +12 -4
  71. data/lib/temporalio/client/connection/cloud_service.rb +60 -0
  72. data/lib/temporalio/client/connection/workflow_service.rb +343 -28
  73. data/lib/temporalio/client/interceptor.rb +64 -7
  74. data/lib/temporalio/client/schedule.rb +35 -3
  75. data/lib/temporalio/client/with_start_workflow_operation.rb +123 -0
  76. data/lib/temporalio/client/workflow_execution.rb +19 -0
  77. data/lib/temporalio/client/workflow_handle.rb +47 -7
  78. data/lib/temporalio/client/workflow_update_handle.rb +9 -3
  79. data/lib/temporalio/client.rb +231 -4
  80. data/lib/temporalio/common_enums.rb +14 -0
  81. data/lib/temporalio/contrib/open_telemetry.rb +474 -0
  82. data/lib/temporalio/converters/data_converter.rb +18 -8
  83. data/lib/temporalio/converters/failure_converter.rb +6 -3
  84. data/lib/temporalio/converters/payload_converter/binary_null.rb +2 -2
  85. data/lib/temporalio/converters/payload_converter/binary_plain.rb +2 -2
  86. data/lib/temporalio/converters/payload_converter/binary_protobuf.rb +2 -2
  87. data/lib/temporalio/converters/payload_converter/composite.rb +6 -4
  88. data/lib/temporalio/converters/payload_converter/encoding.rb +4 -2
  89. data/lib/temporalio/converters/payload_converter/json_plain.rb +2 -2
  90. data/lib/temporalio/converters/payload_converter/json_protobuf.rb +2 -2
  91. data/lib/temporalio/converters/payload_converter.rb +16 -6
  92. data/lib/temporalio/error/failure.rb +19 -1
  93. data/lib/temporalio/error.rb +2 -1
  94. data/lib/temporalio/internal/bridge/3.2/temporalio_bridge.so +0 -0
  95. data/lib/temporalio/internal/bridge/3.3/temporalio_bridge.so +0 -0
  96. data/lib/temporalio/internal/bridge/3.4/temporalio_bridge.so +0 -0
  97. data/lib/temporalio/internal/bridge/api/activity_result/activity_result.rb +1 -1
  98. data/lib/temporalio/internal/bridge/api/activity_task/activity_task.rb +3 -2
  99. data/lib/temporalio/internal/bridge/api/child_workflow/child_workflow.rb +1 -1
  100. data/lib/temporalio/internal/bridge/api/common/common.rb +3 -2
  101. data/lib/temporalio/internal/bridge/api/core_interface.rb +1 -1
  102. data/lib/temporalio/internal/bridge/api/external_data/external_data.rb +1 -1
  103. data/lib/temporalio/internal/bridge/api/nexus/nexus.rb +3 -2
  104. data/lib/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rb +2 -2
  105. data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +3 -2
  106. data/lib/temporalio/internal/bridge/api/workflow_completion/workflow_completion.rb +3 -2
  107. data/lib/temporalio/internal/bridge/runtime.rb +3 -0
  108. data/lib/temporalio/internal/bridge/testing.rb +3 -0
  109. data/lib/temporalio/internal/bridge/worker.rb +28 -4
  110. data/lib/temporalio/internal/bridge.rb +1 -1
  111. data/lib/temporalio/internal/client/implementation.rb +281 -51
  112. data/lib/temporalio/internal/proto_utils.rb +38 -6
  113. data/lib/temporalio/internal/worker/activity_worker.rb +107 -25
  114. data/lib/temporalio/internal/worker/multi_runner.rb +2 -2
  115. data/lib/temporalio/internal/worker/workflow_instance/child_workflow_handle.rb +8 -6
  116. data/lib/temporalio/internal/worker/workflow_instance/context.rb +96 -5
  117. data/lib/temporalio/internal/worker/workflow_instance/details.rb +7 -2
  118. data/lib/temporalio/internal/worker/workflow_instance/external_workflow_handle.rb +2 -2
  119. data/lib/temporalio/internal/worker/workflow_instance/illegal_call_tracer.rb +64 -18
  120. data/lib/temporalio/internal/worker/workflow_instance/outbound_implementation.rb +39 -40
  121. data/lib/temporalio/internal/worker/workflow_instance/scheduler.rb +22 -2
  122. data/lib/temporalio/internal/worker/workflow_instance.rb +134 -55
  123. data/lib/temporalio/internal/worker/workflow_worker.rb +19 -6
  124. data/lib/temporalio/priority.rb +59 -0
  125. data/lib/temporalio/runtime/metric_buffer.rb +94 -0
  126. data/lib/temporalio/runtime.rb +48 -10
  127. data/lib/temporalio/search_attributes.rb +13 -0
  128. data/lib/temporalio/testing/activity_environment.rb +49 -10
  129. data/lib/temporalio/testing/workflow_environment.rb +29 -6
  130. data/lib/temporalio/version.rb +1 -1
  131. data/lib/temporalio/versioning_override.rb +56 -0
  132. data/lib/temporalio/worker/deployment_options.rb +45 -0
  133. data/lib/temporalio/worker/illegal_workflow_call_validator.rb +64 -0
  134. data/lib/temporalio/worker/interceptor.rb +16 -1
  135. data/lib/temporalio/worker/poller_behavior.rb +61 -0
  136. data/lib/temporalio/worker/thread_pool.rb +6 -6
  137. data/lib/temporalio/worker/workflow_executor/thread_pool.rb +9 -3
  138. data/lib/temporalio/worker/workflow_replayer.rb +19 -13
  139. data/lib/temporalio/worker.rb +97 -27
  140. data/lib/temporalio/worker_deployment_version.rb +67 -0
  141. data/lib/temporalio/workflow/child_workflow_handle.rb +10 -2
  142. data/lib/temporalio/workflow/definition.rb +217 -35
  143. data/lib/temporalio/workflow/external_workflow_handle.rb +3 -1
  144. data/lib/temporalio/workflow/future.rb +2 -2
  145. data/lib/temporalio/workflow/info.rb +26 -1
  146. data/lib/temporalio/workflow.rb +113 -15
  147. data/lib/temporalio.rb +1 -0
  148. data/temporalio.gemspec +3 -1
  149. metadata +33 -4
@@ -4,6 +4,7 @@ require 'temporalio/internal/bridge'
4
4
  require 'temporalio/internal/bridge/runtime'
5
5
  require 'temporalio/internal/metric'
6
6
  require 'temporalio/metric'
7
+ require 'temporalio/runtime/metric_buffer'
7
8
 
8
9
  module Temporalio
9
10
  # Runtime for Temporal Ruby SDK.
@@ -107,6 +108,7 @@ module Temporalio
107
108
  MetricsOptions = Data.define(
108
109
  :opentelemetry,
109
110
  :prometheus,
111
+ :buffer,
110
112
  :attach_service_name,
111
113
  :global_tags,
112
114
  :metric_prefix
@@ -116,10 +118,13 @@ module Temporalio
116
118
  #
117
119
  # @!attribute opentelemetry
118
120
  # @return [OpenTelemetryMetricsOptions, nil] OpenTelemetry options if using OpenTelemetry. This is mutually
119
- # exclusive with +prometheus+.
121
+ # exclusive with `prometheus` and `buffer`.
120
122
  # @!attribute prometheus
121
123
  # @return [PrometheusMetricsOptions, nil] Prometheus options if using Prometheus. This is mutually exclusive with
122
- # +opentelemetry+.
124
+ # `opentelemetry` and `buffer`.
125
+ # @!attribute buffer
126
+ # @return [MetricBuffer, nil] Metric buffer to send all metrics to. This is mutually exclusive with `prometheus`
127
+ # and `opentelemetry`.
123
128
  # @!attribute attach_service_name
124
129
  # @return [Boolean] Whether to put the service_name on every metric.
125
130
  # @!attribute global_tags
@@ -130,19 +135,26 @@ module Temporalio
130
135
  # Create metrics options. Either `opentelemetry` or `prometheus` required, but not both.
131
136
  #
132
137
  # @param opentelemetry [OpenTelemetryMetricsOptions, nil] OpenTelemetry options if using OpenTelemetry. This is
133
- # mutually exclusive with `prometheus`.
138
+ # mutually exclusive with `prometheus` and `buffer`.
134
139
  # @param prometheus [PrometheusMetricsOptions, nil] Prometheus options if using Prometheus. This is mutually
135
- # exclusive with `opentelemetry`.
140
+ # exclusive with `opentelemetry` and `buffer`.
141
+ # @param buffer [MetricBuffer, nil] Metric buffer to send all metrics to. This is mutually exclusive with
142
+ # `prometheus` and `opentelemetry`.
136
143
  # @param attach_service_name [Boolean] Whether to put the service_name on every metric.
137
144
  # @param global_tags [Hash<String, String>, nil] Resource tags to be applied to all metrics.
138
145
  # @param metric_prefix [String, nil] Prefix to put on every Temporal metric. If unset, defaults to `temporal_`.
139
146
  def initialize(
140
147
  opentelemetry: nil,
141
148
  prometheus: nil,
149
+ buffer: nil,
142
150
  attach_service_name: true,
143
151
  global_tags: nil,
144
152
  metric_prefix: nil
145
153
  )
154
+ if [opentelemetry, prometheus, buffer].count { |v| !v.nil? } > 1
155
+ raise 'Can only have one of opentelemetry, prometheus, or buffer'
156
+ end
157
+
146
158
  super
147
159
  end
148
160
 
@@ -152,6 +164,7 @@ module Temporalio
152
164
  Internal::Bridge::Runtime::MetricsOptions.new(
153
165
  opentelemetry: opentelemetry&._to_bridge,
154
166
  prometheus: prometheus&._to_bridge,
167
+ buffered_with_size: buffer&._buffer_size,
155
168
  attach_service_name:,
156
169
  global_tags:,
157
170
  metric_prefix:
@@ -164,7 +177,9 @@ module Temporalio
164
177
  :headers,
165
178
  :metric_periodicity,
166
179
  :metric_temporality,
167
- :durations_as_seconds
180
+ :durations_as_seconds,
181
+ :http,
182
+ :histogram_bucket_overrides
168
183
  )
169
184
 
170
185
  # Options for exporting metrics to OpenTelemetry.
@@ -181,6 +196,11 @@ module Temporalio
181
196
  # @!attribute durations_as_seconds
182
197
  # @return [Boolean] Whether to use float seconds instead of integer milliseconds for durations, default is
183
198
  # +false+.
199
+ # @!attribute http
200
+ # @return [Boolean] True if the protocol is HTTP, false if gRPC (the default).
201
+ # @!attribute histogram_bucket_overrides
202
+ # @return [Hash<String, Array<Numeric>>, nil] Override default histogram buckets. Key of the hash it the metric
203
+ # name, value is an array of floats for the set of buckets.
184
204
  class OpenTelemetryMetricsOptions
185
205
  # OpenTelemetry metric temporality.
186
206
  module MetricTemporality
@@ -196,12 +216,17 @@ module Temporalio
196
216
  # @param metric_temporality [MetricTemporality] How frequently metrics should be exported.
197
217
  # @param durations_as_seconds [Boolean] Whether to use float seconds instead of integer milliseconds for
198
218
  # durations.
219
+ # @param http [Boolean] True if the protocol is HTTP, false if gRPC (the default).
220
+ # @param histogram_bucket_overrides [Hash<String, Array<Numeric>>, nil] Override default histogram buckets. Key of
221
+ # the hash it the metric name, value is an array of floats for the set of buckets.
199
222
  def initialize(
200
223
  url:,
201
224
  headers: nil,
202
225
  metric_periodicity: nil,
203
226
  metric_temporality: MetricTemporality::CUMULATIVE,
204
- durations_as_seconds: false
227
+ durations_as_seconds: false,
228
+ http: false,
229
+ histogram_bucket_overrides: nil
205
230
  )
206
231
  super
207
232
  end
@@ -218,7 +243,9 @@ module Temporalio
218
243
  when MetricTemporality::DELTA then true
219
244
  else raise 'Unrecognized metric temporality'
220
245
  end,
221
- durations_as_seconds:
246
+ durations_as_seconds:,
247
+ http:,
248
+ histogram_bucket_overrides:
222
249
  )
223
250
  end
224
251
  end
@@ -227,7 +254,8 @@ module Temporalio
227
254
  :bind_address,
228
255
  :counters_total_suffix,
229
256
  :unit_suffix,
230
- :durations_as_seconds
257
+ :durations_as_seconds,
258
+ :histogram_bucket_overrides
231
259
  )
232
260
 
233
261
  # Options for exporting metrics to Prometheus.
@@ -240,6 +268,9 @@ module Temporalio
240
268
  # @return [Boolean] If `true`, all histograms will include the unit in their name as a suffix.
241
269
  # @!attribute durations_as_seconds
242
270
  # @return [Boolean] Whether to use float seconds instead of integer milliseconds for durations.
271
+ # @!attribute histogram_bucket_overrides
272
+ # @return [Hash<String, Array<Numeric>>, nil] Override default histogram buckets. Key of the hash it the metric
273
+ # name, value is an array of floats for the set of buckets.
243
274
  class PrometheusMetricsOptions
244
275
  # Create Prometheus options.
245
276
  #
@@ -248,11 +279,14 @@ module Temporalio
248
279
  # @param unit_suffix [Boolean] If `true`, all histograms will include the unit in their name as a suffix.
249
280
  # @param durations_as_seconds [Boolean] Whether to use float seconds instead of integer milliseconds for
250
281
  # durations.
282
+ # @param histogram_bucket_overrides [Hash<String, Array<Numeric>>, nil] Override default histogram buckets. Key of
283
+ # the hash it the metric name, value is an array of floats for the set of buckets.
251
284
  def initialize(
252
285
  bind_address:,
253
286
  counters_total_suffix: false,
254
287
  unit_suffix: false,
255
- durations_as_seconds: false
288
+ durations_as_seconds: false,
289
+ histogram_bucket_overrides: nil
256
290
  )
257
291
  super
258
292
  end
@@ -264,7 +298,8 @@ module Temporalio
264
298
  bind_address:,
265
299
  counters_total_suffix:,
266
300
  unit_suffix:,
267
- durations_as_seconds:
301
+ durations_as_seconds:,
302
+ histogram_bucket_overrides:
268
303
  )
269
304
  end
270
305
  end
@@ -295,6 +330,9 @@ module Temporalio
295
330
  #
296
331
  # @param telemetry [TelemetryOptions] Telemetry options to set.
297
332
  def initialize(telemetry: TelemetryOptions.new)
333
+ # Set runtime on the buffer which will fail if the buffer is used on another runtime
334
+ telemetry.metrics&.buffer&._set_runtime(self)
335
+
298
336
  @core_runtime = Internal::Bridge::Runtime.new(
299
337
  Internal::Bridge::Runtime::Options.new(telemetry: telemetry._to_bridge)
300
338
  )
@@ -251,6 +251,14 @@ module Temporalio
251
251
  @raw_hash.length
252
252
  end
253
253
 
254
+ # Check equality.
255
+ #
256
+ # @param other [SearchAttributes] To compare.
257
+ # @return [Boolean] Whether equal.
258
+ def ==(other)
259
+ other.is_a?(SearchAttributes) && @raw_hash == other._raw_hash
260
+ end
261
+
254
262
  alias size length
255
263
 
256
264
  # Return a new search attributes collection with updates applied.
@@ -280,6 +288,11 @@ module Temporalio
280
288
  end
281
289
  end
282
290
 
291
+ # @!visibility private
292
+ def _raw_hash
293
+ @raw_hash
294
+ end
295
+
283
296
  # @!visibility private
284
297
  def _to_proto
285
298
  Api::Common::V1::SearchAttributes.new(indexed_fields: _to_proto_hash)
@@ -13,17 +13,18 @@ module Temporalio
13
13
  # cancellation can be set, users create this for each activity that is run. There is no real performance penalty for
14
14
  # creating an environment for every run.
15
15
  class ActivityEnvironment
16
- # @return [Activity::Info] The activity info used by default. This is frozen, but can be dup'd and mutated to pass
17
- # in to {initialize}.
16
+ # @return [Activity::Info] The activity info used by default. This is frozen, but `with` can be used to make a new
17
+ # instance with changes to pass in to {initialize}.
18
18
  def self.default_info
19
19
  @default_info ||= Activity::Info.new(
20
20
  activity_id: 'test',
21
21
  activity_type: 'unknown',
22
22
  attempt: 1,
23
23
  current_attempt_scheduled_time: Time.at(0),
24
- heartbeat_details: [],
25
24
  heartbeat_timeout: nil,
26
25
  local?: false,
26
+ priority: Temporalio::Priority.default,
27
+ raw_heartbeat_details: [],
27
28
  schedule_to_close_timeout: 1.0,
28
29
  scheduled_time: Time.at(0),
29
30
  start_to_close_timeout: 1.0,
@@ -34,35 +35,49 @@ module Temporalio
34
35
  workflow_namespace: 'default',
35
36
  workflow_run_id: 'test-run',
36
37
  workflow_type: 'test'
37
- ).freeze
38
+ )
38
39
  end
39
40
 
40
41
  # Create a test environment for activities.
41
42
  #
42
- # @param info [Activity::Info] Value for {Activity::Context#info}.
43
+ # @param info [Activity::Info] Value for {Activity::Context#info}. Users should not try to instantiate this
44
+ # themselves, but rather use `with` on {default_info}.
43
45
  # @param on_heartbeat [Proc(Array), nil] Proc that is called with all heartbeat details when
44
- # {Activity::Context#heartbeat} is called.
46
+ # {Activity::Context#heartbeat} is called. Should return a value
45
47
  # @param cancellation [Cancellation] Value for {Activity::Context#cancellation}.
48
+ # @param on_cancellation_details [Proc, nil] Proc that is called when {Activity::Context#cancellation_details} is
49
+ # called. Defaults to a proc that returns an instance if canceled with `cancel_requested` as true.
46
50
  # @param worker_shutdown_cancellation [Cancellation] Value for {Activity::Context#worker_shutdown_cancellation}.
47
51
  # @param payload_converter [Converters::PayloadConverter] Value for {Activity::Context#payload_converter}.
48
52
  # @param logger [Logger] Value for {Activity::Context#logger}.
49
53
  # @param activity_executors [Hash<Symbol, Worker::ActivityExecutor>] Executors that activities can run within.
54
+ # @param metric_meter [Metric::Meter, nil] Value for {Activity::Context#metric_meter}, or nil to raise when
55
+ # called.
56
+ # @param client [Client, nil] Value for {Activity::Context#client}, or nil to raise when called.
50
57
  def initialize(
51
58
  info: ActivityEnvironment.default_info,
52
59
  on_heartbeat: nil,
53
60
  cancellation: Cancellation.new,
61
+ on_cancellation_details: nil,
54
62
  worker_shutdown_cancellation: Cancellation.new,
55
63
  payload_converter: Converters::PayloadConverter.default,
56
64
  logger: Logger.new(nil),
57
- activity_executors: Worker::ActivityExecutor.defaults
65
+ activity_executors: Worker::ActivityExecutor.defaults,
66
+ metric_meter: nil,
67
+ client: nil
58
68
  )
59
69
  @info = info
60
70
  @on_heartbeat = on_heartbeat
61
71
  @cancellation = cancellation
72
+ @on_cancellation_details = on_cancellation_details || proc do
73
+ @_cancellation_details ||= Activity::CancellationDetails.new if @cancellation.canceled?
74
+ end
62
75
  @worker_shutdown_cancellation = worker_shutdown_cancellation
63
76
  @payload_converter = payload_converter
64
77
  @logger = logger
65
78
  @activity_executors = activity_executors
79
+ @metric_meter = metric_meter
80
+ @client = client
66
81
  end
67
82
 
68
83
  # Run an activity and returns its result or raises its exception.
@@ -84,12 +99,15 @@ module Temporalio
84
99
  defn.instance.is_a?(Proc) ? defn.instance.call : defn.instance,
85
100
  on_heartbeat: @on_heartbeat,
86
101
  cancellation: @cancellation,
102
+ on_cancellation_details: @on_cancellation_details,
87
103
  worker_shutdown_cancellation: @worker_shutdown_cancellation,
88
104
  payload_converter: @payload_converter,
89
- logger: @logger
105
+ logger: @logger,
106
+ metric_meter: @metric_meter,
107
+ client: @client
90
108
  ))
91
109
  queue.push([defn.proc.call(*args), nil])
92
- rescue Exception => e # rubocop:disable Lint/RescueException Intentionally capturing all exceptions
110
+ rescue Exception => e # rubocop:disable Lint/RescueException -- Intentionally capturing all exceptions
93
111
  queue.push([nil, e])
94
112
  ensure
95
113
  executor.set_activity_context(defn, nil)
@@ -111,23 +129,44 @@ module Temporalio
111
129
  instance:,
112
130
  on_heartbeat:,
113
131
  cancellation:,
132
+ on_cancellation_details:,
114
133
  worker_shutdown_cancellation:,
115
134
  payload_converter:,
116
- logger:
135
+ logger:,
136
+ metric_meter:,
137
+ client:
117
138
  )
118
139
  @info = info
119
140
  @instance = instance
120
141
  @on_heartbeat = on_heartbeat
121
142
  @cancellation = cancellation
143
+ @on_cancellation_details = on_cancellation_details
122
144
  @worker_shutdown_cancellation = worker_shutdown_cancellation
123
145
  @payload_converter = payload_converter
124
146
  @logger = logger
147
+ @metric_meter = metric_meter
148
+ @client = client
125
149
  end
126
150
 
127
151
  # @!visibility private
128
152
  def heartbeat(*details)
129
153
  @on_heartbeat&.call(details)
130
154
  end
155
+
156
+ # @!visibility private
157
+ def metric_meter
158
+ @metric_meter or raise 'No metric meter configured in this test environment'
159
+ end
160
+
161
+ # @!visibility private
162
+ def client
163
+ @client or raise 'No client configured in this test environment'
164
+ end
165
+
166
+ # @!visibility private
167
+ def cancellation_details
168
+ @on_cancellation_details.call
169
+ end
131
170
  end
132
171
 
133
172
  private_constant :Context
@@ -10,6 +10,7 @@ require 'temporalio/converters'
10
10
  require 'temporalio/internal/bridge/testing'
11
11
  require 'temporalio/internal/proto_utils'
12
12
  require 'temporalio/runtime'
13
+ require 'temporalio/search_attributes'
13
14
  require 'temporalio/version'
14
15
 
15
16
  module Temporalio
@@ -34,8 +35,10 @@ module Temporalio
34
35
  # @param default_workflow_query_reject_condition [WorkflowQueryRejectCondition, nil] Default rejection condition
35
36
  # for the client.
36
37
  # @param ip [String] IP to bind to.
37
- # @param port [Integer, nil] Port to bind on, or +nil+ for random.
38
+ # @param port [Integer, nil] Port to bind on, or `nil` for random.
38
39
  # @param ui [Boolean] If +true+, also starts the UI.
40
+ # @param ui_port [Integer, nil] Port to bind on if `ui` is true, or `nil` for random.
41
+ # @param search_attributes [Array<SearchAttributes::Key>] Search attributes to make available on start.
39
42
  # @param runtime [Runtime] Runtime for the server and client.
40
43
  # @param dev_server_existing_path [String, nil] Existing CLI path to use instead of downloading and caching to
41
44
  # tmp.
@@ -46,6 +49,8 @@ module Temporalio
46
49
  # @param dev_server_download_version [String] Version of dev server to download and cache.
47
50
  # @param dev_server_download_dest_dir [String, nil] Where to download. Defaults to tmp.
48
51
  # @param dev_server_extra_args [Array<String>] Any extra arguments for the CLI dev server.
52
+ # @param dev_server_download_ttl [Float, nil] How long the automatic download should be cached for. If nil, cached
53
+ # indefinitely.
49
54
  #
50
55
  # @yield [environment] If a block is given, it is called with the environment and upon complete the environment is
51
56
  # shutdown.
@@ -62,6 +67,8 @@ module Temporalio
62
67
  ip: '127.0.0.1',
63
68
  port: nil,
64
69
  ui: false, # rubocop:disable Naming/MethodParameterName
70
+ ui_port: nil,
71
+ search_attributes: [],
65
72
  runtime: Runtime.default,
66
73
  dev_server_existing_path: nil,
67
74
  dev_server_database_filename: nil,
@@ -70,8 +77,18 @@ module Temporalio
70
77
  dev_server_download_version: 'default',
71
78
  dev_server_download_dest_dir: nil,
72
79
  dev_server_extra_args: [],
80
+ dev_server_download_ttl: nil,
73
81
  &
74
82
  )
83
+ # Add search attribute args
84
+ unless search_attributes.empty?
85
+ dev_server_extra_args += search_attributes.flat_map do |key|
86
+ raise 'Search attribute must be Key' unless key.is_a?(SearchAttributes::Key)
87
+
88
+ ['--search-attribute', "#{key.name}=#{SearchAttributes::IndexedValueType::PROTO_NAMES[key.type]}"]
89
+ end
90
+ end
91
+
75
92
  server_options = Internal::Bridge::Testing::EphemeralServer::StartDevServerOptions.new(
76
93
  existing_path: dev_server_existing_path,
77
94
  sdk_name: 'sdk-ruby',
@@ -83,9 +100,11 @@ module Temporalio
83
100
  port:,
84
101
  database_filename: dev_server_database_filename,
85
102
  ui:,
103
+ ui_port: ui ? ui_port : nil,
86
104
  log_format: dev_server_log_format,
87
105
  log_level: dev_server_log_level,
88
- extra_args: dev_server_extra_args
106
+ extra_args: dev_server_extra_args,
107
+ download_ttl: dev_server_download_ttl
89
108
  )
90
109
  _with_core_server(
91
110
  core_server: Internal::Bridge::Testing::EphemeralServer.start_dev_server(
@@ -122,6 +141,8 @@ module Temporalio
122
141
  # @param test_server_download_version [String] Version of test server to download and cache.
123
142
  # @param test_server_download_dest_dir [String, nil] Where to download. Defaults to tmp.
124
143
  # @param test_server_extra_args [Array<String>] Any extra arguments for the test server.
144
+ # @param test_server_download_ttl [Float, nil] How long the automatic download should be cached for. If nil,
145
+ # cached indefinitely.
125
146
  #
126
147
  # @yield [environment] If a block is given, it is called with the environment and upon complete the environment is
127
148
  # shutdown.
@@ -140,6 +161,7 @@ module Temporalio
140
161
  test_server_download_version: 'default',
141
162
  test_server_download_dest_dir: nil,
142
163
  test_server_extra_args: [],
164
+ test_server_download_ttl: nil,
143
165
  &
144
166
  )
145
167
  server_options = Internal::Bridge::Testing::EphemeralServer::StartTestServerOptions.new(
@@ -149,7 +171,8 @@ module Temporalio
149
171
  download_version: test_server_download_version,
150
172
  download_dest_dir: test_server_download_dest_dir,
151
173
  port:,
152
- extra_args: test_server_extra_args
174
+ extra_args: test_server_extra_args,
175
+ download_ttl: test_server_download_ttl
153
176
  )
154
177
  _with_core_server(
155
178
  core_server: Internal::Bridge::Testing::EphemeralServer.start_test_server(
@@ -299,7 +322,7 @@ module Temporalio
299
322
  raise 'Block required' unless block_given?
300
323
  return super unless supports_time_skipping?
301
324
 
302
- already_disabled = @auto_time_skipping
325
+ already_disabled = !@auto_time_skipping
303
326
  @auto_time_skipping = false
304
327
  begin
305
328
  yield
@@ -371,8 +394,8 @@ module Temporalio
371
394
  end
372
395
 
373
396
  # @!visibility private
374
- def result(follow_runs: true, rpc_options: nil)
375
- @env.time_skipping_unlocked { super(follow_runs:, rpc_options:) }
397
+ def result(follow_runs: true, result_hint: nil, rpc_options: nil)
398
+ @env.time_skipping_unlocked { super(follow_runs:, result_hint:, rpc_options:) }
376
399
  end
377
400
  end
378
401
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Temporalio
4
- VERSION = '0.3.0'
4
+ VERSION = '0.5.0'
5
5
  end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'temporalio/worker_deployment_version'
4
+
5
+ module Temporalio
6
+ # Base class for version overrides that can be provided in start workflow options.
7
+ # Used to control the versioning behavior of workflows started with this override.
8
+ #
9
+ # WARNING: Experimental API.
10
+ class VersioningOverride
11
+ # @!visibility private
12
+ def _to_proto
13
+ raise NotImplementedError, 'Subclasses must implement this method'
14
+ end
15
+
16
+ # Represents a versioning override to pin a workflow to a specific version
17
+ class Pinned < VersioningOverride
18
+ # The worker deployment version to pin to
19
+ # @return [WorkerDeploymentVersion]
20
+ attr_reader :version
21
+
22
+ # Create a new pinned versioning override
23
+ #
24
+ # @param version [WorkerDeploymentVersion] The worker deployment version to pin to
25
+ def initialize(version)
26
+ @version = version
27
+ super()
28
+ end
29
+
30
+ # TODO: Remove deprecated field setting once removed from server
31
+
32
+ # @!visibility private
33
+ def _to_proto
34
+ Api::Workflow::V1::VersioningOverride.new(
35
+ behavior: Api::Enums::V1::VersioningBehavior::VERSIONING_BEHAVIOR_PINNED,
36
+ pinned_version: @version.to_canonical_string,
37
+ pinned: Api::Workflow::V1::VersioningOverride::PinnedOverride.new(
38
+ behavior: Api::Workflow::V1::VersioningOverride::PinnedOverrideBehavior::PINNED_OVERRIDE_BEHAVIOR_PINNED,
39
+ version: @version._to_proto
40
+ )
41
+ )
42
+ end
43
+ end
44
+
45
+ # Represents a versioning override to auto-upgrade a workflow
46
+ class AutoUpgrade < VersioningOverride
47
+ # @!visibility private
48
+ def _to_proto
49
+ Api::Workflow::V1::VersioningOverride.new(
50
+ behavior: Api::Enums::V1::VersioningBehavior::VERSIONING_BEHAVIOR_AUTO_UPGRADE,
51
+ auto_upgrade: true
52
+ )
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'temporalio/common_enums'
4
+ require 'temporalio/worker_deployment_version'
5
+
6
+ module Temporalio
7
+ class Worker
8
+ DeploymentOptions = Data.define(
9
+ :version,
10
+ :use_worker_versioning,
11
+ :default_versioning_behavior
12
+ )
13
+
14
+ # Options for configuring the Worker Versioning feature.
15
+ #
16
+ # WARNING: Deployment-based versioning is experimental and APIs may change.
17
+ #
18
+ # @!attribute version
19
+ # @return [WorkerDeploymentVersion] The worker deployment version.
20
+ # @!attribute use_worker_versioning
21
+ # @return [Boolean] Whether worker versioning is enabled.
22
+ # @!attribute default_versioning_behavior
23
+ # @return [VersioningBehavior] The default versioning behavior.
24
+ class DeploymentOptions
25
+ def initialize(
26
+ version:,
27
+ use_worker_versioning: false,
28
+ default_versioning_behavior: VersioningBehavior::UNSPECIFIED
29
+ )
30
+ super
31
+ end
32
+
33
+ # @!visibility private
34
+ def _to_bridge_options
35
+ Internal::Bridge::Worker::DeploymentOptions.new(
36
+ version: Internal::Bridge::Worker::WorkerDeploymentVersion.new(
37
+ deployment_name: version.deployment_name, build_id: version.build_id
38
+ ),
39
+ use_worker_versioning: use_worker_versioning,
40
+ default_versioning_behavior: default_versioning_behavior
41
+ )
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Temporalio
4
+ class Worker
5
+ # Custom validator for validating illegal workflow calls.
6
+ class IllegalWorkflowCallValidator
7
+ CallInfo = Data.define(
8
+ :class_name,
9
+ :method_name,
10
+ :trace_point
11
+ )
12
+
13
+ # Call info passed to the validation block for each validation.
14
+ #
15
+ # @!attribute class_name
16
+ # @return [String] Class name the method is on.
17
+ # @!attribute method_name
18
+ # @return [String] Method name being called.
19
+ # @!attribute trace_point
20
+ # @return [TracePoint] TracePoint instance for the call.
21
+ class CallInfo; end # rubocop:disable Lint/EmptyClass
22
+
23
+ # @return [Array<IllegalWorkflowCallValidator>] Set of advanced validators for Time calls.
24
+ def self.default_time_validators
25
+ @default_time_validators ||= [
26
+ # Do not consider initialize as invalid if year is present and not "true"
27
+ IllegalWorkflowCallValidator.new(method_name: :initialize) do |info|
28
+ year_val = info.trace_point.binding&.local_variable_get(:year)
29
+ raise 'can only use if passing string or explicit time info' unless year_val && year_val != true
30
+ end,
31
+ IllegalWorkflowCallValidator.new(method_name: :now) do
32
+ # When the xmlschema (aliased as iso8601) call is made, zone_offset is called which has a default parameter
33
+ # of Time.now.year. We want to prevent failing in that specific case. It is expensive to access the caller
34
+ # stack, but this is only done in the rare case they are calling this safely.
35
+ next if caller_locations&.any? { |loc| loc.label == 'zone_offset' || loc.label == 'Time.zone_offset' }
36
+
37
+ raise 'Invalid Time.now call'
38
+ end
39
+ ]
40
+ end
41
+
42
+ # @return [String, nil] Method name if this validator is specific to a method.
43
+ attr_reader :method_name
44
+
45
+ # @return [Proc] Block provided in constructor to invoke. See constructor for more details.
46
+ attr_reader :block
47
+
48
+ # Create a call validator.
49
+ #
50
+ # @param method_name [String, nil] Method name to check. This must be provided if the validator is in an illegal
51
+ # call array, this cannot be provided if it is a top-level class validator.
52
+ # @yield Required block that is called each time validation is needed. If the call raises, the exception message
53
+ # is used as the reason why the call is considered invalid. Return value is ignored.
54
+ # @yieldparam info [CallInfo] Information about the current call.
55
+ def initialize(method_name: nil, &block)
56
+ raise 'Block required' unless block_given?
57
+ raise TypeError, 'Method name must be Symbol' unless method_name.nil? || method_name.is_a?(Symbol)
58
+
59
+ @method_name = method_name
60
+ @block = block
61
+ end
62
+ end
63
+ end
64
+ end