@temporalio/core-bridge 1.4.4 → 1.5.1
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 +327 -419
- package/Cargo.toml +1 -1
- package/index.js +25 -2
- package/lib/errors.d.ts +22 -0
- package/lib/errors.js +65 -0
- package/lib/errors.js.map +1 -0
- package/lib/index.d.ts +440 -0
- package/lib/index.js +8 -0
- package/lib/index.js.map +1 -0
- package/package.json +11 -5
- 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/sdk-core/.buildkite/docker/Dockerfile +1 -1
- package/sdk-core/.buildkite/docker/docker-compose.yaml +2 -2
- package/sdk-core/bridge-ffi/Cargo.toml +1 -1
- package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +0 -25
- package/sdk-core/bridge-ffi/src/lib.rs +29 -108
- package/sdk-core/bridge-ffi/src/wrappers.rs +35 -25
- package/sdk-core/client/Cargo.toml +1 -1
- package/sdk-core/client/src/lib.rs +12 -20
- package/sdk-core/client/src/raw.rs +9 -8
- package/sdk-core/client/src/retry.rs +100 -23
- package/sdk-core/core/Cargo.toml +5 -5
- package/sdk-core/core/benches/workflow_replay.rs +13 -10
- package/sdk-core/core/src/abstractions.rs +22 -22
- package/sdk-core/core/src/core_tests/activity_tasks.rs +1 -1
- package/sdk-core/core/src/core_tests/local_activities.rs +228 -6
- package/sdk-core/core/src/core_tests/queries.rs +247 -89
- package/sdk-core/core/src/core_tests/workers.rs +2 -2
- package/sdk-core/core/src/core_tests/workflow_cancels.rs +1 -1
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +46 -27
- package/sdk-core/core/src/lib.rs +139 -32
- package/sdk-core/core/src/replay/mod.rs +185 -41
- package/sdk-core/core/src/telemetry/log_export.rs +190 -0
- package/sdk-core/core/src/telemetry/metrics.rs +184 -139
- package/sdk-core/core/src/telemetry/mod.rs +296 -318
- package/sdk-core/core/src/telemetry/prometheus_server.rs +4 -3
- package/sdk-core/core/src/test_help/mod.rs +9 -7
- package/sdk-core/core/src/worker/activities/local_activities.rs +2 -1
- package/sdk-core/core/src/worker/activities.rs +40 -23
- package/sdk-core/core/src/worker/client/mocks.rs +1 -1
- package/sdk-core/core/src/worker/client.rs +30 -4
- package/sdk-core/core/src/worker/mod.rs +22 -18
- package/sdk-core/core/src/worker/workflow/driven_workflow.rs +10 -19
- package/sdk-core/core/src/worker/workflow/history_update.rs +99 -25
- package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +2 -6
- package/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +18 -21
- package/sdk-core/core/src/worker/workflow/machines/mod.rs +12 -38
- package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +178 -0
- package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +8 -2
- package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +1 -5
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +232 -216
- package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +1 -6
- package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +4 -4
- package/sdk-core/core/src/worker/workflow/managed_run.rs +13 -5
- package/sdk-core/core/src/worker/workflow/mod.rs +61 -9
- package/sdk-core/core/src/worker/workflow/wft_poller.rs +2 -2
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +56 -11
- package/sdk-core/core-api/Cargo.toml +4 -3
- package/sdk-core/core-api/src/lib.rs +1 -43
- package/sdk-core/core-api/src/telemetry.rs +147 -0
- package/sdk-core/core-api/src/worker.rs +13 -0
- package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +1 -1
- package/sdk-core/histories/evict_while_la_running_no_interference-23_history.bin +0 -0
- package/sdk-core/histories/evict_while_la_running_no_interference-85_history.bin +0 -0
- package/sdk-core/protos/api_upstream/.github/CODEOWNERS +1 -1
- package/sdk-core/protos/api_upstream/buf.yaml +0 -3
- package/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +3 -7
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +8 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +1 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +2 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +3 -0
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +13 -0
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +19 -59
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +0 -19
- package/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +108 -29
- package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +2 -2
- 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 +47 -8
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +15 -1
- package/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +2 -0
- package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +8 -1
- package/sdk-core/sdk/src/interceptors.rs +36 -3
- package/sdk-core/sdk/src/lib.rs +7 -4
- package/sdk-core/sdk/src/workflow_context.rs +13 -2
- package/sdk-core/sdk-core-protos/src/history_builder.rs +47 -1
- package/sdk-core/sdk-core-protos/src/history_info.rs +22 -22
- package/sdk-core/sdk-core-protos/src/lib.rs +49 -27
- package/sdk-core/test-utils/Cargo.toml +1 -0
- package/sdk-core/test-utils/src/lib.rs +81 -29
- package/sdk-core/tests/integ_tests/metrics_tests.rs +37 -0
- package/sdk-core/tests/integ_tests/polling_tests.rs +0 -13
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +145 -4
- package/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +53 -0
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +106 -20
- package/sdk-core/tests/integ_tests/workflow_tests.rs +18 -8
- package/sdk-core/tests/main.rs +6 -4
- package/src/conversions.rs +52 -47
- package/src/errors.rs +28 -86
- package/src/helpers.rs +3 -4
- package/src/lib.rs +2 -2
- package/src/runtime.rs +132 -61
- package/src/testing.rs +7 -4
- package/src/worker.rs +67 -50
- package/ts/errors.ts +55 -0
- package/{index.d.ts → ts/index.ts} +121 -15
- package/sdk-core/core/src/log_export.rs +0 -62
- package/sdk-core/core/src/worker/workflow/machines/mutable_side_effect_state_machine.rs +0 -127
- package/sdk-core/core/src/worker/workflow/machines/side_effect_state_machine.rs +0 -71
- package/sdk-core/protos/api_upstream/temporal/api/cluster/v1/message.proto +0 -83
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/cluster.proto +0 -40
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
use crate::telemetry::
|
|
1
|
+
use crate::telemetry::default_resource;
|
|
2
2
|
use hyper::{
|
|
3
3
|
header::CONTENT_TYPE,
|
|
4
4
|
service::{make_service_fn, service_fn},
|
|
@@ -7,7 +7,7 @@ use hyper::{
|
|
|
7
7
|
use opentelemetry::{
|
|
8
8
|
metrics::MetricsError,
|
|
9
9
|
sdk::{
|
|
10
|
-
export::metrics::aggregation::TemporalitySelector,
|
|
10
|
+
export::metrics::{aggregation::TemporalitySelector, AggregatorSelector},
|
|
11
11
|
metrics::{controllers, processors},
|
|
12
12
|
},
|
|
13
13
|
};
|
|
@@ -24,10 +24,11 @@ pub(super) struct PromServer {
|
|
|
24
24
|
impl PromServer {
|
|
25
25
|
pub fn new(
|
|
26
26
|
addr: SocketAddr,
|
|
27
|
+
aggregation: impl AggregatorSelector + Send + Sync + 'static,
|
|
27
28
|
temporality: impl TemporalitySelector + Send + Sync + 'static,
|
|
28
29
|
) -> Result<Self, MetricsError> {
|
|
29
30
|
let controller =
|
|
30
|
-
controllers::basic(processors::factory(
|
|
31
|
+
controllers::basic(processors::factory(aggregation, temporality).with_memory(true))
|
|
31
32
|
.with_resource(default_resource())
|
|
32
33
|
.build();
|
|
33
34
|
let exporter = ExporterBuilder::new(controller).try_init()?;
|
|
@@ -5,8 +5,11 @@ use crate::{
|
|
|
5
5
|
protosext::ValidPollWFTQResponse,
|
|
6
6
|
replay::TestHistoryBuilder,
|
|
7
7
|
sticky_q_name_for_worker,
|
|
8
|
+
telemetry::metrics::MetricsContext,
|
|
8
9
|
worker::{
|
|
9
|
-
client::{
|
|
10
|
+
client::{
|
|
11
|
+
mocks::mock_workflow_client, MockWorkerClient, WorkerClient, WorkflowTaskCompletion,
|
|
12
|
+
},
|
|
10
13
|
new_wft_poller,
|
|
11
14
|
},
|
|
12
15
|
TaskToken, Worker, WorkerConfig, WorkerConfigBuilder,
|
|
@@ -26,7 +29,6 @@ use std::{
|
|
|
26
29
|
task::{Context, Poll},
|
|
27
30
|
time::Duration,
|
|
28
31
|
};
|
|
29
|
-
use temporal_client::WorkflowTaskCompletion;
|
|
30
32
|
use temporal_sdk_core_api::Worker as WorkerTrait;
|
|
31
33
|
use temporal_sdk_core_protos::{
|
|
32
34
|
coresdk::{
|
|
@@ -57,6 +59,7 @@ pub fn test_worker_cfg() -> WorkerConfigBuilder {
|
|
|
57
59
|
wcb.namespace("default")
|
|
58
60
|
.task_queue(TEST_Q)
|
|
59
61
|
.worker_build_id("test_bin_id")
|
|
62
|
+
.ignore_evicts_on_shutdown(true)
|
|
60
63
|
// Serial polling since it makes mocking much easier.
|
|
61
64
|
.max_concurrent_wft_polls(1_usize);
|
|
62
65
|
wcb
|
|
@@ -144,7 +147,7 @@ pub(crate) fn mock_worker(mocks: MocksHolder) -> Worker {
|
|
|
144
147
|
mocks.client,
|
|
145
148
|
mocks.inputs.wft_stream,
|
|
146
149
|
act_poller,
|
|
147
|
-
|
|
150
|
+
MetricsContext::no_op(),
|
|
148
151
|
CancellationToken::new(),
|
|
149
152
|
)
|
|
150
153
|
}
|
|
@@ -214,7 +217,7 @@ impl MockWorkerInputs {
|
|
|
214
217
|
}
|
|
215
218
|
pub fn new_from_poller(wf_poller: BoxedWFPoller) -> Self {
|
|
216
219
|
Self {
|
|
217
|
-
wft_stream: new_wft_poller(wf_poller,
|
|
220
|
+
wft_stream: new_wft_poller(wf_poller, MetricsContext::no_op()).boxed(),
|
|
218
221
|
act_poller: None,
|
|
219
222
|
config: test_worker_cfg().build().unwrap(),
|
|
220
223
|
}
|
|
@@ -503,7 +506,7 @@ pub(crate) fn build_mock_pollers(mut cfg: MockPollCfg) -> MocksHolder {
|
|
|
503
506
|
.into_iter()
|
|
504
507
|
.map(|response| {
|
|
505
508
|
let cur_attempt = attempts_at_task_num.entry(response.hashable()).or_insert(1);
|
|
506
|
-
let mut r = hist_to_poll_resp(&hist.hist, hist.wf_id.clone(), response
|
|
509
|
+
let mut r = hist_to_poll_resp(&hist.hist, hist.wf_id.clone(), response);
|
|
507
510
|
r.attempt = *cur_attempt;
|
|
508
511
|
*cur_attempt += 1;
|
|
509
512
|
r
|
|
@@ -654,7 +657,6 @@ pub fn hist_to_poll_resp(
|
|
|
654
657
|
t: &TestHistoryBuilder,
|
|
655
658
|
wf_id: impl Into<String>,
|
|
656
659
|
response_type: ResponseType,
|
|
657
|
-
task_queue: impl Into<String>,
|
|
658
660
|
) -> QueueResponse<PollWorkflowTaskQueueResponse> {
|
|
659
661
|
let run_id = t.get_orig_run_id();
|
|
660
662
|
let wf = WorkflowExecution {
|
|
@@ -683,7 +685,7 @@ pub fn hist_to_poll_resp(
|
|
|
683
685
|
}
|
|
684
686
|
}
|
|
685
687
|
};
|
|
686
|
-
let mut resp = hist_info.as_poll_wft_response(
|
|
688
|
+
let mut resp = hist_info.as_poll_wft_response();
|
|
687
689
|
resp.workflow_execution = Some(wf);
|
|
688
690
|
QueueResponse { resp, delay_until }
|
|
689
691
|
}
|
|
@@ -179,7 +179,7 @@ impl LocalActivityManager {
|
|
|
179
179
|
Self::new(
|
|
180
180
|
max_concurrent,
|
|
181
181
|
"fake_ns".to_string(),
|
|
182
|
-
MetricsContext::
|
|
182
|
+
MetricsContext::no_op(),
|
|
183
183
|
)
|
|
184
184
|
}
|
|
185
185
|
|
|
@@ -515,6 +515,7 @@ enum CancelOrTimeout {
|
|
|
515
515
|
},
|
|
516
516
|
}
|
|
517
517
|
|
|
518
|
+
#[allow(clippy::large_enum_variant)]
|
|
518
519
|
enum NewOrCancel {
|
|
519
520
|
New(NewOrRetry, OwnedMeteredSemPermit),
|
|
520
521
|
Cancel(CancelOrTimeout),
|
|
@@ -7,6 +7,7 @@ pub(crate) use local_activities::{
|
|
|
7
7
|
LocalInFlightActInfo, NewLocalAct,
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
+
use crate::telemetry::metrics::eager;
|
|
10
11
|
use crate::{
|
|
11
12
|
abstractions::{MeteredSemaphore, OwnedMeteredSemPermit},
|
|
12
13
|
pollers::BoxedActPoller,
|
|
@@ -41,6 +42,7 @@ use temporal_sdk_core_protos::{
|
|
|
41
42
|
},
|
|
42
43
|
};
|
|
43
44
|
use tokio::sync::Notify;
|
|
45
|
+
use tracing::Span;
|
|
44
46
|
|
|
45
47
|
#[derive(Debug, derive_more::Constructor)]
|
|
46
48
|
struct PendingActivityCancel {
|
|
@@ -48,11 +50,15 @@ struct PendingActivityCancel {
|
|
|
48
50
|
reason: ActivityCancelReason,
|
|
49
51
|
}
|
|
50
52
|
|
|
51
|
-
/// Contains
|
|
53
|
+
/// Contains details that core wants to store while an activity is running.
|
|
52
54
|
#[derive(Debug)]
|
|
53
55
|
struct InFlightActInfo {
|
|
54
56
|
pub activity_type: String,
|
|
55
57
|
pub workflow_type: String,
|
|
58
|
+
/// Only kept for logging reasons
|
|
59
|
+
pub workflow_id: String,
|
|
60
|
+
/// Only kept for logging reasons
|
|
61
|
+
pub workflow_run_id: String,
|
|
56
62
|
start_time: Instant,
|
|
57
63
|
}
|
|
58
64
|
|
|
@@ -71,19 +77,17 @@ struct RemoteInFlightActInfo {
|
|
|
71
77
|
_permit: OwnedMeteredSemPermit,
|
|
72
78
|
}
|
|
73
79
|
impl RemoteInFlightActInfo {
|
|
74
|
-
fn new(
|
|
75
|
-
|
|
76
|
-
workflow_type: String,
|
|
77
|
-
heartbeat_timeout: Option<prost_types::Duration>,
|
|
78
|
-
permit: OwnedMeteredSemPermit,
|
|
79
|
-
) -> Self {
|
|
80
|
+
fn new(poll_resp: &PollActivityTaskQueueResponse, permit: OwnedMeteredSemPermit) -> Self {
|
|
81
|
+
let wec = poll_resp.workflow_execution.clone().unwrap_or_default();
|
|
80
82
|
Self {
|
|
81
83
|
base: InFlightActInfo {
|
|
82
|
-
activity_type,
|
|
83
|
-
workflow_type,
|
|
84
|
+
activity_type: poll_resp.activity_type.clone().unwrap_or_default().name,
|
|
85
|
+
workflow_type: poll_resp.workflow_type.clone().unwrap_or_default().name,
|
|
86
|
+
workflow_id: wec.workflow_id,
|
|
87
|
+
workflow_run_id: wec.run_id,
|
|
84
88
|
start_time: Instant::now(),
|
|
85
89
|
},
|
|
86
|
-
heartbeat_timeout,
|
|
90
|
+
heartbeat_timeout: poll_resp.heartbeat_timeout.clone(),
|
|
87
91
|
issued_cancel_to_lang: false,
|
|
88
92
|
known_not_found: false,
|
|
89
93
|
_permit: permit,
|
|
@@ -202,7 +206,7 @@ impl WorkerActivityTasks {
|
|
|
202
206
|
cancel_task
|
|
203
207
|
}
|
|
204
208
|
task = self.non_poll_tasks.next() => {
|
|
205
|
-
Ok(Some(self.about_to_issue_task(task)))
|
|
209
|
+
Ok(Some(self.about_to_issue_task(task, true)))
|
|
206
210
|
}
|
|
207
211
|
(work, permit) = poll_with_semaphore => {
|
|
208
212
|
match work {
|
|
@@ -214,7 +218,7 @@ impl WorkerActivityTasks {
|
|
|
214
218
|
}
|
|
215
219
|
let work = self.about_to_issue_task(PermittedTqResp {
|
|
216
220
|
resp: work, permit
|
|
217
|
-
});
|
|
221
|
+
}, false);
|
|
218
222
|
Ok(Some(work))
|
|
219
223
|
}
|
|
220
224
|
None => {
|
|
@@ -234,12 +238,14 @@ impl WorkerActivityTasks {
|
|
|
234
238
|
) {
|
|
235
239
|
if let Some((_, act_info)) = self.outstanding_activity_tasks.remove(&task_token) {
|
|
236
240
|
let act_metrics = self.metrics.with_new_attrs([
|
|
237
|
-
activity_type(act_info.base.activity_type
|
|
238
|
-
workflow_type(act_info.base.workflow_type
|
|
241
|
+
activity_type(act_info.base.activity_type),
|
|
242
|
+
workflow_type(act_info.base.workflow_type),
|
|
239
243
|
]);
|
|
244
|
+
Span::current().record("workflow_id", act_info.base.workflow_id);
|
|
245
|
+
Span::current().record("run_id", act_info.base.workflow_run_id);
|
|
240
246
|
act_metrics.act_execution_latency(act_info.base.start_time.elapsed());
|
|
241
247
|
let known_not_found = act_info.known_not_found;
|
|
242
|
-
|
|
248
|
+
|
|
243
249
|
self.heartbeat_manager.evict(task_token.clone()).await;
|
|
244
250
|
self.complete_notify.notify_waiters();
|
|
245
251
|
|
|
@@ -369,19 +375,28 @@ impl WorkerActivityTasks {
|
|
|
369
375
|
}
|
|
370
376
|
|
|
371
377
|
/// Called when there is a new act task about to be bubbled up out of the manager
|
|
372
|
-
fn about_to_issue_task(&self, task: PermittedTqResp) -> ActivityTask {
|
|
378
|
+
fn about_to_issue_task(&self, task: PermittedTqResp, is_eager: bool) -> ActivityTask {
|
|
379
|
+
if let Some(ref act_type) = task.resp.activity_type {
|
|
380
|
+
if let Some(ref wf_type) = task.resp.workflow_type {
|
|
381
|
+
self.metrics
|
|
382
|
+
.with_new_attrs([
|
|
383
|
+
activity_type(act_type.name.clone()),
|
|
384
|
+
workflow_type(wf_type.name.clone()),
|
|
385
|
+
eager(is_eager),
|
|
386
|
+
])
|
|
387
|
+
.act_task_received();
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
// There could be an else statement here but since the response should always contain both
|
|
391
|
+
// activity_type and workflow_type, we won't bother.
|
|
392
|
+
|
|
373
393
|
if let Some(dur) = task.resp.sched_to_start() {
|
|
374
394
|
self.metrics.act_sched_to_start_latency(dur);
|
|
375
395
|
};
|
|
376
396
|
|
|
377
397
|
self.outstanding_activity_tasks.insert(
|
|
378
398
|
task.resp.task_token.clone().into(),
|
|
379
|
-
RemoteInFlightActInfo::new(
|
|
380
|
-
task.resp.activity_type.clone().unwrap_or_default().name,
|
|
381
|
-
task.resp.workflow_type.clone().unwrap_or_default().name,
|
|
382
|
-
task.resp.heartbeat_timeout.clone(),
|
|
383
|
-
task.permit,
|
|
384
|
-
),
|
|
399
|
+
RemoteInFlightActInfo::new(&task.resp, task.permit),
|
|
385
400
|
);
|
|
386
401
|
|
|
387
402
|
ActivityTask::start_from_poll_resp(task.resp)
|
|
@@ -411,6 +426,8 @@ impl ActivitiesFromWFTsHandle {
|
|
|
411
426
|
/// from WFT completion)
|
|
412
427
|
pub(crate) fn add_tasks(&self, tasks: impl IntoIterator<Item = PermittedTqResp>) {
|
|
413
428
|
for t in tasks.into_iter() {
|
|
429
|
+
// Technically we should be reporting `activity_task_received` here, but for simplicity
|
|
430
|
+
// and time insensitivity, that metric is tracked in `about_to_issue_task`.
|
|
414
431
|
self.tx.try_send(t).expect("Receive half cannot be dropped");
|
|
415
432
|
}
|
|
416
433
|
}
|
|
@@ -449,7 +466,7 @@ mod tests {
|
|
|
449
466
|
Some(2.0),
|
|
450
467
|
poller,
|
|
451
468
|
Arc::new(mock_manual_workflow_client()),
|
|
452
|
-
MetricsContext::
|
|
469
|
+
MetricsContext::no_op(),
|
|
453
470
|
Duration::from_secs(1),
|
|
454
471
|
Duration::from_secs(1),
|
|
455
472
|
);
|
|
@@ -16,7 +16,7 @@ pub(crate) fn mock_manual_workflow_client() -> MockManualWorkerClient {
|
|
|
16
16
|
// results. This is really annoying b/c of the async trait stuff. Need
|
|
17
17
|
// https://github.com/asomers/mockall/issues/189 to be fixed for it to go away.
|
|
18
18
|
mockall::mock! {
|
|
19
|
-
pub ManualWorkerClient {}
|
|
19
|
+
pub(crate) ManualWorkerClient {}
|
|
20
20
|
#[allow(unused)]
|
|
21
21
|
impl WorkerClient for ManualWorkerClient {
|
|
22
22
|
fn poll_workflow_task<'a, 'b>(&'a self, task_queue: String, is_sticky: bool)
|
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
pub(crate) mod mocks;
|
|
4
4
|
|
|
5
|
-
use temporal_client::{Client, RetryClient, WorkflowService
|
|
5
|
+
use temporal_client::{Client, RetryClient, WorkflowService};
|
|
6
6
|
use temporal_sdk_core_protos::{
|
|
7
7
|
coresdk::workflow_commands::QueryResult,
|
|
8
8
|
temporal::api::{
|
|
9
|
+
command::v1::Command,
|
|
9
10
|
common::v1::{Payloads, WorkflowExecution},
|
|
10
11
|
enums::v1::{TaskQueueKind, WorkflowTaskFailedCause},
|
|
11
12
|
failure::v1::Failure,
|
|
12
13
|
query::v1::WorkflowQueryResult,
|
|
13
|
-
taskqueue::v1::{TaskQueue, TaskQueueMetadata},
|
|
14
|
+
taskqueue::v1::{StickyExecutionAttributes, TaskQueue, TaskQueueMetadata, VersionId},
|
|
14
15
|
workflowservice::v1::*,
|
|
15
16
|
},
|
|
16
17
|
TaskToken,
|
|
@@ -133,7 +134,9 @@ impl WorkerClient for WorkerClientBag {
|
|
|
133
134
|
} else {
|
|
134
135
|
self.worker_build_id.clone()
|
|
135
136
|
},
|
|
136
|
-
|
|
137
|
+
worker_versioning_id: Some(VersionId {
|
|
138
|
+
worker_build_id: self.versioning_build_id(),
|
|
139
|
+
}),
|
|
137
140
|
};
|
|
138
141
|
|
|
139
142
|
Ok(self
|
|
@@ -159,7 +162,9 @@ impl WorkerClient for WorkerClientBag {
|
|
|
159
162
|
task_queue_metadata: max_tasks_per_sec.map(|tps| TaskQueueMetadata {
|
|
160
163
|
max_tasks_per_second: Some(tps),
|
|
161
164
|
}),
|
|
162
|
-
|
|
165
|
+
worker_versioning_id: Some(VersionId {
|
|
166
|
+
worker_build_id: self.versioning_build_id(),
|
|
167
|
+
}),
|
|
163
168
|
};
|
|
164
169
|
|
|
165
170
|
Ok(self
|
|
@@ -181,6 +186,9 @@ impl WorkerClient for WorkerClientBag {
|
|
|
181
186
|
sticky_attributes: request.sticky_attributes,
|
|
182
187
|
return_new_workflow_task: request.return_new_workflow_task,
|
|
183
188
|
force_create_new_workflow_task: request.force_create_new_workflow_task,
|
|
189
|
+
worker_versioning_id: Some(VersionId {
|
|
190
|
+
worker_build_id: self.versioning_build_id(),
|
|
191
|
+
}),
|
|
184
192
|
binary_checksum: self.worker_build_id.clone(),
|
|
185
193
|
query_results: request
|
|
186
194
|
.query_responses
|
|
@@ -345,3 +353,21 @@ impl WorkerClient for WorkerClientBag {
|
|
|
345
353
|
.into_inner())
|
|
346
354
|
}
|
|
347
355
|
}
|
|
356
|
+
|
|
357
|
+
/// A version of [RespondWorkflowTaskCompletedRequest] that will finish being filled out by the
|
|
358
|
+
/// server client
|
|
359
|
+
#[derive(Debug, Clone, PartialEq)]
|
|
360
|
+
pub(crate) struct WorkflowTaskCompletion {
|
|
361
|
+
/// The task token that would've been received from polling for a workflow activation
|
|
362
|
+
pub task_token: TaskToken,
|
|
363
|
+
/// A list of new commands to send to the server, such as starting a timer.
|
|
364
|
+
pub commands: Vec<Command>,
|
|
365
|
+
/// If set, indicate that next task should be queued on sticky queue with given attributes.
|
|
366
|
+
pub sticky_attributes: Option<StickyExecutionAttributes>,
|
|
367
|
+
/// Responses to queries in the `queries` field of the workflow task.
|
|
368
|
+
pub query_responses: Vec<QueryResult>,
|
|
369
|
+
/// Indicate that the task completion should return a new WFT if one is available
|
|
370
|
+
pub return_new_workflow_task: bool,
|
|
371
|
+
/// Force a new WFT to be created after this completion
|
|
372
|
+
pub force_create_new_workflow_task: bool,
|
|
373
|
+
}
|
|
@@ -74,7 +74,7 @@ impl WorkerTrait for Worker {
|
|
|
74
74
|
self.next_workflow_activation().await
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
#[instrument(
|
|
77
|
+
#[instrument(skip(self))]
|
|
78
78
|
async fn poll_activity_task(&self) -> Result<ActivityTask, PollActivityError> {
|
|
79
79
|
loop {
|
|
80
80
|
match self.activity_poll().await.transpose() {
|
|
@@ -94,7 +94,6 @@ impl WorkerTrait for Worker {
|
|
|
94
94
|
self.complete_workflow_activation(completion).await
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
#[instrument(level = "debug", skip(self, completion), fields(completion=%&completion))]
|
|
98
97
|
async fn complete_activity_task(
|
|
99
98
|
&self,
|
|
100
99
|
completion: ActivityTaskCompletion,
|
|
@@ -135,7 +134,11 @@ impl WorkerTrait for Worker {
|
|
|
135
134
|
if let Some(atm) = self.at_task_mgr.as_ref() {
|
|
136
135
|
atm.notify_shutdown();
|
|
137
136
|
}
|
|
138
|
-
info!(
|
|
137
|
+
info!(
|
|
138
|
+
task_queue=%self.config.task_queue,
|
|
139
|
+
namespace=%self.config.namespace,
|
|
140
|
+
"Initiated shutdown",
|
|
141
|
+
);
|
|
139
142
|
}
|
|
140
143
|
|
|
141
144
|
async fn shutdown(&self) {
|
|
@@ -155,7 +158,9 @@ impl Worker {
|
|
|
155
158
|
client: Arc<dyn WorkerClient>,
|
|
156
159
|
metrics: MetricsContext,
|
|
157
160
|
) -> Self {
|
|
158
|
-
info!(task_queue
|
|
161
|
+
info!(task_queue=%config.task_queue,
|
|
162
|
+
namespace=%config.namespace,
|
|
163
|
+
"Initializing worker");
|
|
159
164
|
metrics.worker_registered();
|
|
160
165
|
|
|
161
166
|
let shutdown_token = CancellationToken::new();
|
|
@@ -224,7 +229,7 @@ impl Worker {
|
|
|
224
229
|
|
|
225
230
|
#[cfg(test)]
|
|
226
231
|
pub(crate) fn new_test(config: WorkerConfig, client: impl WorkerClient + 'static) -> Self {
|
|
227
|
-
Self::new(config, None, Arc::new(client),
|
|
232
|
+
Self::new(config, None, Arc::new(client), MetricsContext::no_op())
|
|
228
233
|
}
|
|
229
234
|
|
|
230
235
|
pub(crate) fn new_with_pollers(
|
|
@@ -264,6 +269,7 @@ impl Worker {
|
|
|
264
269
|
metrics,
|
|
265
270
|
namespace: config.namespace.clone(),
|
|
266
271
|
task_queue: config.task_queue.clone(),
|
|
272
|
+
ignore_evicts_on_shutdown: config.ignore_evicts_on_shutdown,
|
|
267
273
|
},
|
|
268
274
|
sticky_queue_name.map(|sq| StickyExecutionAttributes {
|
|
269
275
|
worker_task_queue: Some(TaskQueue {
|
|
@@ -317,6 +323,10 @@ impl Worker {
|
|
|
317
323
|
}
|
|
318
324
|
}
|
|
319
325
|
|
|
326
|
+
pub(crate) fn shutdown_token(&self) -> CancellationToken {
|
|
327
|
+
self.shutdown_token.clone()
|
|
328
|
+
}
|
|
329
|
+
|
|
320
330
|
/// Returns number of currently cached workflows
|
|
321
331
|
pub async fn cached_workflows(&self) -> usize {
|
|
322
332
|
self.workflows
|
|
@@ -394,6 +404,9 @@ impl Worker {
|
|
|
394
404
|
}
|
|
395
405
|
}
|
|
396
406
|
|
|
407
|
+
#[instrument(skip(self, task_token, status),
|
|
408
|
+
fields(task_token=%&task_token, status=%&status,
|
|
409
|
+
task_queue=%self.config.task_queue, workflow_id, run_id))]
|
|
397
410
|
pub(crate) async fn complete_activity(
|
|
398
411
|
&self,
|
|
399
412
|
task_token: TaskToken,
|
|
@@ -433,13 +446,14 @@ impl Worker {
|
|
|
433
446
|
Ok(())
|
|
434
447
|
}
|
|
435
448
|
|
|
436
|
-
#[instrument(
|
|
449
|
+
#[instrument(skip(self), fields(run_id, workflow_id, task_queue=%self.config.task_queue))]
|
|
437
450
|
pub(crate) async fn next_workflow_activation(&self) -> Result<WorkflowActivation, PollWfError> {
|
|
438
451
|
self.workflows.next_workflow_activation().await
|
|
439
452
|
}
|
|
440
453
|
|
|
441
|
-
#[instrument(
|
|
442
|
-
|
|
454
|
+
#[instrument(skip(self, completion),
|
|
455
|
+
fields(completion=%&completion, run_id=%completion.run_id, workflow_id,
|
|
456
|
+
task_queue=%self.config.task_queue))]
|
|
443
457
|
pub(crate) async fn complete_workflow_activation(
|
|
444
458
|
&self,
|
|
445
459
|
completion: WorkflowActivationCompletion,
|
|
@@ -470,16 +484,6 @@ impl Worker {
|
|
|
470
484
|
self.post_activate_hook = Some(Box::new(callback))
|
|
471
485
|
}
|
|
472
486
|
|
|
473
|
-
/// Used for replay workers - causes the worker to shutdown when the given run reaches the
|
|
474
|
-
/// given event number
|
|
475
|
-
pub(crate) fn set_shutdown_on_run_reaches_event(&mut self, run_id: String, last_event: i64) {
|
|
476
|
-
self.set_post_activate_hook(move |worker, activated_run_id, last_processed_event| {
|
|
477
|
-
if activated_run_id == run_id && last_processed_event >= last_event as usize {
|
|
478
|
-
worker.initiate_shutdown();
|
|
479
|
-
}
|
|
480
|
-
});
|
|
481
|
-
}
|
|
482
|
-
|
|
483
487
|
fn complete_local_act(
|
|
484
488
|
&self,
|
|
485
489
|
la_res: LocalActivityExecutionResult,
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
use crate::worker::workflow::{WFCommand, WorkflowStartedInfo};
|
|
1
|
+
use crate::worker::workflow::{OutgoingJob, WFCommand, WorkflowStartedInfo};
|
|
2
|
+
use prost_types::Timestamp;
|
|
2
3
|
use temporal_sdk_core_protos::{
|
|
3
|
-
coresdk::workflow_activation::{
|
|
4
|
-
start_workflow_from_attribs, workflow_activation_job, CancelWorkflow, SignalWorkflow,
|
|
5
|
-
WorkflowActivationJob,
|
|
6
|
-
},
|
|
4
|
+
coresdk::workflow_activation::{start_workflow_from_attribs, WorkflowActivationJob},
|
|
7
5
|
temporal::api::history::v1::WorkflowExecutionStartedEventAttributes,
|
|
8
6
|
utilities::TryIntoOrNone,
|
|
9
7
|
};
|
|
@@ -14,7 +12,7 @@ pub struct DrivenWorkflow {
|
|
|
14
12
|
started_attrs: Option<WorkflowStartedInfo>,
|
|
15
13
|
fetcher: Box<dyn WorkflowFetcher>,
|
|
16
14
|
/// Outgoing activation jobs that need to be sent to the lang sdk
|
|
17
|
-
outgoing_wf_activation_jobs: Vec<
|
|
15
|
+
outgoing_wf_activation_jobs: Vec<OutgoingJob>,
|
|
18
16
|
}
|
|
19
17
|
|
|
20
18
|
impl<WF> From<Box<WF>> for DrivenWorkflow
|
|
@@ -36,6 +34,7 @@ impl DrivenWorkflow {
|
|
|
36
34
|
&mut self,
|
|
37
35
|
workflow_id: String,
|
|
38
36
|
randomness_seed: u64,
|
|
37
|
+
start_time: Timestamp,
|
|
39
38
|
attribs: WorkflowExecutionStartedEventAttributes,
|
|
40
39
|
) {
|
|
41
40
|
debug!(run_id = %attribs.original_execution_run_id, "Driven WF start");
|
|
@@ -49,7 +48,9 @@ impl DrivenWorkflow {
|
|
|
49
48
|
search_attrs: attribs.search_attributes.clone(),
|
|
50
49
|
retry_policy: attribs.retry_policy.clone(),
|
|
51
50
|
};
|
|
52
|
-
self.send_job(
|
|
51
|
+
self.send_job(
|
|
52
|
+
start_workflow_from_attribs(attribs, workflow_id, randomness_seed, start_time).into(),
|
|
53
|
+
);
|
|
53
54
|
self.started_attrs = Some(started_info);
|
|
54
55
|
}
|
|
55
56
|
|
|
@@ -59,12 +60,12 @@ impl DrivenWorkflow {
|
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
/// Enqueue a new job to be sent to the driven workflow
|
|
62
|
-
pub fn send_job(&mut self, job:
|
|
63
|
+
pub(super) fn send_job(&mut self, job: OutgoingJob) {
|
|
63
64
|
self.outgoing_wf_activation_jobs.push(job);
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
/// Observe pending jobs
|
|
67
|
-
pub fn peek_pending_jobs(&self) -> &[
|
|
68
|
+
pub(super) fn peek_pending_jobs(&self) -> &[OutgoingJob] {
|
|
68
69
|
self.outgoing_wf_activation_jobs.as_slice()
|
|
69
70
|
}
|
|
70
71
|
|
|
@@ -75,16 +76,6 @@ impl DrivenWorkflow {
|
|
|
75
76
|
.map(Into::into)
|
|
76
77
|
.collect()
|
|
77
78
|
}
|
|
78
|
-
|
|
79
|
-
/// Signal the workflow
|
|
80
|
-
pub fn signal(&mut self, signal: SignalWorkflow) {
|
|
81
|
-
self.send_job(workflow_activation_job::Variant::SignalWorkflow(signal));
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/// Cancel the workflow
|
|
85
|
-
pub fn cancel(&mut self, attribs: CancelWorkflow) {
|
|
86
|
-
self.send_job(workflow_activation_job::Variant::CancelWorkflow(attribs));
|
|
87
|
-
}
|
|
88
79
|
}
|
|
89
80
|
|
|
90
81
|
#[async_trait::async_trait]
|