@temporalio/core-bridge 0.16.4 → 0.18.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 +339 -226
- package/Cargo.toml +7 -3
- package/common.js +50 -0
- package/index.d.ts +7 -0
- package/index.js +12 -0
- package/package.json +7 -4
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
- package/{index.node → releases/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 +10 -50
- package/sdk-core/.buildkite/docker/Dockerfile +1 -1
- package/sdk-core/.buildkite/docker/docker-compose.yaml +2 -2
- package/sdk-core/.buildkite/pipeline.yml +2 -0
- package/sdk-core/Cargo.toml +1 -88
- package/sdk-core/README.md +30 -6
- package/sdk-core/bridge-ffi/Cargo.toml +24 -0
- package/sdk-core/bridge-ffi/LICENSE.txt +23 -0
- package/sdk-core/bridge-ffi/build.rs +25 -0
- package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +216 -0
- package/sdk-core/bridge-ffi/src/lib.rs +829 -0
- package/sdk-core/bridge-ffi/src/wrappers.rs +193 -0
- package/sdk-core/client/Cargo.toml +32 -0
- package/sdk-core/{src/pollers/gateway.rs → client/src/lib.rs} +101 -195
- package/sdk-core/client/src/metrics.rs +89 -0
- package/sdk-core/client/src/mocks.rs +167 -0
- package/sdk-core/{src/pollers → client/src}/retry.rs +172 -14
- package/sdk-core/core/Cargo.toml +96 -0
- package/sdk-core/{src → core/src}/core_tests/activity_tasks.rs +193 -37
- package/sdk-core/{src → core/src}/core_tests/child_workflows.rs +14 -14
- package/sdk-core/{src → core/src}/core_tests/determinism.rs +8 -8
- package/sdk-core/core/src/core_tests/local_activities.rs +328 -0
- package/sdk-core/{src → core/src}/core_tests/mod.rs +6 -9
- package/sdk-core/{src → core/src}/core_tests/queries.rs +54 -54
- package/sdk-core/{src → core/src}/core_tests/replay_flag.rs +8 -12
- package/sdk-core/{src → core/src}/core_tests/workers.rs +120 -33
- package/sdk-core/{src → core/src}/core_tests/workflow_cancels.rs +16 -26
- package/sdk-core/{src → core/src}/core_tests/workflow_tasks.rs +280 -292
- package/sdk-core/core/src/lib.rs +374 -0
- package/sdk-core/{src → core/src}/log_export.rs +3 -27
- package/sdk-core/core/src/pending_activations.rs +162 -0
- package/sdk-core/{src → core/src}/pollers/mod.rs +4 -22
- package/sdk-core/{src → core/src}/pollers/poll_buffer.rs +1 -1
- package/sdk-core/core/src/protosext/mod.rs +396 -0
- package/sdk-core/core/src/replay/mod.rs +210 -0
- package/sdk-core/core/src/retry_logic.rs +144 -0
- package/sdk-core/{src → core/src}/telemetry/metrics.rs +3 -58
- package/sdk-core/{src → core/src}/telemetry/mod.rs +8 -8
- package/sdk-core/{src → core/src}/telemetry/prometheus_server.rs +0 -0
- package/sdk-core/{src → core/src}/test_help/mod.rs +35 -83
- package/sdk-core/{src → core/src}/worker/activities/activity_heartbeat_manager.rs +95 -42
- package/sdk-core/core/src/worker/activities/local_activities.rs +973 -0
- package/sdk-core/{src → core/src}/worker/activities.rs +52 -33
- package/sdk-core/{src → core/src}/worker/dispatcher.rs +8 -6
- package/sdk-core/{src → core/src}/worker/mod.rs +347 -221
- package/sdk-core/core/src/worker/wft_delivery.rs +81 -0
- package/sdk-core/{src → core/src}/workflow/bridge.rs +5 -2
- package/sdk-core/{src → core/src}/workflow/driven_workflow.rs +17 -7
- package/sdk-core/{src → core/src}/workflow/history_update.rs +33 -7
- package/sdk-core/{src → core/src/workflow}/machines/activity_state_machine.rs +26 -26
- package/sdk-core/{src → core/src/workflow}/machines/cancel_external_state_machine.rs +8 -11
- package/sdk-core/{src → core/src/workflow}/machines/cancel_workflow_state_machine.rs +19 -21
- package/sdk-core/{src → core/src/workflow}/machines/child_workflow_state_machine.rs +20 -31
- package/sdk-core/{src → core/src/workflow}/machines/complete_workflow_state_machine.rs +3 -5
- package/sdk-core/{src → core/src/workflow}/machines/continue_as_new_workflow_state_machine.rs +18 -18
- package/sdk-core/{src → core/src/workflow}/machines/fail_workflow_state_machine.rs +5 -6
- package/sdk-core/core/src/workflow/machines/local_activity_state_machine.rs +1451 -0
- package/sdk-core/{src → core/src/workflow}/machines/mod.rs +54 -107
- package/sdk-core/{src → core/src/workflow}/machines/mutable_side_effect_state_machine.rs +0 -0
- package/sdk-core/{src → core/src/workflow}/machines/patch_state_machine.rs +29 -30
- package/sdk-core/{src → core/src/workflow}/machines/side_effect_state_machine.rs +0 -0
- package/sdk-core/{src → core/src/workflow}/machines/signal_external_state_machine.rs +17 -19
- package/sdk-core/{src → core/src/workflow}/machines/timer_state_machine.rs +20 -21
- package/sdk-core/{src → core/src/workflow}/machines/transition_coverage.rs +5 -2
- package/sdk-core/{src → core/src/workflow}/machines/upsert_search_attributes_state_machine.rs +0 -0
- package/sdk-core/core/src/workflow/machines/workflow_machines/local_acts.rs +96 -0
- package/sdk-core/{src → core/src/workflow}/machines/workflow_machines.rs +357 -171
- package/sdk-core/{src → core/src/workflow}/machines/workflow_task_state_machine.rs +1 -1
- package/sdk-core/{src → core/src}/workflow/mod.rs +200 -39
- package/sdk-core/{src → core/src}/workflow/workflow_tasks/cache_manager.rs +0 -0
- package/sdk-core/{src → core/src}/workflow/workflow_tasks/concurrency_manager.rs +38 -5
- package/sdk-core/{src → core/src}/workflow/workflow_tasks/mod.rs +317 -103
- package/sdk-core/{test_utils → core-api}/Cargo.toml +10 -7
- package/sdk-core/{src → core-api/src}/errors.rs +42 -92
- package/sdk-core/core-api/src/lib.rs +158 -0
- package/sdk-core/{src/worker/config.rs → core-api/src/worker.rs} +18 -23
- package/sdk-core/etc/deps.svg +156 -0
- package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +5 -5
- package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +3 -5
- package/sdk-core/fsm/rustfsm_trait/src/lib.rs +7 -1
- package/sdk-core/histories/fail_wf_task.bin +0 -0
- package/sdk-core/histories/timer_workflow_history.bin +0 -0
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +44 -13
- package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +19 -1
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +1 -1
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +9 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +13 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +14 -7
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +176 -18
- package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -0
- package/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +11 -0
- package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +3 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +156 -7
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +135 -104
- package/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +78 -0
- package/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +78 -0
- package/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +205 -0
- package/sdk-core/protos/local/temporal/sdk/core/bridge/service.proto +61 -0
- package/sdk-core/protos/local/{child_workflow.proto → temporal/sdk/core/child_workflow/child_workflow.proto} +1 -1
- package/sdk-core/protos/local/{common.proto → temporal/sdk/core/common/common.proto} +5 -3
- package/sdk-core/protos/local/{core_interface.proto → temporal/sdk/core/core_interface.proto} +10 -10
- package/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +30 -0
- package/sdk-core/protos/local/{workflow_activation.proto → temporal/sdk/core/workflow_activation/workflow_activation.proto} +35 -11
- package/sdk-core/protos/local/{workflow_commands.proto → temporal/sdk/core/workflow_commands/workflow_commands.proto} +55 -4
- package/sdk-core/protos/local/{workflow_completion.proto → temporal/sdk/core/workflow_completion/workflow_completion.proto} +3 -3
- package/sdk-core/sdk/Cargo.toml +32 -0
- package/sdk-core/{src/prototype_rust_sdk → sdk/src}/conversions.rs +0 -0
- package/sdk-core/sdk/src/lib.rs +699 -0
- package/sdk-core/sdk/src/payload_converter.rs +11 -0
- package/sdk-core/sdk/src/workflow_context/options.rs +180 -0
- package/sdk-core/{src/prototype_rust_sdk → sdk/src}/workflow_context.rs +201 -124
- package/sdk-core/{src/prototype_rust_sdk → sdk/src}/workflow_future.rs +63 -30
- package/sdk-core/sdk-core-protos/Cargo.toml +10 -0
- package/sdk-core/sdk-core-protos/build.rs +28 -6
- package/sdk-core/sdk-core-protos/src/constants.rs +7 -0
- package/sdk-core/{src/test_help → sdk-core-protos/src}/history_builder.rs +134 -49
- package/sdk-core/sdk-core-protos/src/history_info.rs +216 -0
- package/sdk-core/sdk-core-protos/src/lib.rs +601 -168
- package/sdk-core/sdk-core-protos/src/task_token.rs +38 -0
- package/sdk-core/sdk-core-protos/src/utilities.rs +14 -0
- package/sdk-core/test-utils/Cargo.toml +32 -0
- package/sdk-core/{src/test_help → test-utils/src}/canned_histories.rs +59 -78
- package/sdk-core/test-utils/src/histfetch.rs +28 -0
- package/sdk-core/{test_utils → test-utils}/src/lib.rs +131 -68
- package/sdk-core/tests/integ_tests/client_tests.rs +1 -1
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +11 -7
- package/sdk-core/tests/integ_tests/polling_tests.rs +12 -11
- package/sdk-core/tests/integ_tests/queries_tests.rs +82 -78
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +91 -71
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +3 -4
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +2 -4
- package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +4 -6
- package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +4 -6
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -4
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +496 -0
- package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +5 -8
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +125 -0
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +7 -13
- package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +33 -5
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +12 -16
- package/sdk-core/tests/integ_tests/workflow_tests.rs +85 -82
- package/sdk-core/tests/load_tests.rs +6 -6
- package/sdk-core/tests/main.rs +2 -2
- package/src/conversions.rs +24 -21
- package/src/errors.rs +8 -0
- package/src/lib.rs +323 -211
- package/sdk-core/protos/local/activity_result.proto +0 -46
- package/sdk-core/protos/local/activity_task.proto +0 -66
- package/sdk-core/src/core_tests/retry.rs +0 -147
- package/sdk-core/src/lib.rs +0 -403
- package/sdk-core/src/machines/local_activity_state_machine.rs +0 -117
- package/sdk-core/src/pending_activations.rs +0 -249
- package/sdk-core/src/protosext/mod.rs +0 -160
- package/sdk-core/src/prototype_rust_sdk.rs +0 -412
- package/sdk-core/src/task_token.rs +0 -20
- package/sdk-core/src/test_help/history_info.rs +0 -157
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
use crate::{
|
|
2
|
+
replay::{default_wes_attribs, TestHistoryBuilder, DEFAULT_WORKFLOW_TYPE},
|
|
3
|
+
test_help::{build_mock_pollers, mock_core, MockPollCfg, ResponseType, TEST_Q},
|
|
4
|
+
Core,
|
|
5
|
+
};
|
|
6
|
+
use anyhow::anyhow;
|
|
7
|
+
use futures::future::join_all;
|
|
8
|
+
use std::{
|
|
9
|
+
sync::{
|
|
10
|
+
atomic::{AtomicUsize, Ordering},
|
|
11
|
+
Arc,
|
|
12
|
+
},
|
|
13
|
+
time::Duration,
|
|
14
|
+
};
|
|
15
|
+
use temporal_client::mocks::mock_gateway;
|
|
16
|
+
use temporal_sdk::{LocalActivityOptions, TestRustWorker, WfContext, WorkflowResult};
|
|
17
|
+
use temporal_sdk_core_protos::{
|
|
18
|
+
coresdk::{common::RetryPolicy, AsJsonPayloadExt},
|
|
19
|
+
temporal::api::{enums::v1::EventType, failure::v1::Failure},
|
|
20
|
+
};
|
|
21
|
+
use tokio::sync::Barrier;
|
|
22
|
+
|
|
23
|
+
async fn echo(e: String) -> anyhow::Result<String> {
|
|
24
|
+
Ok(e)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/// This test verifies that when replaying we are able to resolve local activities whose data we
|
|
28
|
+
/// don't see until after the workflow issues the command
|
|
29
|
+
#[rstest::rstest]
|
|
30
|
+
#[case::replay(true, true)]
|
|
31
|
+
#[case::not_replay(false, true)]
|
|
32
|
+
#[case::replay_cache_off(true, false)]
|
|
33
|
+
#[case::not_replay_cache_off(false, false)]
|
|
34
|
+
#[tokio::test]
|
|
35
|
+
async fn local_act_two_wfts_before_marker(#[case] replay: bool, #[case] cached: bool) {
|
|
36
|
+
let mut t = TestHistoryBuilder::default();
|
|
37
|
+
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
38
|
+
t.add_full_wf_task();
|
|
39
|
+
let timer_started_event_id = t.add_get_event_id(EventType::TimerStarted, None);
|
|
40
|
+
t.add_full_wf_task();
|
|
41
|
+
t.add_local_activity_result_marker(1, "1", b"echo".into());
|
|
42
|
+
t.add_timer_fired(timer_started_event_id, "1".to_string());
|
|
43
|
+
t.add_full_wf_task();
|
|
44
|
+
t.add_workflow_execution_completed();
|
|
45
|
+
|
|
46
|
+
let wf_id = "fakeid";
|
|
47
|
+
let mock = mock_gateway();
|
|
48
|
+
let resps = if replay {
|
|
49
|
+
vec![ResponseType::AllHistory]
|
|
50
|
+
} else {
|
|
51
|
+
vec![1.into(), 2.into(), ResponseType::AllHistory]
|
|
52
|
+
};
|
|
53
|
+
let mh = MockPollCfg::from_resp_batches(wf_id, t, resps, mock);
|
|
54
|
+
let mut mock = build_mock_pollers(mh);
|
|
55
|
+
if cached {
|
|
56
|
+
mock.worker_cfg(TEST_Q, |cfg| cfg.max_cached_workflows = 1);
|
|
57
|
+
}
|
|
58
|
+
let core = mock_core(mock);
|
|
59
|
+
let mut worker = TestRustWorker::new(Arc::new(core), TEST_Q.to_string(), None);
|
|
60
|
+
|
|
61
|
+
worker.register_wf(
|
|
62
|
+
DEFAULT_WORKFLOW_TYPE.to_owned(),
|
|
63
|
+
|ctx: WfContext| async move {
|
|
64
|
+
let la = ctx.local_activity(LocalActivityOptions {
|
|
65
|
+
activity_type: "echo".to_string(),
|
|
66
|
+
input: "hi".as_json_payload().expect("serializes fine"),
|
|
67
|
+
..Default::default()
|
|
68
|
+
});
|
|
69
|
+
ctx.timer(Duration::from_secs(1)).await;
|
|
70
|
+
la.await;
|
|
71
|
+
Ok(().into())
|
|
72
|
+
},
|
|
73
|
+
);
|
|
74
|
+
worker.register_activity("echo", echo);
|
|
75
|
+
worker
|
|
76
|
+
.submit_wf(wf_id.to_owned(), DEFAULT_WORKFLOW_TYPE.to_owned(), vec![])
|
|
77
|
+
.await
|
|
78
|
+
.unwrap();
|
|
79
|
+
worker.run_until_done().await.unwrap();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
pub async fn local_act_fanout_wf(ctx: WfContext) -> WorkflowResult<()> {
|
|
83
|
+
let las: Vec<_> = (1..=50)
|
|
84
|
+
.map(|i| {
|
|
85
|
+
ctx.local_activity(LocalActivityOptions {
|
|
86
|
+
activity_type: "echo".to_string(),
|
|
87
|
+
input: format!("Hi {}", i)
|
|
88
|
+
.as_json_payload()
|
|
89
|
+
.expect("serializes fine"),
|
|
90
|
+
..Default::default()
|
|
91
|
+
})
|
|
92
|
+
})
|
|
93
|
+
.collect();
|
|
94
|
+
ctx.timer(Duration::from_secs(1)).await;
|
|
95
|
+
join_all(las).await;
|
|
96
|
+
Ok(().into())
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
#[tokio::test]
|
|
100
|
+
async fn local_act_many_concurrent() {
|
|
101
|
+
let mut t = TestHistoryBuilder::default();
|
|
102
|
+
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
103
|
+
t.add_full_wf_task();
|
|
104
|
+
let timer_started_event_id = t.add_get_event_id(EventType::TimerStarted, None);
|
|
105
|
+
t.add_full_wf_task();
|
|
106
|
+
for i in 1..=50 {
|
|
107
|
+
t.add_local_activity_result_marker(i, &i.to_string(), b"echo".into());
|
|
108
|
+
}
|
|
109
|
+
t.add_timer_fired(timer_started_event_id, "1".to_string());
|
|
110
|
+
t.add_full_wf_task();
|
|
111
|
+
t.add_workflow_execution_completed();
|
|
112
|
+
|
|
113
|
+
let wf_id = "fakeid";
|
|
114
|
+
let mock = mock_gateway();
|
|
115
|
+
let mh = MockPollCfg::from_resp_batches(wf_id, t, [1, 2, 3], mock);
|
|
116
|
+
let mock = build_mock_pollers(mh);
|
|
117
|
+
let core = mock_core(mock);
|
|
118
|
+
let mut worker = TestRustWorker::new(Arc::new(core), TEST_Q.to_string(), None);
|
|
119
|
+
|
|
120
|
+
worker.register_wf(DEFAULT_WORKFLOW_TYPE.to_owned(), local_act_fanout_wf);
|
|
121
|
+
worker.register_activity("echo", |str: String| async move { Ok(str) });
|
|
122
|
+
worker
|
|
123
|
+
.submit_wf(wf_id.to_owned(), DEFAULT_WORKFLOW_TYPE.to_owned(), vec![])
|
|
124
|
+
.await
|
|
125
|
+
.unwrap();
|
|
126
|
+
worker.run_until_done().await.unwrap();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/// Verifies that local activities which take more than a workflow task timeout will cause
|
|
130
|
+
/// us to issue additional (empty) WFT completions with the force flag on, thus preventing timeout
|
|
131
|
+
/// of WFT while the local activity continues to execute.
|
|
132
|
+
///
|
|
133
|
+
/// The test with shutdown verifies if we call shutdown while the local activity is running that
|
|
134
|
+
/// shutdown does not complete until it's finished.
|
|
135
|
+
#[rstest::rstest]
|
|
136
|
+
#[case::with_shutdown(true)]
|
|
137
|
+
#[case::normal_complete(false)]
|
|
138
|
+
#[tokio::test]
|
|
139
|
+
async fn local_act_heartbeat(#[case] shutdown_middle: bool) {
|
|
140
|
+
let mut t = TestHistoryBuilder::default();
|
|
141
|
+
let wft_timeout = Duration::from_millis(200);
|
|
142
|
+
let mut wes_short_wft_timeout = default_wes_attribs();
|
|
143
|
+
wes_short_wft_timeout.workflow_task_timeout = Some(wft_timeout.into());
|
|
144
|
+
t.add(
|
|
145
|
+
EventType::WorkflowExecutionStarted,
|
|
146
|
+
wes_short_wft_timeout.into(),
|
|
147
|
+
);
|
|
148
|
+
t.add_full_wf_task();
|
|
149
|
+
// Task created by WFT heartbeat
|
|
150
|
+
t.add_full_wf_task();
|
|
151
|
+
t.add_workflow_task_scheduled_and_started();
|
|
152
|
+
|
|
153
|
+
let wf_id = "fakeid";
|
|
154
|
+
let mock = mock_gateway();
|
|
155
|
+
// Allow returning incomplete history more than once, as the wft timeout can be timing sensitive
|
|
156
|
+
// and might poll an extra time
|
|
157
|
+
let mut mh = MockPollCfg::from_resp_batches(wf_id, t, [1, 2, 2, 2, 2], mock);
|
|
158
|
+
mh.enforce_correct_number_of_polls = false;
|
|
159
|
+
let mut mock = build_mock_pollers(mh);
|
|
160
|
+
mock.worker_cfg(TEST_Q, |wc| wc.max_cached_workflows = 1);
|
|
161
|
+
let core = Arc::new(mock_core(mock));
|
|
162
|
+
let mut worker = TestRustWorker::new(core.clone(), TEST_Q.to_string(), None);
|
|
163
|
+
let shutdown_barr: &'static Barrier = Box::leak(Box::new(Barrier::new(2)));
|
|
164
|
+
|
|
165
|
+
worker.register_wf(
|
|
166
|
+
DEFAULT_WORKFLOW_TYPE.to_owned(),
|
|
167
|
+
|ctx: WfContext| async move {
|
|
168
|
+
ctx.local_activity(LocalActivityOptions {
|
|
169
|
+
activity_type: "echo".to_string(),
|
|
170
|
+
input: "hi".as_json_payload().expect("serializes fine"),
|
|
171
|
+
..Default::default()
|
|
172
|
+
})
|
|
173
|
+
.await;
|
|
174
|
+
Ok(().into())
|
|
175
|
+
},
|
|
176
|
+
);
|
|
177
|
+
worker.register_activity("echo", move |str: String| async move {
|
|
178
|
+
if shutdown_middle {
|
|
179
|
+
shutdown_barr.wait().await;
|
|
180
|
+
}
|
|
181
|
+
// Take slightly more than two workflow tasks
|
|
182
|
+
tokio::time::sleep(wft_timeout.mul_f32(2.2)).await;
|
|
183
|
+
Ok(str)
|
|
184
|
+
});
|
|
185
|
+
worker
|
|
186
|
+
.submit_wf(wf_id.to_owned(), DEFAULT_WORKFLOW_TYPE.to_owned(), vec![])
|
|
187
|
+
.await
|
|
188
|
+
.unwrap();
|
|
189
|
+
let (_, runres) = tokio::join!(
|
|
190
|
+
async {
|
|
191
|
+
if shutdown_middle {
|
|
192
|
+
shutdown_barr.wait().await;
|
|
193
|
+
core.shutdown().await;
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
worker.run_until_done()
|
|
197
|
+
);
|
|
198
|
+
runres.unwrap();
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
#[rstest::rstest]
|
|
202
|
+
#[case::retry_then_pass(true)]
|
|
203
|
+
#[case::retry_until_fail(false)]
|
|
204
|
+
#[tokio::test]
|
|
205
|
+
async fn local_act_fail_and_retry(#[case] eventually_pass: bool) {
|
|
206
|
+
let mut t = TestHistoryBuilder::default();
|
|
207
|
+
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
208
|
+
t.add_workflow_task_scheduled_and_started();
|
|
209
|
+
|
|
210
|
+
let wf_id = "fakeid";
|
|
211
|
+
let mock = mock_gateway();
|
|
212
|
+
let mh = MockPollCfg::from_resp_batches(wf_id, t, [1], mock);
|
|
213
|
+
let mock = build_mock_pollers(mh);
|
|
214
|
+
let core = mock_core(mock);
|
|
215
|
+
let mut worker = TestRustWorker::new(Arc::new(core), TEST_Q.to_string(), None);
|
|
216
|
+
|
|
217
|
+
worker.register_wf(
|
|
218
|
+
DEFAULT_WORKFLOW_TYPE.to_owned(),
|
|
219
|
+
move |ctx: WfContext| async move {
|
|
220
|
+
let la_res = ctx
|
|
221
|
+
.local_activity(LocalActivityOptions {
|
|
222
|
+
activity_type: "echo".to_string(),
|
|
223
|
+
input: "hi".as_json_payload().expect("serializes fine"),
|
|
224
|
+
retry_policy: RetryPolicy {
|
|
225
|
+
initial_interval: Some(Duration::from_millis(50).into()),
|
|
226
|
+
backoff_coefficient: 1.2,
|
|
227
|
+
maximum_interval: None,
|
|
228
|
+
maximum_attempts: 5,
|
|
229
|
+
non_retryable_error_types: vec![],
|
|
230
|
+
},
|
|
231
|
+
..Default::default()
|
|
232
|
+
})
|
|
233
|
+
.await;
|
|
234
|
+
if eventually_pass {
|
|
235
|
+
assert!(la_res.completed_ok())
|
|
236
|
+
} else {
|
|
237
|
+
assert!(la_res.failed())
|
|
238
|
+
}
|
|
239
|
+
Ok(().into())
|
|
240
|
+
},
|
|
241
|
+
);
|
|
242
|
+
let attempts: &'static _ = Box::leak(Box::new(AtomicUsize::new(0)));
|
|
243
|
+
worker.register_activity("echo", move |_: String| async move {
|
|
244
|
+
// Succeed on 3rd attempt (which is ==2 since fetch_add returns prev val)
|
|
245
|
+
if 2 == attempts.fetch_add(1, Ordering::Relaxed) && eventually_pass {
|
|
246
|
+
Ok(())
|
|
247
|
+
} else {
|
|
248
|
+
Err(anyhow!("Oh no I failed!"))
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
worker
|
|
252
|
+
.submit_wf(wf_id.to_owned(), DEFAULT_WORKFLOW_TYPE.to_owned(), vec![])
|
|
253
|
+
.await
|
|
254
|
+
.unwrap();
|
|
255
|
+
worker.run_until_done().await.unwrap();
|
|
256
|
+
let expected_attempts = if eventually_pass { 3 } else { 5 };
|
|
257
|
+
assert_eq!(expected_attempts, attempts.load(Ordering::Relaxed));
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
#[tokio::test]
|
|
261
|
+
async fn local_act_retry_long_backoff_uses_timer() {
|
|
262
|
+
let mut t = TestHistoryBuilder::default();
|
|
263
|
+
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
264
|
+
t.add_full_wf_task();
|
|
265
|
+
t.add_local_activity_fail_marker(
|
|
266
|
+
1,
|
|
267
|
+
"1",
|
|
268
|
+
Failure::application_failure("la failed".to_string(), false),
|
|
269
|
+
);
|
|
270
|
+
let timer_started_event_id = t.add_get_event_id(EventType::TimerStarted, None);
|
|
271
|
+
t.add_timer_fired(timer_started_event_id, "1".to_string());
|
|
272
|
+
t.add_full_wf_task();
|
|
273
|
+
t.add_local_activity_fail_marker(
|
|
274
|
+
2,
|
|
275
|
+
"2",
|
|
276
|
+
Failure::application_failure("la failed".to_string(), false),
|
|
277
|
+
);
|
|
278
|
+
let timer_started_event_id = t.add_get_event_id(EventType::TimerStarted, None);
|
|
279
|
+
t.add_timer_fired(timer_started_event_id, "2".to_string());
|
|
280
|
+
t.add_full_wf_task();
|
|
281
|
+
t.add_workflow_execution_completed();
|
|
282
|
+
|
|
283
|
+
let wf_id = "fakeid";
|
|
284
|
+
let mock = mock_gateway();
|
|
285
|
+
let mh = MockPollCfg::from_resp_batches(
|
|
286
|
+
wf_id,
|
|
287
|
+
t,
|
|
288
|
+
[1.into(), 2.into(), ResponseType::AllHistory],
|
|
289
|
+
mock,
|
|
290
|
+
);
|
|
291
|
+
let mut mock = build_mock_pollers(mh);
|
|
292
|
+
mock.worker_cfg(TEST_Q, |w| w.max_cached_workflows = 1);
|
|
293
|
+
let core = mock_core(mock);
|
|
294
|
+
let mut worker = TestRustWorker::new(Arc::new(core), TEST_Q.to_string(), None);
|
|
295
|
+
|
|
296
|
+
worker.register_wf(
|
|
297
|
+
DEFAULT_WORKFLOW_TYPE.to_owned(),
|
|
298
|
+
|ctx: WfContext| async move {
|
|
299
|
+
let la_res = ctx
|
|
300
|
+
.local_activity(LocalActivityOptions {
|
|
301
|
+
activity_type: "echo".to_string(),
|
|
302
|
+
input: "hi".as_json_payload().expect("serializes fine"),
|
|
303
|
+
retry_policy: RetryPolicy {
|
|
304
|
+
initial_interval: Some(Duration::from_millis(65).into()),
|
|
305
|
+
// This will make the second backoff 65 seconds, plenty to use timer
|
|
306
|
+
backoff_coefficient: 1_000.,
|
|
307
|
+
maximum_interval: Some(Duration::from_secs(600).into()),
|
|
308
|
+
maximum_attempts: 3,
|
|
309
|
+
non_retryable_error_types: vec![],
|
|
310
|
+
},
|
|
311
|
+
..Default::default()
|
|
312
|
+
})
|
|
313
|
+
.await;
|
|
314
|
+
assert!(la_res.failed());
|
|
315
|
+
// Extra timer just to have an extra workflow task which we can return full history for
|
|
316
|
+
ctx.timer(Duration::from_secs(1)).await;
|
|
317
|
+
Ok(().into())
|
|
318
|
+
},
|
|
319
|
+
);
|
|
320
|
+
worker.register_activity("echo", move |_: String| async move {
|
|
321
|
+
Result::<(), _>::Err(anyhow!("Oh no I failed!"))
|
|
322
|
+
});
|
|
323
|
+
worker
|
|
324
|
+
.submit_wf(wf_id.to_owned(), DEFAULT_WORKFLOW_TYPE.to_owned(), vec![])
|
|
325
|
+
.await
|
|
326
|
+
.unwrap();
|
|
327
|
+
worker.run_until_done().await.unwrap();
|
|
328
|
+
}
|
|
@@ -1,25 +1,23 @@
|
|
|
1
1
|
mod activity_tasks;
|
|
2
2
|
mod child_workflows;
|
|
3
3
|
mod determinism;
|
|
4
|
+
mod local_activities;
|
|
4
5
|
mod queries;
|
|
5
6
|
mod replay_flag;
|
|
6
|
-
mod retry;
|
|
7
7
|
mod workers;
|
|
8
8
|
mod workflow_cancels;
|
|
9
9
|
mod workflow_tasks;
|
|
10
10
|
|
|
11
11
|
use crate::{
|
|
12
12
|
errors::{PollActivityError, PollWfError},
|
|
13
|
-
|
|
14
|
-
test_help::{
|
|
15
|
-
build_fake_core, canned_histories, fake_sg_opts, hist_to_poll_resp, ResponseType, TEST_Q,
|
|
16
|
-
},
|
|
13
|
+
test_help::{build_fake_core, canned_histories, hist_to_poll_resp, ResponseType, TEST_Q},
|
|
17
14
|
Core, CoreInitOptionsBuilder, CoreSDK, WorkerConfigBuilder,
|
|
18
15
|
};
|
|
19
16
|
use futures::FutureExt;
|
|
20
17
|
use std::time::Duration;
|
|
18
|
+
use temporal_client::mocks::{fake_sg_opts, mock_manual_gateway};
|
|
21
19
|
use temporal_sdk_core_protos::{
|
|
22
|
-
coresdk::workflow_completion::
|
|
20
|
+
coresdk::workflow_completion::WorkflowActivationCompletion,
|
|
23
21
|
temporal::api::workflowservice::v1::PollActivityTaskQueueResponse,
|
|
24
22
|
};
|
|
25
23
|
use tokio::{sync::Barrier, time::sleep};
|
|
@@ -30,7 +28,7 @@ async fn after_shutdown_server_is_not_polled() {
|
|
|
30
28
|
let core = build_fake_core("fake_wf_id", t, &[1]);
|
|
31
29
|
let res = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
32
30
|
assert_eq!(res.jobs.len(), 1);
|
|
33
|
-
core.complete_workflow_activation(
|
|
31
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::empty(TEST_Q, res.run_id))
|
|
34
32
|
.await
|
|
35
33
|
.unwrap();
|
|
36
34
|
core.shutdown().await;
|
|
@@ -46,7 +44,7 @@ lazy_static::lazy_static! {
|
|
|
46
44
|
}
|
|
47
45
|
#[tokio::test]
|
|
48
46
|
async fn shutdown_interrupts_both_polls() {
|
|
49
|
-
let mut mock_gateway =
|
|
47
|
+
let mut mock_gateway = mock_manual_gateway();
|
|
50
48
|
mock_gateway
|
|
51
49
|
.expect_poll_activity_task()
|
|
52
50
|
.times(1)
|
|
@@ -96,7 +94,6 @@ async fn shutdown_interrupts_both_polls() {
|
|
|
96
94
|
.build()
|
|
97
95
|
.unwrap(),
|
|
98
96
|
)
|
|
99
|
-
.await
|
|
100
97
|
.unwrap();
|
|
101
98
|
tokio::join! {
|
|
102
99
|
async {
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
use crate::{
|
|
2
|
-
pollers::MockServerGatewayApis,
|
|
3
2
|
test_help::{
|
|
4
3
|
canned_histories, hist_to_poll_resp, mock_core, MocksHolder, ResponseType, TEST_Q,
|
|
5
4
|
},
|
|
6
5
|
Core,
|
|
7
6
|
};
|
|
8
|
-
use std::
|
|
7
|
+
use std::{
|
|
8
|
+
collections::{HashMap, VecDeque},
|
|
9
|
+
time::Duration,
|
|
10
|
+
};
|
|
11
|
+
use temporal_client::mocks::mock_gateway;
|
|
12
|
+
|
|
9
13
|
use temporal_sdk_core_protos::{
|
|
10
14
|
coresdk::{
|
|
11
|
-
workflow_activation::{
|
|
12
|
-
workflow_commands::{CompleteWorkflowExecution, QueryResult, QuerySuccess
|
|
13
|
-
workflow_completion::
|
|
15
|
+
workflow_activation::{workflow_activation_job, WorkflowActivationJob},
|
|
16
|
+
workflow_commands::{CompleteWorkflowExecution, QueryResult, QuerySuccess},
|
|
17
|
+
workflow_completion::WorkflowActivationCompletion,
|
|
14
18
|
},
|
|
15
19
|
temporal::api::{
|
|
16
20
|
failure::v1::Failure,
|
|
@@ -21,6 +25,7 @@ use temporal_sdk_core_protos::{
|
|
|
21
25
|
},
|
|
22
26
|
},
|
|
23
27
|
};
|
|
28
|
+
use temporal_sdk_core_test_utils::start_timer_cmd;
|
|
24
29
|
|
|
25
30
|
#[rstest::rstest]
|
|
26
31
|
#[case::with_history(true)]
|
|
@@ -37,6 +42,7 @@ async fn legacy_query(#[case] include_history: bool) {
|
|
|
37
42
|
pr.query = Some(WorkflowQuery {
|
|
38
43
|
query_type: "query-type".to_string(),
|
|
39
44
|
query_args: Some(b"hi".into()),
|
|
45
|
+
header: None,
|
|
40
46
|
});
|
|
41
47
|
if !include_history {
|
|
42
48
|
pr.history = Some(History { events: vec![] });
|
|
@@ -45,7 +51,7 @@ async fn legacy_query(#[case] include_history: bool) {
|
|
|
45
51
|
},
|
|
46
52
|
hist_to_poll_resp(&t, wfid.to_owned(), 2.into(), TEST_Q.to_string()),
|
|
47
53
|
]);
|
|
48
|
-
let mut mock_gateway =
|
|
54
|
+
let mut mock_gateway = mock_gateway();
|
|
49
55
|
mock_gateway
|
|
50
56
|
.expect_complete_workflow_task()
|
|
51
57
|
.returning(|_| Ok(RespondWorkflowTaskCompletedResponse::default()));
|
|
@@ -62,21 +68,17 @@ async fn legacy_query(#[case] include_history: bool) {
|
|
|
62
68
|
|
|
63
69
|
let first_wft = || async {
|
|
64
70
|
let task = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
65
|
-
core.complete_workflow_activation(
|
|
71
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
66
72
|
TEST_Q,
|
|
67
73
|
task.run_id,
|
|
68
|
-
|
|
69
|
-
seq: 1,
|
|
70
|
-
..Default::default()
|
|
71
|
-
}
|
|
72
|
-
.into(),
|
|
74
|
+
start_timer_cmd(1, Duration::from_secs(1)),
|
|
73
75
|
))
|
|
74
76
|
.await
|
|
75
77
|
.unwrap();
|
|
76
78
|
};
|
|
77
79
|
let clear_eviction = || async {
|
|
78
80
|
let t = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
79
|
-
core.complete_workflow_activation(
|
|
81
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::empty(TEST_Q, t.run_id))
|
|
80
82
|
.await
|
|
81
83
|
.unwrap();
|
|
82
84
|
};
|
|
@@ -92,12 +94,12 @@ async fn legacy_query(#[case] include_history: bool) {
|
|
|
92
94
|
// Poll again, and we end up getting a `query` field query response
|
|
93
95
|
let query = assert_matches!(
|
|
94
96
|
task.jobs.as_slice(),
|
|
95
|
-
[
|
|
96
|
-
variant: Some(
|
|
97
|
+
[WorkflowActivationJob {
|
|
98
|
+
variant: Some(workflow_activation_job::Variant::QueryWorkflow(q)),
|
|
97
99
|
}] => q
|
|
98
100
|
);
|
|
99
101
|
// Complete the query
|
|
100
|
-
core.complete_workflow_activation(
|
|
102
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
101
103
|
TEST_Q,
|
|
102
104
|
task.run_id,
|
|
103
105
|
QueryResult {
|
|
@@ -122,11 +124,11 @@ async fn legacy_query(#[case] include_history: bool) {
|
|
|
122
124
|
let task = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
123
125
|
assert_matches!(
|
|
124
126
|
task.jobs.as_slice(),
|
|
125
|
-
[
|
|
126
|
-
variant: Some(
|
|
127
|
+
[WorkflowActivationJob {
|
|
128
|
+
variant: Some(workflow_activation_job::Variant::FireTimer(_)),
|
|
127
129
|
}]
|
|
128
130
|
);
|
|
129
|
-
core.complete_workflow_activation(
|
|
131
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
130
132
|
TEST_Q,
|
|
131
133
|
task.run_id,
|
|
132
134
|
vec![CompleteWorkflowExecution { result: None }.into()],
|
|
@@ -155,13 +157,14 @@ async fn new_queries(#[case] num_queries: usize) {
|
|
|
155
157
|
WorkflowQuery {
|
|
156
158
|
query_type: "query-type".to_string(),
|
|
157
159
|
query_args: Some(b"hi".into()),
|
|
160
|
+
header: None,
|
|
158
161
|
},
|
|
159
162
|
);
|
|
160
163
|
}
|
|
161
164
|
pr
|
|
162
165
|
},
|
|
163
166
|
]);
|
|
164
|
-
let mut mock_gateway =
|
|
167
|
+
let mut mock_gateway = mock_gateway();
|
|
165
168
|
mock_gateway
|
|
166
169
|
.expect_complete_workflow_task()
|
|
167
170
|
.returning(|_| Ok(RespondWorkflowTaskCompletedResponse::default()));
|
|
@@ -172,14 +175,10 @@ async fn new_queries(#[case] num_queries: usize) {
|
|
|
172
175
|
let core = mock_core(mock);
|
|
173
176
|
|
|
174
177
|
let task = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
175
|
-
core.complete_workflow_activation(
|
|
178
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
176
179
|
TEST_Q,
|
|
177
180
|
task.run_id,
|
|
178
|
-
|
|
179
|
-
seq: 1,
|
|
180
|
-
..Default::default()
|
|
181
|
-
}
|
|
182
|
-
.into(),
|
|
181
|
+
start_timer_cmd(1, Duration::from_secs(1)),
|
|
183
182
|
))
|
|
184
183
|
.await
|
|
185
184
|
.unwrap();
|
|
@@ -187,15 +186,15 @@ async fn new_queries(#[case] num_queries: usize) {
|
|
|
187
186
|
let task = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
188
187
|
assert_matches!(
|
|
189
188
|
task.jobs[0],
|
|
190
|
-
|
|
191
|
-
variant: Some(
|
|
189
|
+
WorkflowActivationJob {
|
|
190
|
+
variant: Some(workflow_activation_job::Variant::FireTimer(_)),
|
|
192
191
|
}
|
|
193
192
|
);
|
|
194
193
|
for i in 1..=num_queries {
|
|
195
194
|
assert_matches!(
|
|
196
195
|
task.jobs[i],
|
|
197
|
-
|
|
198
|
-
variant: Some(
|
|
196
|
+
WorkflowActivationJob {
|
|
197
|
+
variant: Some(workflow_activation_job::Variant::QueryWorkflow(_)),
|
|
199
198
|
}
|
|
200
199
|
);
|
|
201
200
|
}
|
|
@@ -214,7 +213,7 @@ async fn new_queries(#[case] num_queries: usize) {
|
|
|
214
213
|
})
|
|
215
214
|
.collect();
|
|
216
215
|
qresults.push(CompleteWorkflowExecution { result: None }.into());
|
|
217
|
-
core.complete_workflow_activation(
|
|
216
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
218
217
|
TEST_Q,
|
|
219
218
|
task.run_id,
|
|
220
219
|
qresults,
|
|
@@ -235,13 +234,14 @@ async fn legacy_query_failure_on_wft_failure() {
|
|
|
235
234
|
pr.query = Some(WorkflowQuery {
|
|
236
235
|
query_type: "query-type".to_string(),
|
|
237
236
|
query_args: Some(b"hi".into()),
|
|
237
|
+
header: None,
|
|
238
238
|
});
|
|
239
239
|
pr.history = Some(History { events: vec![] });
|
|
240
240
|
pr
|
|
241
241
|
},
|
|
242
242
|
hist_to_poll_resp(&t, wfid.to_owned(), 2.into(), TEST_Q.to_string()),
|
|
243
243
|
]);
|
|
244
|
-
let mut mock_gateway =
|
|
244
|
+
let mut mock_gateway = mock_gateway();
|
|
245
245
|
mock_gateway
|
|
246
246
|
.expect_complete_workflow_task()
|
|
247
247
|
.returning(|_| Ok(RespondWorkflowTaskCompletedResponse::default()));
|
|
@@ -255,14 +255,10 @@ async fn legacy_query_failure_on_wft_failure() {
|
|
|
255
255
|
let core = mock_core(mock);
|
|
256
256
|
|
|
257
257
|
let task = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
258
|
-
core.complete_workflow_activation(
|
|
258
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
259
259
|
TEST_Q,
|
|
260
260
|
task.run_id,
|
|
261
|
-
|
|
262
|
-
seq: 1,
|
|
263
|
-
..Default::default()
|
|
264
|
-
}
|
|
265
|
-
.into(),
|
|
261
|
+
start_timer_cmd(1, Duration::from_secs(1)),
|
|
266
262
|
))
|
|
267
263
|
.await
|
|
268
264
|
.unwrap();
|
|
@@ -271,12 +267,12 @@ async fn legacy_query_failure_on_wft_failure() {
|
|
|
271
267
|
// Poll again, and we end up getting a `query` field query response
|
|
272
268
|
assert_matches!(
|
|
273
269
|
task.jobs.as_slice(),
|
|
274
|
-
[
|
|
275
|
-
variant: Some(
|
|
270
|
+
[WorkflowActivationJob {
|
|
271
|
+
variant: Some(workflow_activation_job::Variant::QueryWorkflow(q)),
|
|
276
272
|
}] => q
|
|
277
273
|
);
|
|
278
274
|
// Fail wft which should result in query being failed
|
|
279
|
-
core.complete_workflow_activation(
|
|
275
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::fail(
|
|
280
276
|
TEST_Q,
|
|
281
277
|
task.run_id,
|
|
282
278
|
Failure {
|
|
@@ -290,10 +286,17 @@ async fn legacy_query_failure_on_wft_failure() {
|
|
|
290
286
|
core.shutdown().await;
|
|
291
287
|
}
|
|
292
288
|
|
|
289
|
+
#[rstest::rstest]
|
|
293
290
|
#[tokio::test]
|
|
294
|
-
async fn
|
|
291
|
+
async fn legacy_query_after_complete(#[values(false, true)] full_history: bool) {
|
|
295
292
|
let wfid = "fake_wf_id";
|
|
296
|
-
let t =
|
|
293
|
+
let t = if full_history {
|
|
294
|
+
canned_histories::single_timer_wf_completes("1")
|
|
295
|
+
} else {
|
|
296
|
+
let mut t = canned_histories::single_timer("1");
|
|
297
|
+
t.add_workflow_task_completed();
|
|
298
|
+
t
|
|
299
|
+
};
|
|
297
300
|
let query_with_hist_task = {
|
|
298
301
|
let mut pr = hist_to_poll_resp(
|
|
299
302
|
&t,
|
|
@@ -304,6 +307,7 @@ async fn legacy_query_with_full_history_after_complete() {
|
|
|
304
307
|
pr.query = Some(WorkflowQuery {
|
|
305
308
|
query_type: "query-type".to_string(),
|
|
306
309
|
query_args: Some(b"hi".into()),
|
|
310
|
+
header: None,
|
|
307
311
|
});
|
|
308
312
|
pr
|
|
309
313
|
};
|
|
@@ -317,7 +321,7 @@ async fn legacy_query_with_full_history_after_complete() {
|
|
|
317
321
|
query_with_hist_task.clone(),
|
|
318
322
|
query_with_hist_task,
|
|
319
323
|
]);
|
|
320
|
-
let mut mock_gateway =
|
|
324
|
+
let mut mock_gateway = mock_gateway();
|
|
321
325
|
mock_gateway
|
|
322
326
|
.expect_complete_workflow_task()
|
|
323
327
|
.returning(|_| Ok(RespondWorkflowTaskCompletedResponse::default()));
|
|
@@ -331,19 +335,15 @@ async fn legacy_query_with_full_history_after_complete() {
|
|
|
331
335
|
let core = mock_core(mock);
|
|
332
336
|
|
|
333
337
|
let task = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
334
|
-
core.complete_workflow_activation(
|
|
338
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
335
339
|
TEST_Q,
|
|
336
340
|
task.run_id,
|
|
337
|
-
|
|
338
|
-
seq: 1,
|
|
339
|
-
..Default::default()
|
|
340
|
-
}
|
|
341
|
-
.into(),
|
|
341
|
+
start_timer_cmd(1, Duration::from_secs(1)),
|
|
342
342
|
))
|
|
343
343
|
.await
|
|
344
344
|
.unwrap();
|
|
345
345
|
let task = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
346
|
-
core.complete_workflow_activation(
|
|
346
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
347
347
|
TEST_Q,
|
|
348
348
|
task.run_id,
|
|
349
349
|
vec![CompleteWorkflowExecution { result: None }.into()],
|
|
@@ -356,11 +356,11 @@ async fn legacy_query_with_full_history_after_complete() {
|
|
|
356
356
|
let task = core.poll_workflow_activation(TEST_Q).await.unwrap();
|
|
357
357
|
let query = assert_matches!(
|
|
358
358
|
task.jobs.as_slice(),
|
|
359
|
-
[
|
|
360
|
-
variant: Some(
|
|
359
|
+
[WorkflowActivationJob {
|
|
360
|
+
variant: Some(workflow_activation_job::Variant::QueryWorkflow(q)),
|
|
361
361
|
}] => q
|
|
362
362
|
);
|
|
363
|
-
core.complete_workflow_activation(
|
|
363
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
364
364
|
TEST_Q,
|
|
365
365
|
task.run_id,
|
|
366
366
|
QueryResult {
|