@temporalio/core-bridge 1.1.0 → 1.4.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.
- package/Cargo.lock +765 -128
- package/Cargo.toml +2 -2
- package/common.js +7 -3
- package/index.d.ts +118 -5
- package/index.js +2 -6
- package/package.json +2 -3
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
- package/releases/x86_64-apple-darwin/index.node +0 -0
- package/releases/x86_64-pc-windows-msvc/index.node +0 -0
- package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
- package/scripts/build.js +4 -3
- package/sdk-core/.buildkite/docker/Dockerfile +2 -1
- package/sdk-core/.buildkite/pipeline.yml +2 -0
- package/sdk-core/.cargo/config.toml +1 -1
- package/sdk-core/ARCHITECTURE.md +2 -2
- package/sdk-core/README.md +12 -0
- package/sdk-core/bridge-ffi/Cargo.toml +2 -2
- package/sdk-core/bridge-ffi/src/lib.rs +2 -2
- package/sdk-core/client/Cargo.toml +7 -5
- package/sdk-core/client/src/lib.rs +354 -226
- package/sdk-core/client/src/metrics.rs +13 -11
- package/sdk-core/client/src/raw.rs +352 -107
- package/sdk-core/client/src/retry.rs +188 -147
- package/sdk-core/client/src/workflow_handle/mod.rs +1 -1
- package/sdk-core/core/Cargo.toml +28 -15
- package/sdk-core/core/src/core_tests/activity_tasks.rs +98 -33
- package/sdk-core/core/src/core_tests/child_workflows.rs +125 -3
- package/sdk-core/core/src/core_tests/local_activities.rs +6 -6
- package/sdk-core/core/src/core_tests/workers.rs +3 -2
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +70 -2
- package/sdk-core/core/src/ephemeral_server/mod.rs +515 -0
- package/sdk-core/core/src/lib.rs +62 -28
- package/sdk-core/core/src/pollers/mod.rs +2 -0
- package/sdk-core/core/src/pollers/poll_buffer.rs +4 -4
- package/sdk-core/core/src/replay/mod.rs +3 -3
- package/sdk-core/core/src/retry_logic.rs +10 -9
- package/sdk-core/core/src/telemetry/metrics.rs +48 -39
- package/sdk-core/core/src/telemetry/mod.rs +46 -12
- package/sdk-core/core/src/telemetry/prometheus_server.rs +17 -13
- package/sdk-core/core/src/test_help/mod.rs +18 -8
- package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +10 -10
- package/sdk-core/core/src/worker/activities/local_activities.rs +13 -13
- package/sdk-core/core/src/worker/activities.rs +6 -12
- package/sdk-core/core/src/worker/client/mocks.rs +1 -0
- package/sdk-core/core/src/worker/client.rs +193 -64
- package/sdk-core/core/src/worker/mod.rs +14 -19
- package/sdk-core/core/src/worker/workflow/driven_workflow.rs +3 -0
- package/sdk-core/core/src/worker/workflow/history_update.rs +5 -5
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +133 -85
- package/sdk-core/core/src/worker/workflow/machines/mod.rs +3 -2
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +160 -105
- package/sdk-core/core/src/worker/workflow/managed_run.rs +2 -1
- package/sdk-core/core/src/worker/workflow/mod.rs +62 -58
- package/sdk-core/core/src/worker/workflow/run_cache.rs +5 -3
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +7 -5
- package/sdk-core/core-api/Cargo.toml +3 -3
- package/sdk-core/core-api/src/errors.rs +3 -11
- package/sdk-core/core-api/src/worker.rs +7 -0
- package/sdk-core/protos/api_upstream/.buildkite/Dockerfile +1 -1
- package/sdk-core/protos/api_upstream/.github/CODEOWNERS +1 -1
- package/sdk-core/protos/api_upstream/.github/PULL_REQUEST_TEMPLATE.md +2 -6
- package/sdk-core/protos/api_upstream/.github/workflows/trigger-api-go-update.yml +29 -0
- package/sdk-core/protos/api_upstream/Makefile +2 -2
- package/sdk-core/protos/api_upstream/buf.yaml +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +86 -0
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +26 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +46 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +7 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +14 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +51 -0
- package/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +18 -0
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +57 -1
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +1 -3
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +4 -2
- package/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +11 -0
- package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +23 -0
- package/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +46 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +172 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +30 -0
- package/sdk-core/protos/grpc/health/v1/health.proto +63 -0
- package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +18 -15
- package/sdk-core/protos/testsrv_upstream/Makefile +80 -0
- package/sdk-core/protos/testsrv_upstream/api-linter.yaml +38 -0
- package/sdk-core/protos/testsrv_upstream/buf.yaml +13 -0
- package/sdk-core/protos/testsrv_upstream/dependencies/gogoproto/gogo.proto +141 -0
- package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +63 -0
- package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +90 -0
- package/sdk-core/sdk/Cargo.toml +2 -2
- package/sdk-core/sdk/src/lib.rs +2 -2
- package/sdk-core/sdk/src/workflow_context/options.rs +36 -8
- package/sdk-core/sdk/src/workflow_context.rs +30 -6
- package/sdk-core/sdk/src/workflow_future.rs +4 -4
- package/sdk-core/sdk-core-protos/Cargo.toml +5 -5
- package/sdk-core/sdk-core-protos/build.rs +9 -1
- package/sdk-core/sdk-core-protos/src/history_builder.rs +6 -1
- package/sdk-core/sdk-core-protos/src/lib.rs +93 -32
- package/sdk-core/test-utils/Cargo.toml +3 -3
- package/sdk-core/test-utils/src/canned_histories.rs +58 -0
- package/sdk-core/test-utils/src/lib.rs +35 -12
- package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +128 -0
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +55 -5
- package/sdk-core/tests/integ_tests/polling_tests.rs +2 -1
- package/sdk-core/tests/integ_tests/queries_tests.rs +5 -5
- package/sdk-core/tests/integ_tests/visibility_tests.rs +93 -0
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +93 -10
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +14 -14
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +2 -6
- package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +12 -12
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +12 -1
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +3 -3
- package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +8 -2
- package/sdk-core/tests/integ_tests/workflow_tests.rs +19 -4
- package/sdk-core/tests/load_tests.rs +2 -1
- package/sdk-core/tests/main.rs +17 -0
- package/sdk-core/tests/runner.rs +93 -0
- package/src/conversions.rs +157 -94
- package/src/helpers.rs +190 -0
- package/src/lib.rs +10 -912
- package/src/runtime.rs +436 -0
- package/src/testing.rs +67 -0
- package/src/worker.rs +465 -0
|
@@ -13,17 +13,25 @@ mod retry;
|
|
|
13
13
|
mod workflow_handle;
|
|
14
14
|
|
|
15
15
|
pub use crate::retry::{CallType, RetryClient, RETRYABLE_ERROR_CODES};
|
|
16
|
-
pub use raw::WorkflowService;
|
|
16
|
+
pub use raw::{HealthService, OperatorService, TestService, WorkflowService};
|
|
17
|
+
pub use temporal_sdk_core_protos::temporal::api::{
|
|
18
|
+
filter::v1::{StartTimeFilter, StatusFilter, WorkflowExecutionFilter, WorkflowTypeFilter},
|
|
19
|
+
workflowservice::v1::{
|
|
20
|
+
list_closed_workflow_executions_request::Filters as ListClosedFilters,
|
|
21
|
+
list_open_workflow_executions_request::Filters as ListOpenFilters,
|
|
22
|
+
},
|
|
23
|
+
};
|
|
17
24
|
pub use workflow_handle::{WorkflowExecutionInfo, WorkflowExecutionResult};
|
|
18
25
|
|
|
19
26
|
use crate::{
|
|
20
27
|
metrics::{GrpcMetricSvc, MetricsContext},
|
|
21
28
|
raw::{sealed::RawClientLike, AttachMetricLabels},
|
|
22
|
-
sealed::
|
|
29
|
+
sealed::WfHandleClient,
|
|
23
30
|
workflow_handle::UntypedWorkflowHandle,
|
|
24
31
|
};
|
|
25
|
-
use backoff::{ExponentialBackoff, SystemClock};
|
|
32
|
+
use backoff::{exponential, ExponentialBackoff, SystemClock};
|
|
26
33
|
use http::uri::InvalidUri;
|
|
34
|
+
use once_cell::sync::OnceCell;
|
|
27
35
|
use opentelemetry::metrics::Meter;
|
|
28
36
|
use parking_lot::RwLock;
|
|
29
37
|
use std::{
|
|
@@ -36,18 +44,23 @@ use std::{
|
|
|
36
44
|
};
|
|
37
45
|
use temporal_sdk_core_protos::{
|
|
38
46
|
coresdk::{workflow_commands::QueryResult, IntoPayloadsExt},
|
|
47
|
+
grpc::health::v1::health_client::HealthClient,
|
|
39
48
|
temporal::api::{
|
|
40
49
|
command::v1::Command,
|
|
41
|
-
common::v1::{Payload, Payloads, WorkflowExecution, WorkflowType},
|
|
42
|
-
enums::v1::{TaskQueueKind, WorkflowTaskFailedCause},
|
|
50
|
+
common::v1::{Header, Payload, Payloads, WorkflowExecution, WorkflowType},
|
|
51
|
+
enums::v1::{TaskQueueKind, WorkflowIdReusePolicy, WorkflowTaskFailedCause},
|
|
43
52
|
failure::v1::Failure,
|
|
44
|
-
|
|
45
|
-
|
|
53
|
+
operatorservice::v1::operator_service_client::OperatorServiceClient,
|
|
54
|
+
query::v1::WorkflowQuery,
|
|
55
|
+
taskqueue::v1::{StickyExecutionAttributes, TaskQueue},
|
|
56
|
+
testservice::v1::test_service_client::TestServiceClient,
|
|
46
57
|
workflowservice::v1::{workflow_service_client::WorkflowServiceClient, *},
|
|
47
58
|
},
|
|
48
59
|
TaskToken,
|
|
49
60
|
};
|
|
50
61
|
use tonic::{
|
|
62
|
+
body::BoxBody,
|
|
63
|
+
client::GrpcService,
|
|
51
64
|
codegen::InterceptedService,
|
|
52
65
|
metadata::{MetadataKey, MetadataValue},
|
|
53
66
|
service::Interceptor,
|
|
@@ -58,6 +71,9 @@ use tower::ServiceBuilder;
|
|
|
58
71
|
use url::Url;
|
|
59
72
|
use uuid::Uuid;
|
|
60
73
|
|
|
74
|
+
static CLIENT_NAME_HEADER_KEY: &str = "client-name";
|
|
75
|
+
static CLIENT_VERSION_HEADER_KEY: &str = "client-version";
|
|
76
|
+
/// These must match the gRPC method names, not the snake case versions that exist in the Rust code.
|
|
61
77
|
static LONG_POLL_METHOD_NAMES: [&str; 2] = ["PollWorkflowTaskQueue", "PollActivityTaskQueue"];
|
|
62
78
|
/// The server times out polls after 60 seconds. Set our timeout to be slightly beyond that.
|
|
63
79
|
const LONG_POLL_TIMEOUT: Duration = Duration::from_secs(70);
|
|
@@ -164,20 +180,24 @@ impl RetryConfig {
|
|
|
164
180
|
max_retries: 0,
|
|
165
181
|
}
|
|
166
182
|
}
|
|
183
|
+
|
|
184
|
+
pub(crate) fn into_exp_backoff<C>(self, clock: C) -> exponential::ExponentialBackoff<C> {
|
|
185
|
+
exponential::ExponentialBackoff {
|
|
186
|
+
current_interval: self.initial_interval,
|
|
187
|
+
initial_interval: self.initial_interval,
|
|
188
|
+
randomization_factor: self.randomization_factor,
|
|
189
|
+
multiplier: self.multiplier,
|
|
190
|
+
max_interval: self.max_interval,
|
|
191
|
+
max_elapsed_time: self.max_elapsed_time,
|
|
192
|
+
clock,
|
|
193
|
+
start_time: Instant::now(),
|
|
194
|
+
}
|
|
195
|
+
}
|
|
167
196
|
}
|
|
168
197
|
|
|
169
198
|
impl From<RetryConfig> for ExponentialBackoff {
|
|
170
199
|
fn from(c: RetryConfig) -> Self {
|
|
171
|
-
|
|
172
|
-
current_interval: c.initial_interval,
|
|
173
|
-
initial_interval: c.initial_interval,
|
|
174
|
-
randomization_factor: c.randomization_factor,
|
|
175
|
-
multiplier: c.multiplier,
|
|
176
|
-
max_interval: c.max_interval,
|
|
177
|
-
max_elapsed_time: c.max_elapsed_time,
|
|
178
|
-
clock: SystemClock::default(),
|
|
179
|
-
start_time: Instant::now(),
|
|
180
|
-
}
|
|
200
|
+
c.into_exp_backoff(SystemClock::default())
|
|
181
201
|
}
|
|
182
202
|
}
|
|
183
203
|
|
|
@@ -203,51 +223,12 @@ pub enum ClientInitError {
|
|
|
203
223
|
SystemInfoCallError(tonic::Status),
|
|
204
224
|
}
|
|
205
225
|
|
|
206
|
-
#[doc(hidden)]
|
|
207
|
-
/// Allows passing different kinds of clients into things that want to be flexible. Motivating
|
|
208
|
-
/// use-case was worker initialization.
|
|
209
|
-
///
|
|
210
|
-
/// Needs to exist in this crate to avoid blanket impl conflicts.
|
|
211
|
-
pub enum AnyClient {
|
|
212
|
-
/// A high level client, like the type workers work with
|
|
213
|
-
HighLevel(Arc<dyn WorkflowClientTrait + Send + Sync>),
|
|
214
|
-
/// A low level gRPC client, wrapped with the typical interceptors
|
|
215
|
-
LowLevel(Box<ConfiguredClient<WorkflowServiceClientWithMetrics>>),
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
impl<SGA> From<SGA> for AnyClient
|
|
219
|
-
where
|
|
220
|
-
SGA: WorkflowClientTrait + Send + Sync + 'static,
|
|
221
|
-
{
|
|
222
|
-
fn from(s: SGA) -> Self {
|
|
223
|
-
Self::HighLevel(Arc::new(s))
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
impl<SGA> From<Arc<SGA>> for AnyClient
|
|
227
|
-
where
|
|
228
|
-
SGA: WorkflowClientTrait + Send + Sync + 'static,
|
|
229
|
-
{
|
|
230
|
-
fn from(s: Arc<SGA>) -> Self {
|
|
231
|
-
Self::HighLevel(s)
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
impl From<RetryClient<ConfiguredClient<WorkflowServiceClientWithMetrics>>> for AnyClient {
|
|
235
|
-
fn from(c: RetryClient<ConfiguredClient<WorkflowServiceClientWithMetrics>>) -> Self {
|
|
236
|
-
Self::LowLevel(Box::new(c.into_inner()))
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
impl From<ConfiguredClient<WorkflowServiceClientWithMetrics>> for AnyClient {
|
|
240
|
-
fn from(c: ConfiguredClient<WorkflowServiceClientWithMetrics>) -> Self {
|
|
241
|
-
Self::LowLevel(Box::new(c))
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
226
|
/// A client with [ClientOptions] attached, which can be passed to initialize workers,
|
|
246
|
-
/// or can be used directly.
|
|
227
|
+
/// or can be used directly. Is cheap to clone.
|
|
247
228
|
#[derive(Clone, Debug)]
|
|
248
229
|
pub struct ConfiguredClient<C> {
|
|
249
230
|
client: C,
|
|
250
|
-
options: ClientOptions
|
|
231
|
+
options: Arc<ClientOptions>,
|
|
251
232
|
headers: Arc<RwLock<HashMap<String, String>>>,
|
|
252
233
|
/// Capabilities as read from the `get_system_info` RPC call made on client connection
|
|
253
234
|
capabilities: Option<get_system_info_response::Capabilities>,
|
|
@@ -270,11 +251,6 @@ impl<C> ConfiguredClient<C> {
|
|
|
270
251
|
pub fn capabilities(&self) -> Option<&get_system_info_response::Capabilities> {
|
|
271
252
|
self.capabilities.as_ref()
|
|
272
253
|
}
|
|
273
|
-
|
|
274
|
-
/// De-constitute this type
|
|
275
|
-
pub fn into_parts(self) -> (C, ClientOptions) {
|
|
276
|
-
(self.client, self.options)
|
|
277
|
-
}
|
|
278
254
|
}
|
|
279
255
|
|
|
280
256
|
// The configured client is effectively a "smart" (dumb) pointer
|
|
@@ -317,7 +293,7 @@ impl ClientOptions {
|
|
|
317
293
|
&self,
|
|
318
294
|
metrics_meter: Option<&Meter>,
|
|
319
295
|
headers: Option<Arc<RwLock<HashMap<String, String>>>>,
|
|
320
|
-
) -> Result<RetryClient<ConfiguredClient<
|
|
296
|
+
) -> Result<RetryClient<ConfiguredClient<TemporalServiceClientWithMetrics>>, ClientInitError>
|
|
321
297
|
{
|
|
322
298
|
let channel = Channel::from_shared(self.target_url.to_string())?;
|
|
323
299
|
let channel = self.add_tls_to_channel(channel).await?;
|
|
@@ -333,11 +309,12 @@ impl ClientOptions {
|
|
|
333
309
|
opts: self.clone(),
|
|
334
310
|
headers: headers.clone(),
|
|
335
311
|
};
|
|
312
|
+
let svc = InterceptedService::new(service, interceptor);
|
|
336
313
|
|
|
337
314
|
let mut client = ConfiguredClient {
|
|
338
315
|
headers,
|
|
339
|
-
client:
|
|
340
|
-
options: self.clone(),
|
|
316
|
+
client: TemporalServiceClient::new(svc),
|
|
317
|
+
options: Arc::new(self.clone()),
|
|
341
318
|
capabilities: None,
|
|
342
319
|
};
|
|
343
320
|
match client
|
|
@@ -416,27 +393,35 @@ impl Interceptor for ServiceCallInterceptor {
|
|
|
416
393
|
/// cancel the request and have that status returned to the caller.
|
|
417
394
|
fn call(&mut self, mut request: tonic::Request<()>) -> Result<tonic::Request<()>, Status> {
|
|
418
395
|
let metadata = request.metadata_mut();
|
|
419
|
-
metadata.
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
.
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
.
|
|
432
|
-
|
|
396
|
+
if !metadata.contains_key(CLIENT_NAME_HEADER_KEY) {
|
|
397
|
+
metadata.insert(
|
|
398
|
+
CLIENT_NAME_HEADER_KEY,
|
|
399
|
+
self.opts
|
|
400
|
+
.client_name
|
|
401
|
+
.parse()
|
|
402
|
+
.unwrap_or_else(|_| MetadataValue::from_static("")),
|
|
403
|
+
);
|
|
404
|
+
}
|
|
405
|
+
if !metadata.contains_key(CLIENT_VERSION_HEADER_KEY) {
|
|
406
|
+
metadata.insert(
|
|
407
|
+
CLIENT_VERSION_HEADER_KEY,
|
|
408
|
+
self.opts
|
|
409
|
+
.client_version
|
|
410
|
+
.parse()
|
|
411
|
+
.unwrap_or_else(|_| MetadataValue::from_static("")),
|
|
412
|
+
);
|
|
413
|
+
}
|
|
433
414
|
let headers = &*self.headers.read();
|
|
434
415
|
for (k, v) in headers {
|
|
435
|
-
if
|
|
416
|
+
if metadata.contains_key(k) {
|
|
417
|
+
// Don't overwrite per-request specified headers
|
|
418
|
+
continue;
|
|
419
|
+
}
|
|
420
|
+
if let (Ok(k), Ok(v)) = (MetadataKey::from_str(k), v.parse()) {
|
|
436
421
|
metadata.insert(k, v);
|
|
437
422
|
}
|
|
438
423
|
}
|
|
439
|
-
if metadata.
|
|
424
|
+
if !metadata.contains_key("grpc-timeout") {
|
|
440
425
|
request.set_timeout(OTHER_CALL_TIMEOUT);
|
|
441
426
|
}
|
|
442
427
|
|
|
@@ -444,15 +429,88 @@ impl Interceptor for ServiceCallInterceptor {
|
|
|
444
429
|
}
|
|
445
430
|
}
|
|
446
431
|
|
|
432
|
+
/// Aggregates various services exposed by the Temporal server
|
|
433
|
+
#[derive(Debug, Clone)]
|
|
434
|
+
pub struct TemporalServiceClient<T> {
|
|
435
|
+
svc: T,
|
|
436
|
+
workflow_svc_client: OnceCell<WorkflowServiceClient<T>>,
|
|
437
|
+
operator_svc_client: OnceCell<OperatorServiceClient<T>>,
|
|
438
|
+
test_svc_client: OnceCell<TestServiceClient<T>>,
|
|
439
|
+
health_svc_client: OnceCell<HealthClient<T>>,
|
|
440
|
+
}
|
|
441
|
+
impl<T> TemporalServiceClient<T>
|
|
442
|
+
where
|
|
443
|
+
T: Clone,
|
|
444
|
+
T: GrpcService<BoxBody> + Send + Clone + 'static,
|
|
445
|
+
T::ResponseBody: tonic::codegen::Body<Data = tonic::codegen::Bytes> + Send + 'static,
|
|
446
|
+
T::Error: Into<tonic::codegen::StdError>,
|
|
447
|
+
<T::ResponseBody as tonic::codegen::Body>::Error: Into<tonic::codegen::StdError> + Send,
|
|
448
|
+
{
|
|
449
|
+
fn new(svc: T) -> Self {
|
|
450
|
+
Self {
|
|
451
|
+
svc,
|
|
452
|
+
workflow_svc_client: OnceCell::new(),
|
|
453
|
+
operator_svc_client: OnceCell::new(),
|
|
454
|
+
test_svc_client: OnceCell::new(),
|
|
455
|
+
health_svc_client: OnceCell::new(),
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
/// Get the underlying workflow service client
|
|
459
|
+
pub fn workflow_svc(&self) -> &WorkflowServiceClient<T> {
|
|
460
|
+
self.workflow_svc_client
|
|
461
|
+
.get_or_init(|| WorkflowServiceClient::new(self.svc.clone()))
|
|
462
|
+
}
|
|
463
|
+
/// Get the underlying operator service client
|
|
464
|
+
pub fn operator_svc(&self) -> &OperatorServiceClient<T> {
|
|
465
|
+
self.operator_svc_client
|
|
466
|
+
.get_or_init(|| OperatorServiceClient::new(self.svc.clone()))
|
|
467
|
+
}
|
|
468
|
+
/// Get the underlying test service client
|
|
469
|
+
pub fn test_svc(&self) -> &TestServiceClient<T> {
|
|
470
|
+
self.test_svc_client
|
|
471
|
+
.get_or_init(|| TestServiceClient::new(self.svc.clone()))
|
|
472
|
+
}
|
|
473
|
+
/// Get the underlying health service client
|
|
474
|
+
pub fn health_svc(&self) -> &HealthClient<T> {
|
|
475
|
+
self.health_svc_client
|
|
476
|
+
.get_or_init(|| HealthClient::new(self.svc.clone()))
|
|
477
|
+
}
|
|
478
|
+
/// Get the underlying workflow service client mutably
|
|
479
|
+
pub fn workflow_svc_mut(&mut self) -> &mut WorkflowServiceClient<T> {
|
|
480
|
+
let _ = self.workflow_svc();
|
|
481
|
+
self.workflow_svc_client.get_mut().unwrap()
|
|
482
|
+
}
|
|
483
|
+
/// Get the underlying operator service client mutably
|
|
484
|
+
pub fn operator_svc_mut(&mut self) -> &mut OperatorServiceClient<T> {
|
|
485
|
+
let _ = self.operator_svc();
|
|
486
|
+
self.operator_svc_client.get_mut().unwrap()
|
|
487
|
+
}
|
|
488
|
+
/// Get the underlying test service client mutably
|
|
489
|
+
pub fn test_svc_mut(&mut self) -> &mut TestServiceClient<T> {
|
|
490
|
+
let _ = self.test_svc();
|
|
491
|
+
self.test_svc_client.get_mut().unwrap()
|
|
492
|
+
}
|
|
493
|
+
/// Get the underlying health service client mutably
|
|
494
|
+
pub fn health_svc_mut(&mut self) -> &mut HealthClient<T> {
|
|
495
|
+
let _ = self.health_svc();
|
|
496
|
+
self.health_svc_client.get_mut().unwrap()
|
|
497
|
+
}
|
|
498
|
+
}
|
|
447
499
|
/// A [WorkflowServiceClient] with the default interceptors attached.
|
|
448
500
|
pub type WorkflowServiceClientWithMetrics = WorkflowServiceClient<InterceptedMetricsSvc>;
|
|
501
|
+
/// An [OperatorServiceClient] with the default interceptors attached.
|
|
502
|
+
pub type OperatorServiceClientWithMetrics = OperatorServiceClient<InterceptedMetricsSvc>;
|
|
503
|
+
/// An [TestServiceClient] with the default interceptors attached.
|
|
504
|
+
pub type TestServiceClientWithMetrics = TestServiceClient<InterceptedMetricsSvc>;
|
|
505
|
+
/// A [TemporalServiceClient] with the default interceptors attached.
|
|
506
|
+
pub type TemporalServiceClientWithMetrics = TemporalServiceClient<InterceptedMetricsSvc>;
|
|
449
507
|
type InterceptedMetricsSvc = InterceptedService<GrpcMetricSvc, ServiceCallInterceptor>;
|
|
450
508
|
|
|
451
509
|
/// Contains an instance of a namespace-bound client for interacting with the Temporal server
|
|
452
510
|
#[derive(Debug, Clone)]
|
|
453
511
|
pub struct Client {
|
|
454
512
|
/// Client for interacting with workflow service
|
|
455
|
-
inner: ConfiguredClient<
|
|
513
|
+
inner: ConfiguredClient<TemporalServiceClientWithMetrics>,
|
|
456
514
|
/// The namespace this client interacts with
|
|
457
515
|
namespace: String,
|
|
458
516
|
/// If set, attach as the worker build id to relevant calls
|
|
@@ -462,7 +520,7 @@ pub struct Client {
|
|
|
462
520
|
impl Client {
|
|
463
521
|
/// Create a new client from an existing configured lower level client and a namespace
|
|
464
522
|
pub fn new(
|
|
465
|
-
client: ConfiguredClient<
|
|
523
|
+
client: ConfiguredClient<TemporalServiceClientWithMetrics>,
|
|
466
524
|
namespace: String,
|
|
467
525
|
) -> Self {
|
|
468
526
|
Client {
|
|
@@ -489,7 +547,7 @@ impl Client {
|
|
|
489
547
|
/// Note that it is reasonably cheap to clone the returned type if you need to own it. Such
|
|
490
548
|
/// clones will keep re-using the same channel.
|
|
491
549
|
pub fn raw_client(&self) -> &WorkflowServiceClientWithMetrics {
|
|
492
|
-
self.inner.
|
|
550
|
+
self.inner.workflow_svc()
|
|
493
551
|
}
|
|
494
552
|
|
|
495
553
|
/// Return the options this client was initialized with
|
|
@@ -499,7 +557,7 @@ impl Client {
|
|
|
499
557
|
|
|
500
558
|
/// Return the options this client was initialized with mutably
|
|
501
559
|
pub fn options_mut(&mut self) -> &mut ClientOptions {
|
|
502
|
-
&mut self.inner.options
|
|
560
|
+
Arc::make_mut(&mut self.inner.options)
|
|
503
561
|
}
|
|
504
562
|
|
|
505
563
|
/// Set a worker build id to be attached to relevant requests. Unlikely to be useful outside
|
|
@@ -507,6 +565,39 @@ impl Client {
|
|
|
507
565
|
pub fn set_worker_build_id(&mut self, id: String) {
|
|
508
566
|
self.bound_worker_build_id = Some(id)
|
|
509
567
|
}
|
|
568
|
+
|
|
569
|
+
/// Returns a reference to the underlying client
|
|
570
|
+
pub fn inner(&self) -> &ConfiguredClient<TemporalServiceClientWithMetrics> {
|
|
571
|
+
&self.inner
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/// Consumes self and returns the underlying client
|
|
575
|
+
pub fn into_inner(self) -> ConfiguredClient<TemporalServiceClientWithMetrics> {
|
|
576
|
+
self.inner
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
fn wf_svc(&self) -> WorkflowServiceClientWithMetrics {
|
|
580
|
+
self.inner.workflow_svc().clone()
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/// Enum to help reference a namespace by either the namespace name or the namespace id
|
|
585
|
+
#[derive(Clone)]
|
|
586
|
+
pub enum Namespace {
|
|
587
|
+
/// Namespace name
|
|
588
|
+
Name(String),
|
|
589
|
+
/// Namespace id
|
|
590
|
+
Id(String),
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
impl Namespace {
|
|
594
|
+
fn into_describe_namespace_request(self) -> DescribeNamespaceRequest {
|
|
595
|
+
let (namespace, id) = match self {
|
|
596
|
+
Namespace::Name(n) => (n, "".to_owned()),
|
|
597
|
+
Namespace::Id(n) => ("".to_owned(), n),
|
|
598
|
+
};
|
|
599
|
+
DescribeNamespaceRequest { namespace, id }
|
|
600
|
+
}
|
|
510
601
|
}
|
|
511
602
|
|
|
512
603
|
/// This trait provides higher-level friendlier interaction with the server.
|
|
@@ -521,25 +612,10 @@ pub trait WorkflowClientTrait {
|
|
|
521
612
|
task_queue: String,
|
|
522
613
|
workflow_id: String,
|
|
523
614
|
workflow_type: String,
|
|
615
|
+
request_id: Option<String>,
|
|
524
616
|
options: WorkflowOptions,
|
|
525
617
|
) -> Result<StartWorkflowExecutionResponse>;
|
|
526
618
|
|
|
527
|
-
/// Fetch new workflow tasks from the provided queue. Should block indefinitely if there is no
|
|
528
|
-
/// work.
|
|
529
|
-
async fn poll_workflow_task(
|
|
530
|
-
&self,
|
|
531
|
-
task_queue: String,
|
|
532
|
-
is_sticky: bool,
|
|
533
|
-
) -> Result<PollWorkflowTaskQueueResponse>;
|
|
534
|
-
|
|
535
|
-
/// Fetch new activity tasks from the provided queue. Should block indefinitely if there is no
|
|
536
|
-
/// work.
|
|
537
|
-
async fn poll_activity_task(
|
|
538
|
-
&self,
|
|
539
|
-
task_queue: String,
|
|
540
|
-
max_tasks_per_sec: Option<f64>,
|
|
541
|
-
) -> Result<PollActivityTaskQueueResponse>;
|
|
542
|
-
|
|
543
619
|
/// Notifies the server that workflow tasks for a given workflow should be sent to the normal
|
|
544
620
|
/// non-sticky task queue. This normally happens when workflow has been evicted from the cache.
|
|
545
621
|
async fn reset_sticky_task_queue(
|
|
@@ -548,12 +624,6 @@ pub trait WorkflowClientTrait {
|
|
|
548
624
|
run_id: String,
|
|
549
625
|
) -> Result<ResetStickyTaskQueueResponse>;
|
|
550
626
|
|
|
551
|
-
/// Complete a workflow activation.
|
|
552
|
-
async fn complete_workflow_task(
|
|
553
|
-
&self,
|
|
554
|
-
request: WorkflowTaskCompletion,
|
|
555
|
-
) -> Result<RespondWorkflowTaskCompletedResponse>;
|
|
556
|
-
|
|
557
627
|
/// Complete activity task by sending response to the server. `task_token` contains activity
|
|
558
628
|
/// identifier that would've been received from polling for an activity task. `result` is a blob
|
|
559
629
|
/// that contains activity response.
|
|
@@ -607,6 +677,7 @@ pub trait WorkflowClientTrait {
|
|
|
607
677
|
run_id: String,
|
|
608
678
|
signal_name: String,
|
|
609
679
|
payloads: Option<Payloads>,
|
|
680
|
+
request_id: Option<String>,
|
|
610
681
|
) -> Result<SignalWorkflowExecutionResponse>;
|
|
611
682
|
|
|
612
683
|
/// Send signal and start workflow transcationally
|
|
@@ -618,9 +689,11 @@ pub trait WorkflowClientTrait {
|
|
|
618
689
|
task_queue: String,
|
|
619
690
|
workflow_id: String,
|
|
620
691
|
workflow_type: String,
|
|
692
|
+
request_id: Option<String>,
|
|
621
693
|
options: WorkflowOptions,
|
|
622
694
|
signal_name: String,
|
|
623
695
|
signal_input: Option<Payloads>,
|
|
696
|
+
signal_header: Option<Header>,
|
|
624
697
|
) -> Result<SignalWithStartWorkflowExecutionResponse>;
|
|
625
698
|
|
|
626
699
|
/// Request a query of a certain workflow instance
|
|
@@ -659,6 +732,7 @@ pub trait WorkflowClientTrait {
|
|
|
659
732
|
workflow_id: String,
|
|
660
733
|
run_id: Option<String>,
|
|
661
734
|
reason: String,
|
|
735
|
+
request_id: Option<String>,
|
|
662
736
|
) -> Result<RequestCancelWorkflowExecutionResponse>;
|
|
663
737
|
|
|
664
738
|
/// Terminate a currently executing workflow
|
|
@@ -671,6 +745,35 @@ pub trait WorkflowClientTrait {
|
|
|
671
745
|
/// Lists all available namespaces
|
|
672
746
|
async fn list_namespaces(&self) -> Result<ListNamespacesResponse>;
|
|
673
747
|
|
|
748
|
+
/// Query namespace details
|
|
749
|
+
async fn describe_namespace(&self, namespace: Namespace) -> Result<DescribeNamespaceResponse>;
|
|
750
|
+
|
|
751
|
+
/// List open workflows with Standard Visibility filtering
|
|
752
|
+
async fn list_open_workflow_executions(
|
|
753
|
+
&self,
|
|
754
|
+
max_page_size: i32,
|
|
755
|
+
next_page_token: Vec<u8>,
|
|
756
|
+
start_time_filter: Option<StartTimeFilter>,
|
|
757
|
+
filters: Option<ListOpenFilters>,
|
|
758
|
+
) -> Result<ListOpenWorkflowExecutionsResponse>;
|
|
759
|
+
|
|
760
|
+
/// List closed workflows Standard Visibility filtering
|
|
761
|
+
async fn list_closed_workflow_executions(
|
|
762
|
+
&self,
|
|
763
|
+
max_page_size: i32,
|
|
764
|
+
next_page_token: Vec<u8>,
|
|
765
|
+
start_time_filter: Option<StartTimeFilter>,
|
|
766
|
+
filters: Option<ListClosedFilters>,
|
|
767
|
+
) -> Result<ListClosedWorkflowExecutionsResponse>;
|
|
768
|
+
|
|
769
|
+
/// List workflows with Advanced Visibility filtering
|
|
770
|
+
async fn list_workflow_executions(
|
|
771
|
+
&self,
|
|
772
|
+
max_page_size: i32,
|
|
773
|
+
next_page_token: Vec<u8>,
|
|
774
|
+
query: String,
|
|
775
|
+
) -> Result<ListWorkflowExecutionsResponse>;
|
|
776
|
+
|
|
674
777
|
/// Returns options that were used to initialize the client
|
|
675
778
|
fn get_options(&self) -> &ClientOptions;
|
|
676
779
|
|
|
@@ -681,9 +784,22 @@ pub trait WorkflowClientTrait {
|
|
|
681
784
|
/// Optional fields supplied at the start of workflow execution
|
|
682
785
|
#[derive(Debug, Clone, Default)]
|
|
683
786
|
pub struct WorkflowOptions {
|
|
684
|
-
///
|
|
787
|
+
/// Set the policy for reusing the workflow id
|
|
788
|
+
pub id_reuse_policy: WorkflowIdReusePolicy,
|
|
789
|
+
|
|
790
|
+
/// Optionally set the execution timeout for the workflow
|
|
791
|
+
/// <https://docs.temporal.io/workflows/#workflow-execution-timeout>
|
|
792
|
+
pub execution_timeout: Option<Duration>,
|
|
793
|
+
|
|
794
|
+
/// Optionally indicates the default run timeout for a workflow run
|
|
795
|
+
pub run_timeout: Option<Duration>,
|
|
796
|
+
|
|
797
|
+
/// Optionally indicates the default task timeout for a workflow run
|
|
685
798
|
pub task_timeout: Option<Duration>,
|
|
686
799
|
|
|
800
|
+
/// Optionally set a cron schedule for the workflow
|
|
801
|
+
pub cron_schedule: Option<String>,
|
|
802
|
+
|
|
687
803
|
/// Optionally associate extra search attributes with a workflow
|
|
688
804
|
pub search_attributes: Option<HashMap<String, Payload>>,
|
|
689
805
|
}
|
|
@@ -696,10 +812,9 @@ impl WorkflowClientTrait for Client {
|
|
|
696
812
|
task_queue: String,
|
|
697
813
|
workflow_id: String,
|
|
698
814
|
workflow_type: String,
|
|
815
|
+
request_id: Option<String>,
|
|
699
816
|
options: WorkflowOptions,
|
|
700
817
|
) -> Result<StartWorkflowExecutionResponse> {
|
|
701
|
-
let request_id = Uuid::new_v4().to_string();
|
|
702
|
-
|
|
703
818
|
Ok(self
|
|
704
819
|
.wf_svc()
|
|
705
820
|
.start_workflow_execution(StartWorkflowExecutionRequest {
|
|
@@ -713,65 +828,21 @@ impl WorkflowClientTrait for Client {
|
|
|
713
828
|
name: task_queue,
|
|
714
829
|
kind: TaskQueueKind::Unspecified as i32,
|
|
715
830
|
}),
|
|
716
|
-
request_id,
|
|
717
|
-
|
|
718
|
-
|
|
831
|
+
request_id: request_id.unwrap_or_else(|| Uuid::new_v4().to_string()),
|
|
832
|
+
workflow_id_reuse_policy: options.id_reuse_policy as i32,
|
|
833
|
+
workflow_execution_timeout: options
|
|
834
|
+
.execution_timeout
|
|
835
|
+
.and_then(|d| d.try_into().ok()),
|
|
836
|
+
workflow_run_timeout: options.execution_timeout.and_then(|d| d.try_into().ok()),
|
|
837
|
+
workflow_task_timeout: options.task_timeout.and_then(|d| d.try_into().ok()),
|
|
838
|
+
search_attributes: options.search_attributes.and_then(|d| d.try_into().ok()),
|
|
839
|
+
cron_schedule: options.cron_schedule.unwrap_or_default(),
|
|
719
840
|
..Default::default()
|
|
720
841
|
})
|
|
721
842
|
.await?
|
|
722
843
|
.into_inner())
|
|
723
844
|
}
|
|
724
845
|
|
|
725
|
-
async fn poll_workflow_task(
|
|
726
|
-
&self,
|
|
727
|
-
task_queue: String,
|
|
728
|
-
is_sticky: bool,
|
|
729
|
-
) -> Result<PollWorkflowTaskQueueResponse> {
|
|
730
|
-
let request = PollWorkflowTaskQueueRequest {
|
|
731
|
-
namespace: self.namespace.clone(),
|
|
732
|
-
task_queue: Some(TaskQueue {
|
|
733
|
-
name: task_queue,
|
|
734
|
-
kind: if is_sticky {
|
|
735
|
-
TaskQueueKind::Sticky
|
|
736
|
-
} else {
|
|
737
|
-
TaskQueueKind::Normal
|
|
738
|
-
} as i32,
|
|
739
|
-
}),
|
|
740
|
-
identity: self.inner.options.identity.clone(),
|
|
741
|
-
binary_checksum: self.bound_worker_build_id.clone().unwrap_or_default(),
|
|
742
|
-
};
|
|
743
|
-
|
|
744
|
-
Ok(self
|
|
745
|
-
.wf_svc()
|
|
746
|
-
.poll_workflow_task_queue(request)
|
|
747
|
-
.await?
|
|
748
|
-
.into_inner())
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
async fn poll_activity_task(
|
|
752
|
-
&self,
|
|
753
|
-
task_queue: String,
|
|
754
|
-
max_tasks_per_sec: Option<f64>,
|
|
755
|
-
) -> Result<PollActivityTaskQueueResponse> {
|
|
756
|
-
let request = PollActivityTaskQueueRequest {
|
|
757
|
-
namespace: self.namespace.clone(),
|
|
758
|
-
task_queue: Some(TaskQueue {
|
|
759
|
-
name: task_queue,
|
|
760
|
-
kind: TaskQueueKind::Normal as i32,
|
|
761
|
-
}),
|
|
762
|
-
identity: self.inner.options.identity.clone(),
|
|
763
|
-
task_queue_metadata: max_tasks_per_sec.map(|tps| TaskQueueMetadata {
|
|
764
|
-
max_tasks_per_second: Some(tps),
|
|
765
|
-
}),
|
|
766
|
-
};
|
|
767
|
-
|
|
768
|
-
Ok(self
|
|
769
|
-
.wf_svc()
|
|
770
|
-
.poll_activity_task_queue(request)
|
|
771
|
-
.await?
|
|
772
|
-
.into_inner())
|
|
773
|
-
}
|
|
774
|
-
|
|
775
846
|
async fn reset_sticky_task_queue(
|
|
776
847
|
&self,
|
|
777
848
|
workflow_id: String,
|
|
@@ -791,42 +862,6 @@ impl WorkflowClientTrait for Client {
|
|
|
791
862
|
.into_inner())
|
|
792
863
|
}
|
|
793
864
|
|
|
794
|
-
async fn complete_workflow_task(
|
|
795
|
-
&self,
|
|
796
|
-
request: WorkflowTaskCompletion,
|
|
797
|
-
) -> Result<RespondWorkflowTaskCompletedResponse> {
|
|
798
|
-
let request = RespondWorkflowTaskCompletedRequest {
|
|
799
|
-
task_token: request.task_token.into(),
|
|
800
|
-
commands: request.commands,
|
|
801
|
-
identity: self.inner.options.identity.clone(),
|
|
802
|
-
sticky_attributes: request.sticky_attributes,
|
|
803
|
-
return_new_workflow_task: request.return_new_workflow_task,
|
|
804
|
-
force_create_new_workflow_task: request.force_create_new_workflow_task,
|
|
805
|
-
binary_checksum: self.bound_worker_build_id.clone().unwrap_or_default(),
|
|
806
|
-
query_results: request
|
|
807
|
-
.query_responses
|
|
808
|
-
.into_iter()
|
|
809
|
-
.map(|qr| {
|
|
810
|
-
let (id, completed_type, query_result, error_message) = qr.into_components();
|
|
811
|
-
(
|
|
812
|
-
id,
|
|
813
|
-
WorkflowQueryResult {
|
|
814
|
-
result_type: completed_type as i32,
|
|
815
|
-
answer: query_result,
|
|
816
|
-
error_message,
|
|
817
|
-
},
|
|
818
|
-
)
|
|
819
|
-
})
|
|
820
|
-
.collect(),
|
|
821
|
-
namespace: self.namespace.clone(),
|
|
822
|
-
};
|
|
823
|
-
Ok(self
|
|
824
|
-
.wf_svc()
|
|
825
|
-
.respond_workflow_task_completed(request)
|
|
826
|
-
.await?
|
|
827
|
-
.into_inner())
|
|
828
|
-
}
|
|
829
|
-
|
|
830
865
|
async fn complete_activity_task(
|
|
831
866
|
&self,
|
|
832
867
|
task_token: TaskToken,
|
|
@@ -924,6 +959,7 @@ impl WorkflowClientTrait for Client {
|
|
|
924
959
|
run_id: String,
|
|
925
960
|
signal_name: String,
|
|
926
961
|
payloads: Option<Payloads>,
|
|
962
|
+
request_id: Option<String>,
|
|
927
963
|
) -> Result<SignalWorkflowExecutionResponse> {
|
|
928
964
|
Ok(self
|
|
929
965
|
.wf_svc()
|
|
@@ -936,6 +972,7 @@ impl WorkflowClientTrait for Client {
|
|
|
936
972
|
signal_name,
|
|
937
973
|
input: payloads,
|
|
938
974
|
identity: self.inner.options.identity.clone(),
|
|
975
|
+
request_id: request_id.unwrap_or_else(|| Uuid::new_v4().to_string()),
|
|
939
976
|
..Default::default()
|
|
940
977
|
})
|
|
941
978
|
.await?
|
|
@@ -948,11 +985,12 @@ impl WorkflowClientTrait for Client {
|
|
|
948
985
|
task_queue: String,
|
|
949
986
|
workflow_id: String,
|
|
950
987
|
workflow_type: String,
|
|
988
|
+
request_id: Option<String>,
|
|
951
989
|
options: WorkflowOptions,
|
|
952
990
|
signal_name: String,
|
|
953
991
|
signal_input: Option<Payloads>,
|
|
992
|
+
signal_header: Option<Header>,
|
|
954
993
|
) -> Result<SignalWithStartWorkflowExecutionResponse> {
|
|
955
|
-
let request_id = Uuid::new_v4().to_string();
|
|
956
994
|
Ok(self
|
|
957
995
|
.wf_svc()
|
|
958
996
|
.signal_with_start_workflow_execution(SignalWithStartWorkflowExecutionRequest {
|
|
@@ -965,13 +1003,20 @@ impl WorkflowClientTrait for Client {
|
|
|
965
1003
|
name: task_queue,
|
|
966
1004
|
kind: TaskQueueKind::Normal as i32,
|
|
967
1005
|
}),
|
|
968
|
-
request_id,
|
|
969
1006
|
input,
|
|
970
1007
|
signal_name,
|
|
971
1008
|
signal_input,
|
|
972
1009
|
identity: self.inner.options.identity.clone(),
|
|
973
|
-
|
|
974
|
-
|
|
1010
|
+
request_id: request_id.unwrap_or_else(|| Uuid::new_v4().to_string()),
|
|
1011
|
+
workflow_id_reuse_policy: options.id_reuse_policy as i32,
|
|
1012
|
+
workflow_execution_timeout: options
|
|
1013
|
+
.execution_timeout
|
|
1014
|
+
.and_then(|d| d.try_into().ok()),
|
|
1015
|
+
workflow_run_timeout: options.execution_timeout.and_then(|d| d.try_into().ok()),
|
|
1016
|
+
workflow_task_timeout: options.task_timeout.and_then(|d| d.try_into().ok()),
|
|
1017
|
+
search_attributes: options.search_attributes.and_then(|d| d.try_into().ok()),
|
|
1018
|
+
cron_schedule: options.cron_schedule.unwrap_or_default(),
|
|
1019
|
+
header: signal_header,
|
|
975
1020
|
..Default::default()
|
|
976
1021
|
})
|
|
977
1022
|
.await?
|
|
@@ -1062,6 +1107,7 @@ impl WorkflowClientTrait for Client {
|
|
|
1062
1107
|
workflow_id: String,
|
|
1063
1108
|
run_id: Option<String>,
|
|
1064
1109
|
reason: String,
|
|
1110
|
+
request_id: Option<String>,
|
|
1065
1111
|
) -> Result<RequestCancelWorkflowExecutionResponse> {
|
|
1066
1112
|
Ok(self
|
|
1067
1113
|
.wf_svc()
|
|
@@ -1072,7 +1118,7 @@ impl WorkflowClientTrait for Client {
|
|
|
1072
1118
|
run_id: run_id.unwrap_or_default(),
|
|
1073
1119
|
}),
|
|
1074
1120
|
identity: self.inner.options.identity.clone(),
|
|
1075
|
-
request_id:
|
|
1121
|
+
request_id: request_id.unwrap_or_else(|| Uuid::new_v4().to_string()),
|
|
1076
1122
|
first_execution_run_id: "".to_string(),
|
|
1077
1123
|
reason,
|
|
1078
1124
|
})
|
|
@@ -1110,6 +1156,72 @@ impl WorkflowClientTrait for Client {
|
|
|
1110
1156
|
.into_inner())
|
|
1111
1157
|
}
|
|
1112
1158
|
|
|
1159
|
+
async fn describe_namespace(&self, namespace: Namespace) -> Result<DescribeNamespaceResponse> {
|
|
1160
|
+
Ok(self
|
|
1161
|
+
.wf_svc()
|
|
1162
|
+
.describe_namespace(namespace.into_describe_namespace_request())
|
|
1163
|
+
.await?
|
|
1164
|
+
.into_inner())
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
async fn list_open_workflow_executions(
|
|
1168
|
+
&self,
|
|
1169
|
+
maximum_page_size: i32,
|
|
1170
|
+
next_page_token: Vec<u8>,
|
|
1171
|
+
start_time_filter: Option<StartTimeFilter>,
|
|
1172
|
+
filters: Option<ListOpenFilters>,
|
|
1173
|
+
) -> Result<ListOpenWorkflowExecutionsResponse> {
|
|
1174
|
+
Ok(self
|
|
1175
|
+
.wf_svc()
|
|
1176
|
+
.list_open_workflow_executions(ListOpenWorkflowExecutionsRequest {
|
|
1177
|
+
namespace: self.namespace.clone(),
|
|
1178
|
+
maximum_page_size,
|
|
1179
|
+
next_page_token,
|
|
1180
|
+
start_time_filter,
|
|
1181
|
+
filters,
|
|
1182
|
+
})
|
|
1183
|
+
.await?
|
|
1184
|
+
.into_inner())
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
async fn list_closed_workflow_executions(
|
|
1188
|
+
&self,
|
|
1189
|
+
maximum_page_size: i32,
|
|
1190
|
+
next_page_token: Vec<u8>,
|
|
1191
|
+
start_time_filter: Option<StartTimeFilter>,
|
|
1192
|
+
filters: Option<ListClosedFilters>,
|
|
1193
|
+
) -> Result<ListClosedWorkflowExecutionsResponse> {
|
|
1194
|
+
Ok(self
|
|
1195
|
+
.wf_svc()
|
|
1196
|
+
.list_closed_workflow_executions(ListClosedWorkflowExecutionsRequest {
|
|
1197
|
+
namespace: self.namespace.clone(),
|
|
1198
|
+
maximum_page_size,
|
|
1199
|
+
next_page_token,
|
|
1200
|
+
start_time_filter,
|
|
1201
|
+
filters,
|
|
1202
|
+
})
|
|
1203
|
+
.await?
|
|
1204
|
+
.into_inner())
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
async fn list_workflow_executions(
|
|
1208
|
+
&self,
|
|
1209
|
+
page_size: i32,
|
|
1210
|
+
next_page_token: Vec<u8>,
|
|
1211
|
+
query: String,
|
|
1212
|
+
) -> Result<ListWorkflowExecutionsResponse> {
|
|
1213
|
+
Ok(self
|
|
1214
|
+
.wf_svc()
|
|
1215
|
+
.list_workflow_executions(ListWorkflowExecutionsRequest {
|
|
1216
|
+
namespace: self.namespace.clone(),
|
|
1217
|
+
page_size,
|
|
1218
|
+
next_page_token,
|
|
1219
|
+
query,
|
|
1220
|
+
})
|
|
1221
|
+
.await?
|
|
1222
|
+
.into_inner())
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1113
1225
|
fn get_options(&self) -> &ClientOptions {
|
|
1114
1226
|
&self.inner.options
|
|
1115
1227
|
}
|
|
@@ -1122,39 +1234,28 @@ impl WorkflowClientTrait for Client {
|
|
|
1122
1234
|
mod sealed {
|
|
1123
1235
|
use crate::{InterceptedMetricsSvc, RawClientLike, WorkflowClientTrait};
|
|
1124
1236
|
|
|
1125
|
-
pub trait
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
fn wf_svc(&self) -> Self::RawClientT;
|
|
1237
|
+
pub trait WfHandleClient:
|
|
1238
|
+
WorkflowClientTrait + RawClientLike<SvcType = InterceptedMetricsSvc>
|
|
1239
|
+
{
|
|
1129
1240
|
}
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
}
|
|
1134
|
-
|
|
1135
|
-
impl RawClientLikeUser for Client {
|
|
1136
|
-
type RawClientT = WorkflowServiceClientWithMetrics;
|
|
1137
|
-
|
|
1138
|
-
fn wf_svc(&self) -> Self::RawClientT {
|
|
1139
|
-
self.raw_client().clone()
|
|
1241
|
+
impl<T> WfHandleClient for T where
|
|
1242
|
+
T: WorkflowClientTrait + RawClientLike<SvcType = InterceptedMetricsSvc>
|
|
1243
|
+
{
|
|
1140
1244
|
}
|
|
1141
1245
|
}
|
|
1142
1246
|
|
|
1143
1247
|
/// Additional methods for workflow clients
|
|
1144
|
-
pub trait WfClientExt: WfHandleClient + Sized {
|
|
1248
|
+
pub trait WfClientExt: WfHandleClient + Sized + Clone {
|
|
1145
1249
|
/// Create an untyped handle for a workflow execution, which can be used to do things like
|
|
1146
1250
|
/// wait for that workflow's result. `run_id` may be left blank to target the latest run.
|
|
1147
1251
|
fn get_untyped_workflow_handle(
|
|
1148
1252
|
&self,
|
|
1149
1253
|
workflow_id: impl Into<String>,
|
|
1150
1254
|
run_id: impl Into<String>,
|
|
1151
|
-
) -> UntypedWorkflowHandle<Self
|
|
1152
|
-
where
|
|
1153
|
-
Self::RawClientT: Clone,
|
|
1154
|
-
{
|
|
1255
|
+
) -> UntypedWorkflowHandle<Self> {
|
|
1155
1256
|
let rid = run_id.into();
|
|
1156
1257
|
UntypedWorkflowHandle::new(
|
|
1157
|
-
self.
|
|
1258
|
+
self.clone(),
|
|
1158
1259
|
WorkflowExecutionInfo {
|
|
1159
1260
|
namespace: self.namespace().to_string(),
|
|
1160
1261
|
workflow_id: workflow_id.into(),
|
|
@@ -1163,4 +1264,31 @@ pub trait WfClientExt: WfHandleClient + Sized {
|
|
|
1163
1264
|
)
|
|
1164
1265
|
}
|
|
1165
1266
|
}
|
|
1166
|
-
impl<T> WfClientExt for T where T: WfHandleClient + Sized {}
|
|
1267
|
+
impl<T> WfClientExt for T where T: WfHandleClient + Clone + Sized {}
|
|
1268
|
+
|
|
1269
|
+
#[cfg(test)]
|
|
1270
|
+
mod tests {
|
|
1271
|
+
use super::*;
|
|
1272
|
+
|
|
1273
|
+
#[test]
|
|
1274
|
+
fn respects_per_call_headers() {
|
|
1275
|
+
let opts = ClientOptionsBuilder::default()
|
|
1276
|
+
.identity("enchicat".to_string())
|
|
1277
|
+
.target_url(Url::parse("https://smolkitty").unwrap())
|
|
1278
|
+
.client_name("cute-kitty".to_string())
|
|
1279
|
+
.client_version("0.1.0".to_string())
|
|
1280
|
+
.build()
|
|
1281
|
+
.unwrap();
|
|
1282
|
+
|
|
1283
|
+
let mut static_headers = HashMap::new();
|
|
1284
|
+
static_headers.insert("enchi".to_string(), "kitty".to_string());
|
|
1285
|
+
let mut iceptor = ServiceCallInterceptor {
|
|
1286
|
+
opts,
|
|
1287
|
+
headers: Arc::new(RwLock::new(static_headers)),
|
|
1288
|
+
};
|
|
1289
|
+
let mut req = tonic::Request::new(());
|
|
1290
|
+
req.metadata_mut().insert("enchi", "cat".parse().unwrap());
|
|
1291
|
+
let next_req = iceptor.call(req).unwrap();
|
|
1292
|
+
assert_eq!(next_req.metadata().get("enchi").unwrap(), "cat");
|
|
1293
|
+
}
|
|
1294
|
+
}
|