temporalio 1.2.0 → 1.3.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.
- checksums.yaml +4 -4
- data/Cargo.lock +77 -2
- data/ext/Cargo.toml +4 -0
- data/lib/temporalio/client.rb +0 -2
- data/lib/temporalio/common_enums.rb +0 -2
- data/lib/temporalio/contrib/open_telemetry.rb +21 -0
- data/lib/temporalio/converters/failure_converter.rb +30 -0
- data/lib/temporalio/env_config.rb +1 -3
- data/lib/temporalio/error/failure.rb +66 -0
- data/lib/temporalio/internal/worker/workflow_instance/context.rb +5 -0
- data/lib/temporalio/internal/worker/workflow_instance/nexus_client.rb +42 -0
- data/lib/temporalio/internal/worker/workflow_instance/nexus_operation_handle.rb +51 -0
- data/lib/temporalio/internal/worker/workflow_instance/outbound_implementation.rb +68 -0
- data/lib/temporalio/internal/worker/workflow_instance.rb +11 -0
- data/lib/temporalio/testing/workflow_environment.rb +40 -0
- data/lib/temporalio/version.rb +1 -1
- data/lib/temporalio/versioning_override.rb +0 -2
- data/lib/temporalio/worker/deployment_options.rb +0 -2
- data/lib/temporalio/worker/interceptor.rb +27 -0
- data/lib/temporalio/worker/workflow_executor/thread_pool.rb +1 -1
- data/lib/temporalio/worker.rb +0 -1
- data/lib/temporalio/worker_deployment_version.rb +0 -2
- data/lib/temporalio/workflow/definition.rb +0 -3
- data/lib/temporalio/workflow/nexus_client.rb +81 -0
- data/lib/temporalio/workflow/nexus_operation_cancellation_type.rb +21 -0
- data/lib/temporalio/workflow/nexus_operation_handle.rb +37 -0
- data/lib/temporalio/workflow.rb +14 -0
- metadata +6 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 402b9eb0039d985a8e98f5cebfcae841af4483c06d070a76f9f3b213b4853049
|
|
4
|
+
data.tar.gz: 2d2d14d2e8d13d825db718267ea086fedefc5562843e1eb584bbd20b2cf02c90
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 90dda134d91f20010315e248caf76065f21c4d806219612b14e20823ed947480129aea0098c602d6b639ecc296e9a22c0694fae484b46aad630432307c4c0cc6
|
|
7
|
+
data.tar.gz: f64e68cb9b0a58be826314ea1a40dff5bd86ea5b230eebea5ba129a9f6100b72ce454247b314781c2541b784ac4141681f0a2da3f03406996c5c030426aa1c61
|
data/Cargo.lock
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
# It is not intended for manual editing.
|
|
3
3
|
version = 4
|
|
4
4
|
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "addr2line"
|
|
7
|
+
version = "0.25.1"
|
|
8
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
9
|
+
checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"gimli",
|
|
12
|
+
]
|
|
13
|
+
|
|
5
14
|
[[package]]
|
|
6
15
|
name = "adler2"
|
|
7
16
|
version = "2.0.1"
|
|
@@ -262,6 +271,21 @@ dependencies = [
|
|
|
262
271
|
"rand 0.8.5",
|
|
263
272
|
]
|
|
264
273
|
|
|
274
|
+
[[package]]
|
|
275
|
+
name = "backtrace"
|
|
276
|
+
version = "0.3.76"
|
|
277
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
278
|
+
checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6"
|
|
279
|
+
dependencies = [
|
|
280
|
+
"addr2line",
|
|
281
|
+
"cfg-if",
|
|
282
|
+
"libc",
|
|
283
|
+
"miniz_oxide",
|
|
284
|
+
"object",
|
|
285
|
+
"rustc-demangle",
|
|
286
|
+
"windows-link 0.2.1",
|
|
287
|
+
]
|
|
288
|
+
|
|
265
289
|
[[package]]
|
|
266
290
|
name = "base64"
|
|
267
291
|
version = "0.21.7"
|
|
@@ -345,9 +369,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
|
|
345
369
|
|
|
346
370
|
[[package]]
|
|
347
371
|
name = "bytes"
|
|
348
|
-
version = "1.11.
|
|
372
|
+
version = "1.11.1"
|
|
349
373
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
350
|
-
checksum = "
|
|
374
|
+
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
|
|
351
375
|
|
|
352
376
|
[[package]]
|
|
353
377
|
name = "bzip2"
|
|
@@ -730,6 +754,22 @@ dependencies = [
|
|
|
730
754
|
"unicode-xid",
|
|
731
755
|
]
|
|
732
756
|
|
|
757
|
+
[[package]]
|
|
758
|
+
name = "dhat"
|
|
759
|
+
version = "0.3.3"
|
|
760
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
761
|
+
checksum = "98cd11d84628e233de0ce467de10b8633f4ddaecafadefc86e13b84b8739b827"
|
|
762
|
+
dependencies = [
|
|
763
|
+
"backtrace",
|
|
764
|
+
"lazy_static",
|
|
765
|
+
"mintex",
|
|
766
|
+
"parking_lot",
|
|
767
|
+
"rustc-hash 1.1.0",
|
|
768
|
+
"serde",
|
|
769
|
+
"serde_json",
|
|
770
|
+
"thousands",
|
|
771
|
+
]
|
|
772
|
+
|
|
733
773
|
[[package]]
|
|
734
774
|
name = "dirs"
|
|
735
775
|
version = "6.0.0"
|
|
@@ -1056,6 +1096,12 @@ dependencies = [
|
|
|
1056
1096
|
"wasm-bindgen",
|
|
1057
1097
|
]
|
|
1058
1098
|
|
|
1099
|
+
[[package]]
|
|
1100
|
+
name = "gimli"
|
|
1101
|
+
version = "0.32.3"
|
|
1102
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1103
|
+
checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7"
|
|
1104
|
+
|
|
1059
1105
|
[[package]]
|
|
1060
1106
|
name = "glob"
|
|
1061
1107
|
version = "0.3.3"
|
|
@@ -1694,6 +1740,12 @@ dependencies = [
|
|
|
1694
1740
|
"simd-adler32",
|
|
1695
1741
|
]
|
|
1696
1742
|
|
|
1743
|
+
[[package]]
|
|
1744
|
+
name = "mintex"
|
|
1745
|
+
version = "0.1.4"
|
|
1746
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1747
|
+
checksum = "c505b3e17ed6b70a7ed2e67fbb2c560ee327353556120d6e72f5232b6880d536"
|
|
1748
|
+
|
|
1697
1749
|
[[package]]
|
|
1698
1750
|
name = "mio"
|
|
1699
1751
|
version = "1.1.1"
|
|
@@ -1799,6 +1851,15 @@ dependencies = [
|
|
|
1799
1851
|
"objc2-core-foundation",
|
|
1800
1852
|
]
|
|
1801
1853
|
|
|
1854
|
+
[[package]]
|
|
1855
|
+
name = "object"
|
|
1856
|
+
version = "0.37.3"
|
|
1857
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1858
|
+
checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe"
|
|
1859
|
+
dependencies = [
|
|
1860
|
+
"memchr",
|
|
1861
|
+
]
|
|
1862
|
+
|
|
1802
1863
|
[[package]]
|
|
1803
1864
|
name = "once_cell"
|
|
1804
1865
|
version = "1.21.3"
|
|
@@ -2656,6 +2717,12 @@ dependencies = [
|
|
|
2656
2717
|
"unicode-ident",
|
|
2657
2718
|
]
|
|
2658
2719
|
|
|
2720
|
+
[[package]]
|
|
2721
|
+
name = "rustc-demangle"
|
|
2722
|
+
version = "0.1.27"
|
|
2723
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2724
|
+
checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d"
|
|
2725
|
+
|
|
2659
2726
|
[[package]]
|
|
2660
2727
|
name = "rustc-hash"
|
|
2661
2728
|
version = "1.1.0"
|
|
@@ -3172,6 +3239,7 @@ dependencies = [
|
|
|
3172
3239
|
"anyhow",
|
|
3173
3240
|
"assert_matches",
|
|
3174
3241
|
"async-trait",
|
|
3242
|
+
"backoff",
|
|
3175
3243
|
"bimap",
|
|
3176
3244
|
"bon",
|
|
3177
3245
|
"bytes",
|
|
@@ -3238,6 +3306,7 @@ name = "temporalio_bridge"
|
|
|
3238
3306
|
version = "0.1.0"
|
|
3239
3307
|
dependencies = [
|
|
3240
3308
|
"async-trait",
|
|
3309
|
+
"dhat",
|
|
3241
3310
|
"futures",
|
|
3242
3311
|
"log",
|
|
3243
3312
|
"magnus",
|
|
@@ -3310,6 +3379,12 @@ dependencies = [
|
|
|
3310
3379
|
"syn",
|
|
3311
3380
|
]
|
|
3312
3381
|
|
|
3382
|
+
[[package]]
|
|
3383
|
+
name = "thousands"
|
|
3384
|
+
version = "0.2.0"
|
|
3385
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3386
|
+
checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820"
|
|
3387
|
+
|
|
3313
3388
|
[[package]]
|
|
3314
3389
|
name = "thread_local"
|
|
3315
3390
|
version = "1.1.9"
|
data/ext/Cargo.toml
CHANGED
data/lib/temporalio/client.rb
CHANGED
|
@@ -298,7 +298,6 @@ module Temporalio
|
|
|
298
298
|
# @param request_eager_start [Boolean] Potentially reduce the latency to start this workflow by encouraging the
|
|
299
299
|
# server to start it on a local worker running with this same client. This is currently experimental.
|
|
300
300
|
# @param versioning_override [VersioningOverride, nil] Override the version of the workflow.
|
|
301
|
-
# This is currently experimental.
|
|
302
301
|
# @param priority [Priority] Priority of the workflow. This is currently experimental.
|
|
303
302
|
# @param arg_hints [Array<Object>, nil] Overrides converter hints for arguments if any. If unset/nil and the
|
|
304
303
|
# workflow definition has arg hints, those are used by default.
|
|
@@ -392,7 +391,6 @@ module Temporalio
|
|
|
392
391
|
# @param request_eager_start [Boolean] Potentially reduce the latency to start this workflow by encouraging the
|
|
393
392
|
# server to start it on a local worker running with this same client. This is currently experimental.
|
|
394
393
|
# @param versioning_override [VersioningOverride, nil] Override the version of the workflow.
|
|
395
|
-
# This is currently experimental.
|
|
396
394
|
# @param priority [Priority] Priority for the workflow. This is currently experimental.
|
|
397
395
|
# @param arg_hints [Array<Object>, nil] Overrides converter hints for arguments if any. If unset/nil and the
|
|
398
396
|
# workflow definition has arg hints, those are used by default.
|
|
@@ -40,8 +40,6 @@ module Temporalio
|
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
# Specifies when a workflow might move from a worker of one Build Id to another.
|
|
43
|
-
#
|
|
44
|
-
# WARNING: Experimental API.
|
|
45
43
|
module VersioningBehavior
|
|
46
44
|
# Unspecified versioning behavior. By default, workers opting into worker versioning will
|
|
47
45
|
# be required to specify a behavior.
|
|
@@ -67,6 +67,11 @@ module Temporalio
|
|
|
67
67
|
headers[@header_key] = carrier unless carrier.empty?
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
+
# @!visibility private
|
|
71
|
+
def _propagator
|
|
72
|
+
@propagator
|
|
73
|
+
end
|
|
74
|
+
|
|
70
75
|
# @!visibility private
|
|
71
76
|
def _attach_context(headers)
|
|
72
77
|
context = _context_from_headers(headers)
|
|
@@ -402,6 +407,22 @@ module Temporalio
|
|
|
402
407
|
super
|
|
403
408
|
end
|
|
404
409
|
|
|
410
|
+
# @!visibility private
|
|
411
|
+
def start_nexus_operation(input)
|
|
412
|
+
# Nexus headers are string-to-string maps (not payload-based like activity/workflow headers)
|
|
413
|
+
# so we inject the tracing context directly into the headers instead of nesting under a key
|
|
414
|
+
span = Workflow.completed_span("StartNexusOperation:#{input.service}/#{input.operation}", kind: :client)
|
|
415
|
+
Temporalio::Workflow::Unsafe.durable_scheduler_disabled do
|
|
416
|
+
if span
|
|
417
|
+
@root._propagator.inject(
|
|
418
|
+
input.headers,
|
|
419
|
+
context: ::OpenTelemetry::Trace.context_with_span(span)
|
|
420
|
+
)
|
|
421
|
+
end
|
|
422
|
+
end
|
|
423
|
+
super
|
|
424
|
+
end
|
|
425
|
+
|
|
405
426
|
# @!visibility private
|
|
406
427
|
def _apply_span_to_headers(headers, span)
|
|
407
428
|
# See WorkflowInbound#_attach_context comments for why we have to disable scheduler even for these simple
|
|
@@ -84,6 +84,18 @@ module Temporalio
|
|
|
84
84
|
started_event_id: error.started_event_id,
|
|
85
85
|
retry_state: error.retry_state
|
|
86
86
|
)
|
|
87
|
+
when Error::NexusOperationError
|
|
88
|
+
failure.nexus_operation_execution_failure_info = Api::Failure::V1::NexusOperationFailureInfo.new(
|
|
89
|
+
endpoint: error.endpoint,
|
|
90
|
+
service: error.service,
|
|
91
|
+
operation: error.operation,
|
|
92
|
+
operation_token: error.operation_token || ''
|
|
93
|
+
)
|
|
94
|
+
when Error::NexusHandlerError
|
|
95
|
+
failure.nexus_handler_failure_info = Api::Failure::V1::NexusHandlerFailureInfo.new(
|
|
96
|
+
type: error.error_type.to_s,
|
|
97
|
+
retry_behavior: error.retry_behavior
|
|
98
|
+
)
|
|
87
99
|
else
|
|
88
100
|
failure.application_failure_info = Api::Failure::V1::ApplicationFailureInfo.new(
|
|
89
101
|
type: error.class.name.to_s.split('::').last
|
|
@@ -190,6 +202,24 @@ module Temporalio
|
|
|
190
202
|
zero_means_nil: true
|
|
191
203
|
)
|
|
192
204
|
)
|
|
205
|
+
elsif failure.nexus_operation_execution_failure_info
|
|
206
|
+
token = failure.nexus_operation_execution_failure_info.operation_token
|
|
207
|
+
Error::NexusOperationError.new(
|
|
208
|
+
Internal::ProtoUtils.string_or(failure.message, 'Nexus operation error'),
|
|
209
|
+
endpoint: failure.nexus_operation_execution_failure_info.endpoint,
|
|
210
|
+
service: failure.nexus_operation_execution_failure_info.service,
|
|
211
|
+
operation: failure.nexus_operation_execution_failure_info.operation,
|
|
212
|
+
operation_token: token.empty? ? nil : token
|
|
213
|
+
)
|
|
214
|
+
elsif failure.nexus_handler_failure_info
|
|
215
|
+
Error::NexusHandlerError.new(
|
|
216
|
+
Internal::ProtoUtils.string_or(failure.message, 'Nexus handler error'),
|
|
217
|
+
error_type: failure.nexus_handler_failure_info.type,
|
|
218
|
+
retry_behavior: Internal::ProtoUtils.enum_to_int(
|
|
219
|
+
Api::Enums::V1::NexusHandlerErrorRetryBehavior,
|
|
220
|
+
failure.nexus_handler_failure_info.retry_behavior
|
|
221
|
+
)
|
|
222
|
+
)
|
|
193
223
|
else
|
|
194
224
|
Error::Failure.new(Internal::ProtoUtils.string_or(failure.message, 'Failure error'))
|
|
195
225
|
end
|
|
@@ -4,9 +4,7 @@ require 'pathname'
|
|
|
4
4
|
require 'temporalio/internal/bridge'
|
|
5
5
|
|
|
6
6
|
module Temporalio
|
|
7
|
-
# Environment and file-based configuration for Temporal clients
|
|
8
|
-
#
|
|
9
|
-
# WARNING: Experimental API.
|
|
7
|
+
# Environment and file-based configuration for Temporal clients.
|
|
10
8
|
module EnvConfig
|
|
11
9
|
# This module provides utilities to load Temporal client configuration from TOML files
|
|
12
10
|
# and environment variables.
|
|
@@ -233,5 +233,71 @@ module Temporalio
|
|
|
233
233
|
@retry_state = retry_state
|
|
234
234
|
end
|
|
235
235
|
end
|
|
236
|
+
|
|
237
|
+
# Error raised on Nexus operation failure.
|
|
238
|
+
#
|
|
239
|
+
# WARNING: Nexus support is experimental.
|
|
240
|
+
class NexusOperationError < Failure
|
|
241
|
+
# @return [String] Nexus endpoint.
|
|
242
|
+
attr_reader :endpoint
|
|
243
|
+
# @return [String] Nexus service.
|
|
244
|
+
attr_reader :service
|
|
245
|
+
# @return [String] Nexus operation.
|
|
246
|
+
attr_reader :operation
|
|
247
|
+
# @return [String, nil] Operation token for async operations.
|
|
248
|
+
attr_reader :operation_token
|
|
249
|
+
|
|
250
|
+
# @!visibility private
|
|
251
|
+
def initialize(
|
|
252
|
+
message,
|
|
253
|
+
endpoint:,
|
|
254
|
+
service:,
|
|
255
|
+
operation:,
|
|
256
|
+
operation_token:
|
|
257
|
+
)
|
|
258
|
+
super(message)
|
|
259
|
+
@endpoint = endpoint
|
|
260
|
+
@service = service
|
|
261
|
+
@operation = operation
|
|
262
|
+
@operation_token = operation_token
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# Error raised from a Nexus handler.
|
|
267
|
+
#
|
|
268
|
+
# WARNING: Nexus support is experimental.
|
|
269
|
+
class NexusHandlerError < Failure
|
|
270
|
+
# @return [Symbol] Error type from the handler.
|
|
271
|
+
attr_reader :error_type
|
|
272
|
+
|
|
273
|
+
# @return [RetryBehavior] Retry behavior for the error.
|
|
274
|
+
attr_reader :retry_behavior
|
|
275
|
+
|
|
276
|
+
# @!visibility private
|
|
277
|
+
def initialize(
|
|
278
|
+
message,
|
|
279
|
+
error_type:,
|
|
280
|
+
retry_behavior:
|
|
281
|
+
)
|
|
282
|
+
super(message)
|
|
283
|
+
@error_type = error_type.to_sym
|
|
284
|
+
@retry_behavior = retry_behavior
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
# Nexus handler error retry behavior.
|
|
288
|
+
module RetryBehavior
|
|
289
|
+
# Unspecified retry behavior.
|
|
290
|
+
UNSPECIFIED =
|
|
291
|
+
Api::Enums::V1::NexusHandlerErrorRetryBehavior::NEXUS_HANDLER_ERROR_RETRY_BEHAVIOR_UNSPECIFIED
|
|
292
|
+
|
|
293
|
+
# Retryable error.
|
|
294
|
+
RETRYABLE =
|
|
295
|
+
Api::Enums::V1::NexusHandlerErrorRetryBehavior::NEXUS_HANDLER_ERROR_RETRY_BEHAVIOR_RETRYABLE
|
|
296
|
+
|
|
297
|
+
# Non-retryable error.
|
|
298
|
+
NON_RETRYABLE =
|
|
299
|
+
Api::Enums::V1::NexusHandlerErrorRetryBehavior::NEXUS_HANDLER_ERROR_RETRY_BEHAVIOR_NON_RETRYABLE
|
|
300
|
+
end
|
|
301
|
+
end
|
|
236
302
|
end
|
|
237
303
|
end
|
|
@@ -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,10 @@ 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
|
+
|
|
35
40
|
def current_details
|
|
36
41
|
@instance.current_details || ''
|
|
37
42
|
end
|
|
@@ -0,0 +1,42 @@
|
|
|
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, cancellation_type: nil, summary: nil,
|
|
21
|
+
cancellation: Workflow.cancellation, arg_hint: nil, result_hint: nil)
|
|
22
|
+
@outbound.start_nexus_operation(
|
|
23
|
+
Temporalio::Worker::Interceptor::Workflow::StartNexusOperationInput.new(
|
|
24
|
+
endpoint: @endpoint,
|
|
25
|
+
service: @service,
|
|
26
|
+
operation: operation.to_s,
|
|
27
|
+
arg:,
|
|
28
|
+
schedule_to_close_timeout:,
|
|
29
|
+
cancellation_type:,
|
|
30
|
+
summary:,
|
|
31
|
+
cancellation:,
|
|
32
|
+
arg_hint:,
|
|
33
|
+
result_hint:,
|
|
34
|
+
headers: {}
|
|
35
|
+
)
|
|
36
|
+
)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
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
|
|
@@ -429,6 +431,72 @@ 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
|
+
nexus_header: input.headers,
|
|
450
|
+
cancellation_type: input.cancellation_type
|
|
451
|
+
),
|
|
452
|
+
user_metadata: ProtoUtils.to_user_metadata(input.summary, nil, @instance.payload_converter)
|
|
453
|
+
)
|
|
454
|
+
)
|
|
455
|
+
|
|
456
|
+
# Set as pending start
|
|
457
|
+
@instance.pending_nexus_operation_starts[seq] = Fiber.current
|
|
458
|
+
|
|
459
|
+
# Register cancel callback
|
|
460
|
+
cancel_callback_key = input.cancellation.add_cancel_callback do
|
|
461
|
+
# Send cancel if in start or pending
|
|
462
|
+
if @instance.pending_nexus_operation_starts.include?(seq) ||
|
|
463
|
+
@instance.pending_nexus_operations.include?(seq)
|
|
464
|
+
@instance.add_command(
|
|
465
|
+
Bridge::Api::WorkflowCommands::WorkflowCommand.new(
|
|
466
|
+
request_cancel_nexus_operation: Bridge::Api::WorkflowCommands::RequestCancelNexusOperation.new(
|
|
467
|
+
seq:
|
|
468
|
+
)
|
|
469
|
+
)
|
|
470
|
+
)
|
|
471
|
+
end
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
# Wait for start resolution
|
|
475
|
+
resolution = begin
|
|
476
|
+
Fiber.yield
|
|
477
|
+
ensure
|
|
478
|
+
# Remove pending start
|
|
479
|
+
@instance.pending_nexus_operation_starts.delete(seq)
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
# Handle start failure
|
|
483
|
+
if resolution.failed
|
|
484
|
+
input.cancellation.remove_cancel_callback(cancel_callback_key)
|
|
485
|
+
raise @instance.failure_converter.from_failure(resolution.failed, @instance.payload_converter)
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
# Create handle and add to pending operations (result will come via resolve_nexus_operation)
|
|
489
|
+
handle = NexusOperationHandle.new(
|
|
490
|
+
operation_token: resolution.operation_token,
|
|
491
|
+
instance: @instance,
|
|
492
|
+
cancellation: input.cancellation,
|
|
493
|
+
cancel_callback_key:,
|
|
494
|
+
result_hint: input.result_hint
|
|
495
|
+
)
|
|
496
|
+
@instance.pending_nexus_operations[seq] = handle
|
|
497
|
+
|
|
498
|
+
handle
|
|
499
|
+
end
|
|
432
500
|
end
|
|
433
501
|
end
|
|
434
502
|
end
|
|
@@ -54,6 +54,7 @@ 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
59
|
:failure_converter, :cancellation, :continue_as_new_suggested, :current_deployment_version,
|
|
59
60
|
:current_history_length, :current_history_size, :replaying, :random,
|
|
@@ -79,6 +80,8 @@ module Temporalio
|
|
|
79
80
|
@pending_timers = {} # Keyed by sequence, value is fiber to resume with proto result
|
|
80
81
|
@pending_child_workflow_starts = {} # Keyed by sequence, value is fiber to resume with proto result
|
|
81
82
|
@pending_child_workflows = {} # Keyed by sequence, value is ChildWorkflowHandle to resolve with proto result
|
|
83
|
+
@pending_nexus_operation_starts = {} # Keyed by sequence, value is fiber to resume with proto result
|
|
84
|
+
@pending_nexus_operations = {} # Keyed by sequence, value is NexusOperationHandle to resolve with proto result
|
|
82
85
|
@pending_external_signals = {} # Keyed by sequence, value is fiber to resume with proto result
|
|
83
86
|
@pending_external_cancels = {} # Keyed by sequence, value is fiber to resume with proto result
|
|
84
87
|
@buffered_signals = {} # Keyed by signal name, value is array of signal jobs
|
|
@@ -369,6 +372,14 @@ module Temporalio
|
|
|
369
372
|
pending_child_workflows[job.resolve_child_workflow_execution.seq]&._resolve(
|
|
370
373
|
job.resolve_child_workflow_execution.result
|
|
371
374
|
)
|
|
375
|
+
when :resolve_nexus_operation_start
|
|
376
|
+
pending_nexus_operation_starts[job.resolve_nexus_operation_start.seq]&.resume(
|
|
377
|
+
job.resolve_nexus_operation_start
|
|
378
|
+
)
|
|
379
|
+
when :resolve_nexus_operation
|
|
380
|
+
pending_nexus_operations[job.resolve_nexus_operation.seq]&._resolve(
|
|
381
|
+
job.resolve_nexus_operation.result
|
|
382
|
+
)
|
|
372
383
|
when :resolve_signal_external_workflow
|
|
373
384
|
pending_external_signals[job.resolve_signal_external_workflow.seq]&.resume(
|
|
374
385
|
job.resolve_signal_external_workflow
|
|
@@ -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
|
#
|
data/lib/temporalio/version.rb
CHANGED
|
@@ -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,23 @@ 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
|
+
:cancellation_type,
|
|
313
|
+
:summary,
|
|
314
|
+
:cancellation,
|
|
315
|
+
:arg_hint,
|
|
316
|
+
:result_hint,
|
|
317
|
+
:headers
|
|
318
|
+
)
|
|
319
|
+
|
|
303
320
|
# Outbound interceptor for intercepting outbound workflow calls. This should be extended by users needing to
|
|
304
321
|
# intercept workflow calls.
|
|
305
322
|
class Outbound
|
|
@@ -371,6 +388,16 @@ module Temporalio
|
|
|
371
388
|
def start_child_workflow(input)
|
|
372
389
|
@next_interceptor.start_child_workflow(input)
|
|
373
390
|
end
|
|
391
|
+
|
|
392
|
+
# Start Nexus operation.
|
|
393
|
+
#
|
|
394
|
+
# WARNING: Nexus support is experimental.
|
|
395
|
+
#
|
|
396
|
+
# @param input [StartNexusOperationInput] Input.
|
|
397
|
+
# @return [Workflow::NexusOperationHandle] Nexus operation handle.
|
|
398
|
+
def start_nexus_operation(input)
|
|
399
|
+
@next_interceptor.start_nexus_operation(input)
|
|
400
|
+
end
|
|
374
401
|
end
|
|
375
402
|
end
|
|
376
403
|
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 <<
|
|
52
|
+
@workers << created_worker
|
|
53
53
|
created_worker
|
|
54
54
|
else
|
|
55
55
|
@workers.min_by(&:workflow_count)
|
data/lib/temporalio/worker.rb
CHANGED
|
@@ -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
|
|
@@ -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.
|
|
@@ -110,8 +110,6 @@ module Temporalio
|
|
|
110
110
|
|
|
111
111
|
# Set the versioning behavior of this workflow.
|
|
112
112
|
#
|
|
113
|
-
# WARNING: This method is experimental and may change in future versions.
|
|
114
|
-
#
|
|
115
113
|
# @param behavior [VersioningBehavior] The versioning behavior.
|
|
116
114
|
def workflow_versioning_behavior(behavior)
|
|
117
115
|
@versioning_behavior = behavior
|
|
@@ -732,7 +730,6 @@ module Temporalio
|
|
|
732
730
|
# @!attribute versioning_behavior
|
|
733
731
|
# Dynamic equivalent of {Definition.workflow_versioning_behavior}.
|
|
734
732
|
# Will override any behavior set there if set.
|
|
735
|
-
# WARNING: Deployment-based versioning is experimental and APIs may change.
|
|
736
733
|
# @return [VersioningBehavior, nil] The versioning behavior
|
|
737
734
|
#
|
|
738
735
|
# @return [VersioningBehavior, nil] The versioning behavior
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Temporalio
|
|
4
|
+
module Workflow
|
|
5
|
+
# Client for executing Nexus operations from workflows.
|
|
6
|
+
#
|
|
7
|
+
# This is created via {Workflow.create_nexus_client}, it is never instantiated directly.
|
|
8
|
+
#
|
|
9
|
+
# WARNING: Nexus support is experimental.
|
|
10
|
+
class NexusClient
|
|
11
|
+
# @!visibility private
|
|
12
|
+
def initialize
|
|
13
|
+
raise NotImplementedError, 'Cannot instantiate a Nexus client directly'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @return [String] Endpoint name for this client.
|
|
17
|
+
def endpoint
|
|
18
|
+
raise NotImplementedError
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @return [String] Service name for this client.
|
|
22
|
+
def service
|
|
23
|
+
raise NotImplementedError
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Start a Nexus operation and return a handle.
|
|
27
|
+
#
|
|
28
|
+
# @param operation [Symbol, String] Operation name.
|
|
29
|
+
# @param arg [Object] Argument for the operation.
|
|
30
|
+
# @param schedule_to_close_timeout [Float, nil] Total timeout for the operation in seconds.
|
|
31
|
+
# @param cancellation_type [NexusOperationCancellationType] How the operation will react to cancellation.
|
|
32
|
+
# @param summary [String, nil] Optional summary for the operation (appears in UI/CLI).
|
|
33
|
+
# @param cancellation [Cancellation] Cancellation for the operation.
|
|
34
|
+
# @param arg_hint [Object, nil] Converter hint for the argument.
|
|
35
|
+
# @param result_hint [Object, nil] Converter hint for the result.
|
|
36
|
+
# @return [NexusOperationHandle] Handle to the started operation.
|
|
37
|
+
def start_operation(
|
|
38
|
+
operation,
|
|
39
|
+
arg,
|
|
40
|
+
schedule_to_close_timeout: nil,
|
|
41
|
+
cancellation_type: NexusOperationCancellationType::WAIT_CANCELLATION_COMPLETED,
|
|
42
|
+
summary: nil,
|
|
43
|
+
cancellation: Workflow.cancellation,
|
|
44
|
+
arg_hint: nil,
|
|
45
|
+
result_hint: nil
|
|
46
|
+
)
|
|
47
|
+
raise NotImplementedError
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Execute a Nexus operation and wait for the result.
|
|
51
|
+
#
|
|
52
|
+
# This is a convenience method that calls {#start_operation} and immediately waits for the result.
|
|
53
|
+
#
|
|
54
|
+
# @param operation [Symbol, String] Operation name.
|
|
55
|
+
# @param arg [Object] Argument for the operation.
|
|
56
|
+
# @param schedule_to_close_timeout [Float, nil] Total timeout for the operation in seconds.
|
|
57
|
+
# @param cancellation_type [NexusOperationCancellationType] How the operation will react to cancellation.
|
|
58
|
+
# @param summary [String, nil] Optional summary for the operation (appears in UI/CLI).
|
|
59
|
+
# @param cancellation [Cancellation] Cancellation for the operation.
|
|
60
|
+
# @param arg_hint [Object, nil] Converter hint for the argument.
|
|
61
|
+
# @param result_hint [Object, nil] Converter hint for the result.
|
|
62
|
+
# @return [Object] Result of the operation.
|
|
63
|
+
# @raise [Error::NexusOperationError] Operation failed.
|
|
64
|
+
def execute_operation(
|
|
65
|
+
operation,
|
|
66
|
+
arg,
|
|
67
|
+
schedule_to_close_timeout: nil,
|
|
68
|
+
cancellation_type: NexusOperationCancellationType::WAIT_CANCELLATION_COMPLETED,
|
|
69
|
+
summary: nil,
|
|
70
|
+
cancellation: Workflow.cancellation,
|
|
71
|
+
arg_hint: nil,
|
|
72
|
+
result_hint: nil
|
|
73
|
+
)
|
|
74
|
+
start_operation(
|
|
75
|
+
operation, arg, schedule_to_close_timeout:, cancellation_type:, summary:, cancellation:,
|
|
76
|
+
arg_hint:, result_hint:
|
|
77
|
+
).result
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'temporalio/internal/bridge/api'
|
|
4
|
+
|
|
5
|
+
module Temporalio
|
|
6
|
+
module Workflow
|
|
7
|
+
# How a Nexus operation should handle cancellation.
|
|
8
|
+
#
|
|
9
|
+
# WARNING: Nexus support is experimental.
|
|
10
|
+
module NexusOperationCancellationType
|
|
11
|
+
# Wait for cancellation to complete (default).
|
|
12
|
+
WAIT_CANCELLATION_COMPLETED = Internal::Bridge::Api::Nexus::NexusOperationCancellationType::WAIT_CANCELLATION_COMPLETED
|
|
13
|
+
# Abandon the operation without sending a cancellation request.
|
|
14
|
+
ABANDON = Internal::Bridge::Api::Nexus::NexusOperationCancellationType::ABANDON
|
|
15
|
+
# Send a cancellation request but do not wait for confirmation.
|
|
16
|
+
TRY_CANCEL = Internal::Bridge::Api::Nexus::NexusOperationCancellationType::TRY_CANCEL
|
|
17
|
+
# Wait for the server to confirm the cancellation request was delivered.
|
|
18
|
+
WAIT_CANCELLATION_REQUESTED = Internal::Bridge::Api::Nexus::NexusOperationCancellationType::WAIT_CANCELLATION_REQUESTED
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Temporalio
|
|
4
|
+
module Workflow
|
|
5
|
+
# Handle for interacting with a Nexus operation.
|
|
6
|
+
#
|
|
7
|
+
# This is created via {NexusClient#start_operation}, it is never instantiated directly.
|
|
8
|
+
#
|
|
9
|
+
# WARNING: Nexus support is experimental.
|
|
10
|
+
class NexusOperationHandle
|
|
11
|
+
# @!visibility private
|
|
12
|
+
def initialize
|
|
13
|
+
raise NotImplementedError, 'Cannot instantiate a Nexus operation handle directly'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @return [String, nil] Operation token for async operations, nil for sync operations.
|
|
17
|
+
def operation_token
|
|
18
|
+
raise NotImplementedError
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @return [Object, nil] Hint for the result if any.
|
|
22
|
+
def result_hint
|
|
23
|
+
raise NotImplementedError
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Wait for the result.
|
|
27
|
+
#
|
|
28
|
+
# @param result_hint [Object, nil] Override the result hint, or if nil uses the one on the handle.
|
|
29
|
+
# @return [Object] Result of the Nexus operation.
|
|
30
|
+
#
|
|
31
|
+
# @raise [Error::NexusOperationError] Operation failed with +cause+ as the cause.
|
|
32
|
+
def result(result_hint: nil)
|
|
33
|
+
raise NotImplementedError
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
data/lib/temporalio/workflow.rb
CHANGED
|
@@ -12,6 +12,9 @@ require 'temporalio/workflow/external_workflow_handle'
|
|
|
12
12
|
require 'temporalio/workflow/future'
|
|
13
13
|
require 'temporalio/workflow/handler_unfinished_policy'
|
|
14
14
|
require 'temporalio/workflow/info'
|
|
15
|
+
require 'temporalio/workflow/nexus_client'
|
|
16
|
+
require 'temporalio/workflow/nexus_operation_cancellation_type'
|
|
17
|
+
require 'temporalio/workflow/nexus_operation_handle'
|
|
15
18
|
require 'temporalio/workflow/parent_close_policy'
|
|
16
19
|
require 'temporalio/workflow/update_info'
|
|
17
20
|
require 'timeout'
|
|
@@ -40,6 +43,17 @@ module Temporalio
|
|
|
40
43
|
_current.continue_as_new_suggested
|
|
41
44
|
end
|
|
42
45
|
|
|
46
|
+
# Create a Nexus client for executing operations.
|
|
47
|
+
#
|
|
48
|
+
# WARNING: Nexus support is experimental.
|
|
49
|
+
#
|
|
50
|
+
# @param endpoint [Symbol, String] Endpoint name.
|
|
51
|
+
# @param service [Symbol, String] Service name.
|
|
52
|
+
# @return [NexusClient] Client for executing Nexus operations.
|
|
53
|
+
def self.create_nexus_client(endpoint:, service:)
|
|
54
|
+
_current.create_nexus_client(endpoint:, service:)
|
|
55
|
+
end
|
|
56
|
+
|
|
43
57
|
# Get current details for this workflow that may appear in UI/CLI. Unlike static details set at start, this value
|
|
44
58
|
# can be updated throughout the life of the workflow. This can be in Temporal markdown format and can span multiple
|
|
45
59
|
# lines. This is currently experimental.
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: temporalio
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Temporal Technologies Inc
|
|
@@ -197,6 +197,8 @@ files:
|
|
|
197
197
|
- lib/temporalio/internal/worker/workflow_instance/handler_hash.rb
|
|
198
198
|
- lib/temporalio/internal/worker/workflow_instance/illegal_call_tracer.rb
|
|
199
199
|
- lib/temporalio/internal/worker/workflow_instance/inbound_implementation.rb
|
|
200
|
+
- lib/temporalio/internal/worker/workflow_instance/nexus_client.rb
|
|
201
|
+
- lib/temporalio/internal/worker/workflow_instance/nexus_operation_handle.rb
|
|
200
202
|
- lib/temporalio/internal/worker/workflow_instance/outbound_implementation.rb
|
|
201
203
|
- lib/temporalio/internal/worker/workflow_instance/replay_safe_logger.rb
|
|
202
204
|
- lib/temporalio/internal/worker/workflow_instance/replay_safe_metric.rb
|
|
@@ -239,6 +241,9 @@ files:
|
|
|
239
241
|
- lib/temporalio/workflow/future.rb
|
|
240
242
|
- lib/temporalio/workflow/handler_unfinished_policy.rb
|
|
241
243
|
- lib/temporalio/workflow/info.rb
|
|
244
|
+
- lib/temporalio/workflow/nexus_client.rb
|
|
245
|
+
- lib/temporalio/workflow/nexus_operation_cancellation_type.rb
|
|
246
|
+
- lib/temporalio/workflow/nexus_operation_handle.rb
|
|
242
247
|
- lib/temporalio/workflow/parent_close_policy.rb
|
|
243
248
|
- lib/temporalio/workflow/update_info.rb
|
|
244
249
|
- lib/temporalio/workflow_history.rb
|