dex-python-sdk 0.12.0__tar.gz → 0.13.0__tar.gz
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.
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/PKG-INFO +35 -6
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/README.md +34 -5
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/__init__.py +4 -2
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/_grpc_errors.py +4 -6
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/async_client.py +99 -32
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/client.py +99 -32
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/dexpb/dex_pb2.py +248 -248
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/dexpb/dex_pb2.pyi +14 -10
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/dexpb/dex_pb2_grpc.py +12 -12
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/flow.py +63 -0
- dex_python_sdk-0.13.0/dex/rpc_invoke_options.py +42 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/runtime_errors.py +4 -4
- dex_python_sdk-0.13.0/dex/wait_options.py +112 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/pyproject.toml +1 -1
- dex_python_sdk-0.12.0/dex/wait_options.py +0 -84
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/LEGACY_NOTICES.md +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/LICENSE +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/_async_value_hydrator.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/_async_worker_dispatcher.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/_async_worker_service.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/_invocation_context.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/_native.pyi +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/_server_protocol.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/_utils.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/_value_hydrator.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/_value_mapper.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/_worker_dispatcher.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/_worker_service.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/async_worker.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/attribute.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/attribute_match.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/blob_cache.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/channel.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/client_options.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/codec.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/condition.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/context.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/dexpb/__init__.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/flow_config.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/flow_info.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/flow_options.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/flow_result.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/py.typed +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/step.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/step_execution.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/stream.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/subflow.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/timer.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/wait.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/worker.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/dex/worker_options.py +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/sdk-rust/Cargo.lock +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/sdk-rust/Cargo.toml +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/sdk-rust/crates/dex-blob-cache/Cargo.toml +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/sdk-rust/crates/dex-blob-cache/LICENSE +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/sdk-rust/crates/dex-blob-cache/src/config.rs +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/sdk-rust/crates/dex-blob-cache/src/entry.rs +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/sdk-rust/crates/dex-blob-cache/src/error.rs +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/sdk-rust/crates/dex-blob-cache/src/format.rs +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/sdk-rust/crates/dex-blob-cache/src/lib.rs +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/sdk-rust/crates/dex-blob-cache/src/policy.rs +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/sdk-rust/crates/dex-blob-cache/src/store.rs +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/sdk-rust/crates/dex-blob-cache/tests/blob_cache_integration.rs +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/sdk-rust/crates/dex-blob-cache-python/Cargo.toml +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/sdk-rust/crates/dex-blob-cache-python/LICENSE +0 -0
- {dex_python_sdk-0.12.0 → dex_python_sdk-0.13.0}/sdk-rust/crates/dex-blob-cache-python/src/lib.rs +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dex-python-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.13.0
|
|
4
4
|
Requires-Dist: grpcio>=1.83.0
|
|
5
5
|
Requires-Dist: grpcio-status>=1.83.0
|
|
6
6
|
Requires-Dist: protobuf>=7.35.1
|
|
@@ -58,6 +58,30 @@ atomic commit and Channel deletion validation. Attribute locks add isolation
|
|
|
58
58
|
only among cooperating Steps and RPCs using the same lock. Write-only publish
|
|
59
59
|
and delete operations do not require loading.
|
|
60
60
|
|
|
61
|
+
### Invocation-time map instances
|
|
62
|
+
|
|
63
|
+
The `@rpc` decorator remains the registration-time contract for timeout,
|
|
64
|
+
transactionality, locks, and fixed state loads. Pass frozen `RPCInvokeOptions`
|
|
65
|
+
through the keyword-only `options` argument when the caller chooses an exact map
|
|
66
|
+
instance at runtime:
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
options = dex.RPCInvokeOptions(
|
|
70
|
+
lock_attribute_map_instances=(profiles.lock(partition_name),),
|
|
71
|
+
load_attribute_map_instances=(profiles.load(partition_name),),
|
|
72
|
+
)
|
|
73
|
+
result = client.invoke_rpc(
|
|
74
|
+
directory.upsert_customer_profile,
|
|
75
|
+
flow_id,
|
|
76
|
+
profile,
|
|
77
|
+
options=options,
|
|
78
|
+
)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`Client` and `AsyncClient` union, sort, and deduplicate these selections with the
|
|
82
|
+
registered ones. Locking and loading are independent; read-modify-write handlers
|
|
83
|
+
need both for the same instance.
|
|
84
|
+
|
|
61
85
|
## Step and timeout-handler state loading
|
|
62
86
|
|
|
63
87
|
`StepOptions` provides the same five selections independently for `wait_for` and
|
|
@@ -363,11 +387,16 @@ sorted. Use `force_complete_if_channels_empty(...)` for conditional completion.
|
|
|
363
387
|
|
|
364
388
|
Request IDs are optional for both durable waits. When omitted, the server
|
|
365
389
|
derives a stable ID from the Step execution or Attribute condition. Reuse an
|
|
366
|
-
override only for the same wait. `
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
390
|
+
override only for the same wait. `request_timeout` is the total SDK call budget
|
|
391
|
+
across transparent transport reattachments. Zero waits indefinitely.
|
|
392
|
+
Temporal permits 10 in-flight Updates and 2,000 total Updates in History per
|
|
393
|
+
Workflow Execution. A caller timeout or cancellation does not finish an
|
|
394
|
+
accepted durable wait, so an abandoned handler can retain one in-flight slot.
|
|
395
|
+
Set `internal_handler_timeout` only when abandoned waits can approach that
|
|
396
|
+
limit. An active call transparently starts another generation, which counts
|
|
397
|
+
toward the 2,000-Update history limit. Prefer a value comfortably longer than
|
|
398
|
+
normal request timeouts and reconnect gaps. Zero disables timed rollover.
|
|
399
|
+
Request expiry raises `RequestTimeoutError`.
|
|
371
400
|
|
|
372
401
|
`Client.wait_for_flow` and `AsyncClient.wait_for_flow` return a
|
|
373
402
|
`FlowResult` after hydrating every output-bearing completion. Use
|
|
@@ -42,6 +42,30 @@ atomic commit and Channel deletion validation. Attribute locks add isolation
|
|
|
42
42
|
only among cooperating Steps and RPCs using the same lock. Write-only publish
|
|
43
43
|
and delete operations do not require loading.
|
|
44
44
|
|
|
45
|
+
### Invocation-time map instances
|
|
46
|
+
|
|
47
|
+
The `@rpc` decorator remains the registration-time contract for timeout,
|
|
48
|
+
transactionality, locks, and fixed state loads. Pass frozen `RPCInvokeOptions`
|
|
49
|
+
through the keyword-only `options` argument when the caller chooses an exact map
|
|
50
|
+
instance at runtime:
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
options = dex.RPCInvokeOptions(
|
|
54
|
+
lock_attribute_map_instances=(profiles.lock(partition_name),),
|
|
55
|
+
load_attribute_map_instances=(profiles.load(partition_name),),
|
|
56
|
+
)
|
|
57
|
+
result = client.invoke_rpc(
|
|
58
|
+
directory.upsert_customer_profile,
|
|
59
|
+
flow_id,
|
|
60
|
+
profile,
|
|
61
|
+
options=options,
|
|
62
|
+
)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`Client` and `AsyncClient` union, sort, and deduplicate these selections with the
|
|
66
|
+
registered ones. Locking and loading are independent; read-modify-write handlers
|
|
67
|
+
need both for the same instance.
|
|
68
|
+
|
|
45
69
|
## Step and timeout-handler state loading
|
|
46
70
|
|
|
47
71
|
`StepOptions` provides the same five selections independently for `wait_for` and
|
|
@@ -347,11 +371,16 @@ sorted. Use `force_complete_if_channels_empty(...)` for conditional completion.
|
|
|
347
371
|
|
|
348
372
|
Request IDs are optional for both durable waits. When omitted, the server
|
|
349
373
|
derives a stable ID from the Step execution or Attribute condition. Reuse an
|
|
350
|
-
override only for the same wait. `
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
374
|
+
override only for the same wait. `request_timeout` is the total SDK call budget
|
|
375
|
+
across transparent transport reattachments. Zero waits indefinitely.
|
|
376
|
+
Temporal permits 10 in-flight Updates and 2,000 total Updates in History per
|
|
377
|
+
Workflow Execution. A caller timeout or cancellation does not finish an
|
|
378
|
+
accepted durable wait, so an abandoned handler can retain one in-flight slot.
|
|
379
|
+
Set `internal_handler_timeout` only when abandoned waits can approach that
|
|
380
|
+
limit. An active call transparently starts another generation, which counts
|
|
381
|
+
toward the 2,000-Update history limit. Prefer a value comfortably longer than
|
|
382
|
+
normal request timeouts and reconnect gaps. Zero disables timed rollover.
|
|
383
|
+
Request expiry raises `RequestTimeoutError`.
|
|
355
384
|
|
|
356
385
|
`Client.wait_for_flow` and `AsyncClient.wait_for_flow` return a
|
|
357
386
|
`FlowResult` after hydrating every output-bearing completion. Use
|
|
@@ -74,11 +74,12 @@ from dex.runtime_errors import (
|
|
|
74
74
|
FlowNotFoundError,
|
|
75
75
|
InvalidStepResultError,
|
|
76
76
|
LongPollTimeoutError,
|
|
77
|
+
RequestTimeoutError,
|
|
77
78
|
RpcLockConflictError,
|
|
78
79
|
ValueMappingError,
|
|
79
|
-
WaitHandlerTimeoutError,
|
|
80
80
|
WorkerInvocationError,
|
|
81
81
|
)
|
|
82
|
+
from dex.rpc_invoke_options import RPCInvokeOptions
|
|
82
83
|
from dex.step import (
|
|
83
84
|
RetryPolicy,
|
|
84
85
|
Step,
|
|
@@ -166,9 +167,10 @@ __all__ = [
|
|
|
166
167
|
"IndexType",
|
|
167
168
|
"JsonCodec",
|
|
168
169
|
"LongPollTimeoutError",
|
|
169
|
-
"
|
|
170
|
+
"RequestTimeoutError",
|
|
170
171
|
"PersistenceSchema",
|
|
171
172
|
"RPCResult",
|
|
173
|
+
"RPCInvokeOptions",
|
|
172
174
|
"RecoveryErrorInfo",
|
|
173
175
|
"RetryAfterError",
|
|
174
176
|
"RpcLockConflictError",
|
|
@@ -26,8 +26,8 @@ from dex.runtime_errors import (
|
|
|
26
26
|
FlowNotActiveError,
|
|
27
27
|
FlowNotFoundError,
|
|
28
28
|
LongPollTimeoutError,
|
|
29
|
+
RequestTimeoutError,
|
|
29
30
|
RpcLockConflictError,
|
|
30
|
-
WaitHandlerTimeoutError,
|
|
31
31
|
WorkerInvocationError,
|
|
32
32
|
)
|
|
33
33
|
|
|
@@ -144,8 +144,8 @@ def translate_rpc_error(
|
|
|
144
144
|
return LongPollTimeoutError(*parameters)
|
|
145
145
|
if sub_status is ErrorSubStatus.CHANNEL_MESSAGE_NOT_FOUND:
|
|
146
146
|
return ChannelMessageNotFoundError(*parameters)
|
|
147
|
-
if sub_status is ErrorSubStatus.
|
|
148
|
-
return
|
|
147
|
+
if sub_status is ErrorSubStatus.REQUEST_TIMEOUT:
|
|
148
|
+
return RequestTimeoutError(*parameters)
|
|
149
149
|
return DexServiceError(*parameters)
|
|
150
150
|
|
|
151
151
|
|
|
@@ -249,8 +249,6 @@ def _map_sub_status(value: int) -> ErrorSubStatus:
|
|
|
249
249
|
int(
|
|
250
250
|
pb.ERROR_SUB_STATUS_CHANNEL_MESSAGE_NOT_FOUND
|
|
251
251
|
): ErrorSubStatus.CHANNEL_MESSAGE_NOT_FOUND,
|
|
252
|
-
int(
|
|
253
|
-
pb.ERROR_SUB_STATUS_WAIT_HANDLER_TIME_OUT
|
|
254
|
-
): ErrorSubStatus.WAIT_HANDLER_TIMEOUT,
|
|
252
|
+
int(pb.ERROR_SUB_STATUS_REQUEST_TIMEOUT): ErrorSubStatus.REQUEST_TIMEOUT,
|
|
255
253
|
}
|
|
256
254
|
return statuses.get(value, ErrorSubStatus.UNCATEGORIZED)
|
|
@@ -45,14 +45,16 @@ from dex.flow_options import (
|
|
|
45
45
|
_resolve_flow_timeout_policy,
|
|
46
46
|
)
|
|
47
47
|
from dex.flow_result import FlowResult, flow_result_from_proto
|
|
48
|
-
from dex.runtime_errors import FlowErrorType, LongPollTimeoutError
|
|
48
|
+
from dex.runtime_errors import DexServiceError, FlowErrorType, LongPollTimeoutError
|
|
49
|
+
from dex.rpc_invoke_options import RPCInvokeOptions
|
|
49
50
|
from dex.step import RetryPolicy, StepDurability
|
|
50
51
|
from dex.step_execution import StepExecutionId, TimerId
|
|
51
52
|
from dex.stream import Stream, StreamMessage, StreamMessagesPage
|
|
52
53
|
from dex.wait_options import (
|
|
53
54
|
WaitForAttributeOptions,
|
|
54
55
|
WaitForStepCompletionOptions,
|
|
55
|
-
|
|
56
|
+
_ClientRequestBudget,
|
|
57
|
+
_duration_seconds32,
|
|
56
58
|
)
|
|
57
59
|
|
|
58
60
|
InputT = TypeVar("InputT")
|
|
@@ -213,6 +215,7 @@ class AsyncClient:
|
|
|
213
215
|
input: InputT,
|
|
214
216
|
*,
|
|
215
217
|
run_id: str = "",
|
|
218
|
+
options: RPCInvokeOptions = RPCInvokeOptions(),
|
|
216
219
|
) -> OutputT: ...
|
|
217
220
|
|
|
218
221
|
@overload
|
|
@@ -222,6 +225,7 @@ class AsyncClient:
|
|
|
222
225
|
flow_id: str,
|
|
223
226
|
*,
|
|
224
227
|
run_id: str = "",
|
|
228
|
+
options: RPCInvokeOptions = RPCInvokeOptions(),
|
|
225
229
|
) -> OutputT: ...
|
|
226
230
|
|
|
227
231
|
@overload
|
|
@@ -232,6 +236,7 @@ class AsyncClient:
|
|
|
232
236
|
input: InputT,
|
|
233
237
|
*,
|
|
234
238
|
run_id: str = "",
|
|
239
|
+
options: RPCInvokeOptions = RPCInvokeOptions(),
|
|
235
240
|
) -> None: ...
|
|
236
241
|
|
|
237
242
|
@overload
|
|
@@ -241,6 +246,7 @@ class AsyncClient:
|
|
|
241
246
|
flow_id: str,
|
|
242
247
|
*,
|
|
243
248
|
run_id: str = "",
|
|
249
|
+
options: RPCInvokeOptions = RPCInvokeOptions(),
|
|
244
250
|
) -> None: ...
|
|
245
251
|
|
|
246
252
|
async def invoke_rpc(
|
|
@@ -250,6 +256,7 @@ class AsyncClient:
|
|
|
250
256
|
input: object = None,
|
|
251
257
|
*,
|
|
252
258
|
run_id: str = "",
|
|
259
|
+
options: RPCInvokeOptions = RPCInvokeOptions(),
|
|
253
260
|
) -> Any:
|
|
254
261
|
"""Invoke a registered RPC and await its typed result.
|
|
255
262
|
|
|
@@ -266,6 +273,7 @@ class AsyncClient:
|
|
|
266
273
|
input: The annotated input, or ``None`` for an input-free RPC.
|
|
267
274
|
run_id: Optional exact run. With ``""``, the server resolves the current
|
|
268
275
|
execution.
|
|
276
|
+
options: Additive runtime AttributeMap locks and exact map-instance loads.
|
|
269
277
|
|
|
270
278
|
Returns:
|
|
271
279
|
The decoded ``RPCResult.output``, or ``None`` for a no-output RPC.
|
|
@@ -278,7 +286,12 @@ class AsyncClient:
|
|
|
278
286
|
DexServiceError: If the selected path requires an active execution or the
|
|
279
287
|
service call otherwise fails.
|
|
280
288
|
"""
|
|
281
|
-
|
|
289
|
+
registered_flow, rpc = self.registry._rpc_for_method(rpc_method)
|
|
290
|
+
(
|
|
291
|
+
invocation_locks,
|
|
292
|
+
invocation_attribute_map_loads,
|
|
293
|
+
invocation_channel_map_loads,
|
|
294
|
+
) = self.registry._resolve_rpc_invoke_options(registered_flow, options)
|
|
282
295
|
encoded_input = (
|
|
283
296
|
self._values.encode(input, rpc.input_codec)
|
|
284
297
|
if rpc.input_codec is not None
|
|
@@ -299,12 +312,28 @@ class AsyncClient:
|
|
|
299
312
|
rpc_name=rpc.name,
|
|
300
313
|
input=encoded_input,
|
|
301
314
|
timeout_seconds=timeout,
|
|
302
|
-
lock_attribute_keys=
|
|
315
|
+
lock_attribute_keys=tuple(
|
|
316
|
+
sorted(set(rpc.locks + invocation_locks))
|
|
317
|
+
),
|
|
303
318
|
request_id=str(uuid4()),
|
|
304
319
|
is_transactional=rpc.options.is_transactional,
|
|
305
|
-
load_attribute_map_instances=
|
|
320
|
+
load_attribute_map_instances=tuple(
|
|
321
|
+
sorted(
|
|
322
|
+
set(
|
|
323
|
+
rpc.load_attribute_map_instances
|
|
324
|
+
+ invocation_attribute_map_loads
|
|
325
|
+
)
|
|
326
|
+
)
|
|
327
|
+
),
|
|
306
328
|
load_channel_names=rpc.load_channel_names,
|
|
307
|
-
load_channel_map_instances=
|
|
329
|
+
load_channel_map_instances=tuple(
|
|
330
|
+
sorted(
|
|
331
|
+
set(
|
|
332
|
+
rpc.load_channel_map_instances
|
|
333
|
+
+ invocation_channel_map_loads
|
|
334
|
+
)
|
|
335
|
+
)
|
|
336
|
+
),
|
|
308
337
|
),
|
|
309
338
|
"invoke_rpc",
|
|
310
339
|
flow_id,
|
|
@@ -738,27 +767,33 @@ class AsyncClient:
|
|
|
738
767
|
step_execution_id: StepExecutionId,
|
|
739
768
|
options: WaitForStepCompletionOptions,
|
|
740
769
|
) -> None:
|
|
741
|
-
"""Await one Step execution
|
|
770
|
+
"""Await one Step execution completion or its request timeout expiry.
|
|
742
771
|
|
|
743
772
|
The server derives a stable Request ID from the Step execution when none
|
|
744
|
-
is supplied.
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
positive value bounds the caller-visible wait.
|
|
773
|
+
is supplied. Request timeout covers transparent transport reattachments.
|
|
774
|
+
Internal handler timeout controls Update generation rollover without ending
|
|
775
|
+
this request.
|
|
748
776
|
|
|
749
777
|
Args:
|
|
750
778
|
flow_id: The non-empty active Flow ID.
|
|
751
779
|
step_execution_id: The Step type and positive execution number.
|
|
752
|
-
options: The optional Request ID
|
|
780
|
+
options: The optional Request ID, request timeout, and internal handler
|
|
781
|
+
timeout controls.
|
|
753
782
|
|
|
754
783
|
Raises:
|
|
755
|
-
ValueError: If the Request ID or
|
|
756
|
-
|
|
784
|
+
ValueError: If the Request ID or request timeout is invalid.
|
|
785
|
+
RequestTimeoutError: If a positive request timeout expires first.
|
|
757
786
|
FlowNotActiveError: If the Flow closes first.
|
|
758
787
|
DexServiceError: If FlowService cannot perform the wait.
|
|
759
788
|
"""
|
|
760
|
-
|
|
789
|
+
request_budget = _ClientRequestBudget(options.request_timeout)
|
|
790
|
+
internal_handler_timeout_seconds = _duration_seconds32(
|
|
791
|
+
options.internal_handler_timeout
|
|
792
|
+
)
|
|
761
793
|
while True:
|
|
794
|
+
request_attempt = request_budget.next_attempt(
|
|
795
|
+
"wait_for_step_completion", flow_id
|
|
796
|
+
)
|
|
762
797
|
try:
|
|
763
798
|
await self._call(
|
|
764
799
|
self._service.WaitForStepCompletion,
|
|
@@ -766,18 +801,29 @@ class AsyncClient:
|
|
|
766
801
|
flow_id=require_name(flow_id),
|
|
767
802
|
step_type=step_execution_id.step_type,
|
|
768
803
|
step_execution_number=str(step_execution_id.number),
|
|
769
|
-
|
|
770
|
-
|
|
804
|
+
request_timeout_seconds=request_attempt.request_timeout_seconds,
|
|
805
|
+
internal_handler_timeout_seconds=(
|
|
806
|
+
internal_handler_timeout_seconds
|
|
771
807
|
),
|
|
772
808
|
request_id=options.request_id,
|
|
773
809
|
),
|
|
774
810
|
"wait_for_step_completion",
|
|
775
811
|
flow_id,
|
|
776
812
|
"active",
|
|
813
|
+
request_attempt.transport_timeout_seconds,
|
|
777
814
|
)
|
|
778
815
|
return
|
|
779
816
|
except LongPollTimeoutError:
|
|
780
817
|
continue
|
|
818
|
+
except DexServiceError as error:
|
|
819
|
+
if (
|
|
820
|
+
error.code is grpc.StatusCode.DEADLINE_EXCEEDED
|
|
821
|
+
and request_budget.has_expired()
|
|
822
|
+
):
|
|
823
|
+
raise request_budget.timeout_error(
|
|
824
|
+
"wait_for_step_completion", flow_id
|
|
825
|
+
) from error
|
|
826
|
+
raise
|
|
781
827
|
|
|
782
828
|
@overload
|
|
783
829
|
async def wait_for_attribute_match(
|
|
@@ -791,24 +837,23 @@ class AsyncClient:
|
|
|
791
837
|
|
|
792
838
|
The Client returns the value observed by the successful wait. The server
|
|
793
839
|
derives a stable Request ID from the condition when none is supplied.
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
Workflow history; prefer at least one minute when nonzero. A positive value
|
|
797
|
-
bounds the caller-visible wait.
|
|
840
|
+
Request timeout covers transparent transport reattachments. Internal handler
|
|
841
|
+
timeout controls Update generation rollover without ending this request.
|
|
798
842
|
JSON, bytes, and null operands raise ``ValueError`` before transport.
|
|
799
843
|
|
|
800
844
|
Args:
|
|
801
845
|
flow_id: The non-empty active Flow ID.
|
|
802
846
|
attribute: The registered singleton Attribute to observe.
|
|
803
847
|
match: The scalar predicate to await.
|
|
804
|
-
options: The optional Request ID
|
|
848
|
+
options: The optional Request ID, request timeout, and internal handler
|
|
849
|
+
timeout controls.
|
|
805
850
|
|
|
806
851
|
Returns:
|
|
807
852
|
The current Attribute value that satisfied ``match``.
|
|
808
853
|
|
|
809
854
|
Raises:
|
|
810
855
|
ValueError: If an identifier, option, or match operand is invalid.
|
|
811
|
-
|
|
856
|
+
RequestTimeoutError: If a positive request timeout expires first.
|
|
812
857
|
FlowNotActiveError: If the Flow closes first.
|
|
813
858
|
DexServiceError: If FlowService cannot perform the wait.
|
|
814
859
|
"""
|
|
@@ -825,7 +870,7 @@ class AsyncClient:
|
|
|
825
870
|
) -> ValueT:
|
|
826
871
|
"""Await one AttributeMap instance in the current run satisfying a match.
|
|
827
872
|
|
|
828
|
-
Match restrictions, Request ID, handler-
|
|
873
|
+
Match restrictions, Request ID, request-timeout and handler-generation behavior, and service
|
|
829
874
|
errors match :meth:`wait_for_attribute_match`.
|
|
830
875
|
|
|
831
876
|
Args:
|
|
@@ -833,14 +878,14 @@ class AsyncClient:
|
|
|
833
878
|
attribute: The registered AttributeMap to observe.
|
|
834
879
|
instance: The map instance to observe. Slash is prohibited because it is a reserved character.
|
|
835
880
|
match: The scalar predicate to await.
|
|
836
|
-
options: The optional Request ID override and total handler
|
|
881
|
+
options: The optional Request ID override and total handler request timeout.
|
|
837
882
|
|
|
838
883
|
Returns:
|
|
839
884
|
The current AttributeMap value that satisfied ``match``.
|
|
840
885
|
|
|
841
886
|
Raises:
|
|
842
887
|
ValueError: If an identifier, option, or match operand is invalid.
|
|
843
|
-
|
|
888
|
+
RequestTimeoutError: If a positive request timeout expires first.
|
|
844
889
|
FlowNotActiveError: If the Flow closes first.
|
|
845
890
|
DexServiceError: If FlowService cannot perform the wait.
|
|
846
891
|
"""
|
|
@@ -870,7 +915,7 @@ class AsyncClient:
|
|
|
870
915
|
Raises:
|
|
871
916
|
TypeError: If arguments do not match the Attribute definition.
|
|
872
917
|
ValueError: If an identifier, option, or expected value is invalid.
|
|
873
|
-
|
|
918
|
+
RequestTimeoutError: If a positive request timeout expires first.
|
|
874
919
|
FlowNotActiveError: If the Flow closes first.
|
|
875
920
|
DexServiceError: If FlowService cannot perform the wait.
|
|
876
921
|
"""
|
|
@@ -895,8 +940,14 @@ class AsyncClient:
|
|
|
895
940
|
self._values.codec(attribute.value_type),
|
|
896
941
|
)
|
|
897
942
|
encoded_match.key = self._definition_name(attribute, instance)
|
|
898
|
-
|
|
943
|
+
request_budget = _ClientRequestBudget(options.request_timeout)
|
|
944
|
+
internal_handler_timeout_seconds = _duration_seconds32(
|
|
945
|
+
options.internal_handler_timeout
|
|
946
|
+
)
|
|
899
947
|
while True:
|
|
948
|
+
request_attempt = request_budget.next_attempt(
|
|
949
|
+
"wait_for_attribute_match", flow_id
|
|
950
|
+
)
|
|
900
951
|
try:
|
|
901
952
|
response = cast(
|
|
902
953
|
pb.WaitForAttributeResponse,
|
|
@@ -905,14 +956,18 @@ class AsyncClient:
|
|
|
905
956
|
pb.WaitForAttributeRequest(
|
|
906
957
|
flow_id=require_name(flow_id),
|
|
907
958
|
match=encoded_match,
|
|
908
|
-
|
|
909
|
-
|
|
959
|
+
request_timeout_seconds=(
|
|
960
|
+
request_attempt.request_timeout_seconds
|
|
961
|
+
),
|
|
962
|
+
internal_handler_timeout_seconds=(
|
|
963
|
+
internal_handler_timeout_seconds
|
|
910
964
|
),
|
|
911
965
|
request_id=options.request_id,
|
|
912
966
|
),
|
|
913
967
|
"wait_for_attribute_match",
|
|
914
968
|
flow_id,
|
|
915
969
|
"active",
|
|
970
|
+
request_attempt.transport_timeout_seconds,
|
|
916
971
|
),
|
|
917
972
|
)
|
|
918
973
|
if not response.HasField("matched_value"):
|
|
@@ -923,6 +978,15 @@ class AsyncClient:
|
|
|
923
978
|
)
|
|
924
979
|
except LongPollTimeoutError:
|
|
925
980
|
continue
|
|
981
|
+
except DexServiceError as error:
|
|
982
|
+
if (
|
|
983
|
+
error.code is grpc.StatusCode.DEADLINE_EXCEEDED
|
|
984
|
+
and request_budget.has_expired()
|
|
985
|
+
):
|
|
986
|
+
raise request_budget.timeout_error(
|
|
987
|
+
"wait_for_attribute_match", flow_id
|
|
988
|
+
) from error
|
|
989
|
+
raise
|
|
926
990
|
|
|
927
991
|
async def update_flow_config(self, flow_id: str, config: FlowConfig) -> None:
|
|
928
992
|
"""Replace mutable configuration for an active Flow.
|
|
@@ -1245,13 +1309,16 @@ class AsyncClient:
|
|
|
1245
1309
|
|
|
1246
1310
|
@staticmethod
|
|
1247
1311
|
async def _call(
|
|
1248
|
-
method: Callable[
|
|
1312
|
+
method: Callable[..., Any],
|
|
1249
1313
|
request: Any,
|
|
1250
1314
|
operation: str,
|
|
1251
1315
|
flow_id: str | None,
|
|
1252
1316
|
requirement: FlowTargetRequirement,
|
|
1317
|
+
timeout: float | None = None,
|
|
1253
1318
|
) -> Any:
|
|
1254
1319
|
try:
|
|
1255
|
-
|
|
1320
|
+
if timeout is None:
|
|
1321
|
+
return await method(request)
|
|
1322
|
+
return await method(request, timeout=timeout)
|
|
1256
1323
|
except grpc.RpcError as error:
|
|
1257
1324
|
raise translate_rpc_error(error, operation, flow_id, requirement) from error
|