temporalio 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +175 -4
- data/bridge/Cargo.lock +44 -21
- data/bridge/Cargo.toml +1 -0
- data/bridge/sdk-core/Cargo.toml +1 -1
- data/bridge/sdk-core/README.md +1 -4
- data/bridge/sdk-core/client/Cargo.toml +1 -1
- data/bridge/sdk-core/client/src/lib.rs +12 -20
- data/bridge/sdk-core/client/src/raw.rs +9 -8
- data/bridge/sdk-core/client/src/retry.rs +100 -23
- data/bridge/sdk-core/core/Cargo.toml +7 -7
- data/bridge/sdk-core/core/benches/workflow_replay.rs +13 -10
- data/bridge/sdk-core/core/src/abstractions.rs +22 -22
- data/bridge/sdk-core/core/src/core_tests/activity_tasks.rs +146 -43
- data/bridge/sdk-core/core/src/core_tests/local_activities.rs +419 -9
- data/bridge/sdk-core/core/src/core_tests/queries.rs +247 -89
- data/bridge/sdk-core/core/src/core_tests/workers.rs +2 -2
- data/bridge/sdk-core/core/src/core_tests/workflow_cancels.rs +1 -1
- data/bridge/sdk-core/core/src/core_tests/workflow_tasks.rs +47 -27
- data/bridge/sdk-core/core/src/lib.rs +139 -32
- data/bridge/sdk-core/core/src/protosext/mod.rs +1 -1
- data/bridge/sdk-core/core/src/replay/mod.rs +185 -41
- data/bridge/sdk-core/core/src/telemetry/log_export.rs +190 -0
- data/bridge/sdk-core/core/src/telemetry/metrics.rs +184 -139
- data/bridge/sdk-core/core/src/telemetry/mod.rs +310 -315
- data/bridge/sdk-core/core/src/telemetry/prometheus_server.rs +4 -3
- data/bridge/sdk-core/core/src/test_help/mod.rs +23 -9
- data/bridge/sdk-core/core/src/worker/activities/local_activities.rs +12 -6
- data/bridge/sdk-core/core/src/worker/activities.rs +40 -23
- data/bridge/sdk-core/core/src/worker/client/mocks.rs +1 -1
- data/bridge/sdk-core/core/src/worker/client.rs +30 -4
- data/bridge/sdk-core/core/src/worker/mod.rs +23 -19
- data/bridge/sdk-core/core/src/worker/workflow/driven_workflow.rs +10 -19
- data/bridge/sdk-core/core/src/worker/workflow/history_update.rs +99 -25
- data/bridge/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +1 -5
- data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -5
- data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +1 -5
- data/bridge/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +3 -5
- data/bridge/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +1 -5
- data/bridge/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +2 -6
- data/bridge/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +1 -5
- data/bridge/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +24 -22
- data/bridge/sdk-core/core/src/worker/workflow/machines/mod.rs +12 -38
- data/bridge/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +178 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +1 -5
- data/bridge/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -5
- data/bridge/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +1 -5
- data/bridge/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +8 -2
- data/bridge/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +1 -5
- data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +1 -1
- data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +233 -217
- data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +1 -6
- data/bridge/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +4 -4
- data/bridge/sdk-core/core/src/worker/workflow/managed_run.rs +13 -5
- data/bridge/sdk-core/core/src/worker/workflow/mod.rs +86 -29
- data/bridge/sdk-core/core/src/worker/workflow/wft_poller.rs +2 -2
- data/bridge/sdk-core/core/src/worker/workflow/workflow_stream.rs +56 -11
- data/bridge/sdk-core/core-api/Cargo.toml +4 -3
- data/bridge/sdk-core/core-api/src/lib.rs +1 -43
- data/bridge/sdk-core/core-api/src/telemetry.rs +147 -0
- data/bridge/sdk-core/core-api/src/worker.rs +13 -0
- data/bridge/sdk-core/etc/deps.svg +115 -140
- data/bridge/sdk-core/etc/regen-depgraph.sh +5 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +1 -1
- data/bridge/sdk-core/histories/evict_while_la_running_no_interference-23_history.bin +0 -0
- data/bridge/sdk-core/histories/evict_while_la_running_no_interference-85_history.bin +0 -0
- data/bridge/sdk-core/protos/api_upstream/buf.yaml +0 -3
- data/bridge/sdk-core/protos/api_upstream/build/go.mod +7 -0
- data/bridge/sdk-core/protos/api_upstream/build/go.sum +5 -0
- data/bridge/sdk-core/protos/api_upstream/{temporal/api/update/v1/message.proto → build/tools.go} +6 -23
- data/bridge/sdk-core/protos/api_upstream/go.mod +6 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +12 -9
- data/bridge/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +20 -19
- data/bridge/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +3 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +4 -4
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +3 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +5 -3
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +23 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/{cluster.proto → interaction_type.proto} +10 -11
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/query.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +2 -13
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/filter/v1/message.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +26 -19
- data/bridge/sdk-core/protos/api_upstream/temporal/api/interaction/v1/message.proto +87 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +21 -61
- data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +2 -21
- data/bridge/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +110 -31
- data/bridge/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +4 -4
- data/bridge/sdk-core/protos/api_upstream/temporal/api/version/v1/message.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +3 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +60 -16
- data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +17 -3
- data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +2 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +8 -1
- data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +2 -2
- data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +2 -2
- data/bridge/sdk-core/sdk/Cargo.toml +2 -2
- data/bridge/sdk-core/sdk/src/interceptors.rs +36 -3
- data/bridge/sdk-core/sdk/src/lib.rs +7 -5
- data/bridge/sdk-core/sdk/src/workflow_context.rs +13 -2
- data/bridge/sdk-core/sdk/src/workflow_future.rs +3 -7
- data/bridge/sdk-core/sdk-core-protos/Cargo.toml +1 -1
- data/bridge/sdk-core/sdk-core-protos/build.rs +0 -1
- data/bridge/sdk-core/sdk-core-protos/src/history_builder.rs +65 -18
- data/bridge/sdk-core/sdk-core-protos/src/history_info.rs +22 -22
- data/bridge/sdk-core/sdk-core-protos/src/lib.rs +104 -44
- data/bridge/sdk-core/test-utils/Cargo.toml +2 -1
- data/bridge/sdk-core/test-utils/src/lib.rs +81 -29
- data/bridge/sdk-core/tests/integ_tests/heartbeat_tests.rs +5 -2
- data/bridge/sdk-core/tests/integ_tests/metrics_tests.rs +37 -0
- data/bridge/sdk-core/tests/integ_tests/polling_tests.rs +0 -13
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +167 -13
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +53 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/replay.rs +106 -20
- data/bridge/sdk-core/tests/integ_tests/workflow_tests.rs +18 -8
- data/bridge/sdk-core/tests/main.rs +6 -4
- data/bridge/src/connection.rs +81 -62
- data/bridge/src/lib.rs +92 -33
- data/bridge/src/runtime.rs +9 -2
- data/bridge/src/worker.rs +53 -2
- data/lib/bridge.so +0 -0
- data/lib/gen/temporal/api/batch/v1/message_pb.rb +8 -6
- data/lib/gen/temporal/api/command/v1/message_pb.rb +17 -9
- data/lib/gen/temporal/api/common/v1/message_pb.rb +1 -1
- data/lib/gen/temporal/api/enums/v1/batch_operation_pb.rb +2 -1
- data/lib/gen/temporal/api/enums/v1/command_type_pb.rb +3 -1
- data/lib/gen/temporal/api/enums/v1/common_pb.rb +2 -1
- data/lib/gen/temporal/api/enums/v1/event_type_pb.rb +3 -2
- data/lib/gen/temporal/api/enums/v1/failed_cause_pb.rb +7 -1
- data/lib/gen/temporal/api/enums/v1/interaction_type_pb.rb +25 -0
- data/lib/gen/temporal/api/enums/v1/namespace_pb.rb +1 -1
- data/lib/gen/temporal/api/enums/v1/query_pb.rb +1 -1
- data/lib/gen/temporal/api/enums/v1/reset_pb.rb +1 -1
- data/lib/gen/temporal/api/enums/v1/schedule_pb.rb +1 -1
- data/lib/gen/temporal/api/enums/v1/task_queue_pb.rb +1 -1
- data/lib/gen/temporal/api/enums/v1/update_pb.rb +1 -6
- data/lib/gen/temporal/api/enums/v1/workflow_pb.rb +1 -1
- data/lib/gen/temporal/api/errordetails/v1/message_pb.rb +1 -1
- data/lib/gen/temporal/api/failure/v1/message_pb.rb +1 -1
- data/lib/gen/temporal/api/filter/v1/message_pb.rb +1 -1
- data/lib/gen/temporal/api/history/v1/message_pb.rb +19 -18
- data/lib/gen/temporal/api/interaction/v1/message_pb.rb +49 -0
- data/lib/gen/temporal/api/namespace/v1/message_pb.rb +1 -1
- data/lib/gen/temporal/api/operatorservice/v1/request_response_pb.rb +11 -51
- data/lib/gen/temporal/api/operatorservice/v1/service_pb.rb +1 -1
- data/lib/gen/temporal/api/query/v1/message_pb.rb +1 -1
- data/lib/gen/temporal/api/replication/v1/message_pb.rb +1 -1
- data/lib/gen/temporal/api/schedule/v1/message_pb.rb +22 -1
- data/lib/gen/temporal/api/taskqueue/v1/message_pb.rb +2 -2
- data/lib/gen/temporal/api/version/v1/message_pb.rb +1 -1
- data/lib/gen/temporal/api/workflow/v1/message_pb.rb +2 -1
- data/lib/gen/temporal/api/workflowservice/v1/request_response_pb.rb +27 -10
- data/lib/gen/temporal/api/workflowservice/v1/service_pb.rb +1 -1
- data/lib/gen/temporal/sdk/core/workflow_activation/workflow_activation_pb.rb +1 -0
- data/lib/gen/temporal/sdk/core/workflow_commands/workflow_commands_pb.rb +5 -1
- data/lib/temporalio/activity/context.rb +97 -0
- data/lib/temporalio/activity/info.rb +67 -0
- data/lib/temporalio/activity.rb +85 -0
- data/lib/temporalio/bridge/error.rb +8 -0
- data/lib/temporalio/bridge.rb +14 -0
- data/lib/{temporal → temporalio}/client/implementation.rb +49 -48
- data/lib/{temporal → temporalio}/client/workflow_handle.rb +35 -35
- data/lib/{temporal → temporalio}/client.rb +19 -32
- data/lib/{temporal → temporalio}/connection.rb +238 -223
- data/lib/{temporal → temporalio}/data_converter.rb +76 -35
- data/lib/{temporal → temporalio}/error/failure.rb +6 -6
- data/lib/{temporal → temporalio}/error/workflow_failure.rb +4 -2
- data/lib/{temporal → temporalio}/errors.rb +19 -1
- data/lib/{temporal → temporalio}/failure_converter/base.rb +5 -5
- data/lib/{temporal → temporalio}/failure_converter/basic.rb +58 -52
- data/lib/temporalio/failure_converter.rb +7 -0
- data/lib/{temporal → temporalio}/interceptor/chain.rb +2 -1
- data/lib/{temporal → temporalio}/interceptor/client.rb +22 -1
- data/lib/{temporal → temporalio}/payload_codec/base.rb +5 -5
- data/lib/{temporal → temporalio}/payload_converter/base.rb +3 -3
- data/lib/{temporal → temporalio}/payload_converter/bytes.rb +4 -3
- data/lib/{temporal → temporalio}/payload_converter/composite.rb +7 -5
- data/lib/{temporal → temporalio}/payload_converter/encoding_base.rb +4 -4
- data/lib/{temporal → temporalio}/payload_converter/json.rb +4 -3
- data/lib/{temporal → temporalio}/payload_converter/nil.rb +4 -3
- data/lib/temporalio/payload_converter.rb +14 -0
- data/lib/{temporal → temporalio}/retry_policy.rb +4 -4
- data/lib/{temporal → temporalio}/retry_state.rb +1 -1
- data/lib/temporalio/runtime.rb +25 -0
- data/lib/{temporal → temporalio}/timeout_type.rb +2 -2
- data/lib/temporalio/version.rb +3 -0
- data/lib/temporalio/worker/activity_runner.rb +92 -0
- data/lib/temporalio/worker/activity_worker.rb +138 -0
- data/lib/temporalio/worker/reactor.rb +46 -0
- data/lib/temporalio/worker/runner.rb +63 -0
- data/lib/temporalio/worker/sync_worker.rb +88 -0
- data/lib/temporalio/worker/thread_pool_executor.rb +51 -0
- data/lib/temporalio/worker.rb +198 -0
- data/lib/{temporal → temporalio}/workflow/execution_info.rb +4 -4
- data/lib/{temporal → temporalio}/workflow/execution_status.rb +1 -1
- data/lib/{temporal → temporalio}/workflow/id_reuse_policy.rb +6 -6
- data/lib/{temporal → temporalio}/workflow/query_reject_condition.rb +5 -5
- data/lib/temporalio.rb +12 -3
- data/temporalio.gemspec +7 -3
- metadata +79 -56
- data/bridge/sdk-core/bridge-ffi/Cargo.toml +0 -24
- data/bridge/sdk-core/bridge-ffi/LICENSE.txt +0 -23
- data/bridge/sdk-core/bridge-ffi/build.rs +0 -25
- data/bridge/sdk-core/bridge-ffi/include/sdk-core-bridge.h +0 -249
- data/bridge/sdk-core/bridge-ffi/src/lib.rs +0 -825
- data/bridge/sdk-core/bridge-ffi/src/wrappers.rs +0 -211
- data/bridge/sdk-core/core/src/log_export.rs +0 -62
- data/bridge/sdk-core/core/src/worker/workflow/machines/mutable_side_effect_state_machine.rs +0 -127
- data/bridge/sdk-core/core/src/worker/workflow/machines/side_effect_state_machine.rs +0 -71
- data/bridge/sdk-core/protos/api_upstream/temporal/api/cluster/v1/message.proto +0 -83
- data/bridge/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +0 -210
- data/bridge/sdk-core/sdk/src/conversions.rs +0 -8
- data/lib/gen/temporal/api/cluster/v1/message_pb.rb +0 -67
- data/lib/gen/temporal/api/enums/v1/cluster_pb.rb +0 -26
- data/lib/gen/temporal/api/update/v1/message_pb.rb +0 -26
- data/lib/temporal/bridge.rb +0 -14
- data/lib/temporal/failure_converter.rb +0 -8
- data/lib/temporal/payload_converter.rb +0 -14
- data/lib/temporal/runtime.rb +0 -22
- data/lib/temporal/version.rb +0 -3
- data/lib/temporal.rb +0 -8
|
@@ -3,19 +3,20 @@ use crate::{
|
|
|
3
3
|
replay::{default_wes_attribs, TestHistoryBuilder, DEFAULT_WORKFLOW_TYPE},
|
|
4
4
|
test_help::{
|
|
5
5
|
hist_to_poll_resp, mock_sdk, mock_sdk_cfg, mock_worker, single_hist_mock_sg, MockPollCfg,
|
|
6
|
-
ResponseType,
|
|
6
|
+
ResponseType,
|
|
7
7
|
},
|
|
8
|
-
worker::client::mocks::mock_workflow_client,
|
|
8
|
+
worker::{client::mocks::mock_workflow_client, LEGACY_QUERY_ID},
|
|
9
9
|
};
|
|
10
10
|
use anyhow::anyhow;
|
|
11
11
|
use futures::{future::join_all, FutureExt};
|
|
12
12
|
use std::{
|
|
13
13
|
collections::HashMap,
|
|
14
|
+
ops::Sub,
|
|
14
15
|
sync::{
|
|
15
16
|
atomic::{AtomicUsize, Ordering},
|
|
16
17
|
Arc,
|
|
17
18
|
},
|
|
18
|
-
time::Duration,
|
|
19
|
+
time::{Duration, SystemTime},
|
|
19
20
|
};
|
|
20
21
|
use temporal_client::WorkflowOptions;
|
|
21
22
|
use temporal_sdk::{ActContext, LocalActivityOptions, WfContext, WorkflowResult};
|
|
@@ -29,11 +30,16 @@ use temporal_sdk_core_protos::{
|
|
|
29
30
|
ActivityTaskCompletion, AsJsonPayloadExt,
|
|
30
31
|
},
|
|
31
32
|
temporal::api::{
|
|
32
|
-
common::v1::RetryPolicy,
|
|
33
|
+
common::v1::RetryPolicy,
|
|
34
|
+
enums::v1::{EventType, TimeoutType},
|
|
35
|
+
failure::v1::Failure,
|
|
36
|
+
history::v1::History,
|
|
33
37
|
query::v1::WorkflowQuery,
|
|
34
38
|
},
|
|
35
39
|
};
|
|
36
|
-
use temporal_sdk_core_test_utils::{
|
|
40
|
+
use temporal_sdk_core_test_utils::{
|
|
41
|
+
schedule_local_activity_cmd, start_timer_cmd, WorkerTestHelpers,
|
|
42
|
+
};
|
|
37
43
|
use tokio::sync::Barrier;
|
|
38
44
|
|
|
39
45
|
async fn echo(_ctx: ActContext, e: String) -> anyhow::Result<String> {
|
|
@@ -365,7 +371,7 @@ async fn local_act_null_result() {
|
|
|
365
371
|
let mut t = TestHistoryBuilder::default();
|
|
366
372
|
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
367
373
|
t.add_full_wf_task();
|
|
368
|
-
t.add_local_activity_marker(1, "1", None, None,
|
|
374
|
+
t.add_local_activity_marker(1, "1", None, None, |_| {});
|
|
369
375
|
t.add_workflow_execution_completed();
|
|
370
376
|
|
|
371
377
|
let wf_id = "fakeid";
|
|
@@ -398,6 +404,50 @@ async fn local_act_null_result() {
|
|
|
398
404
|
worker.run_until_done().await.unwrap();
|
|
399
405
|
}
|
|
400
406
|
|
|
407
|
+
#[tokio::test]
|
|
408
|
+
async fn local_act_command_immediately_follows_la_marker() {
|
|
409
|
+
// This repro only works both when cache is off, and there is at least one heartbeat wft
|
|
410
|
+
// before the marker & next command are recorded.
|
|
411
|
+
let mut t = TestHistoryBuilder::default();
|
|
412
|
+
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
413
|
+
t.add_full_wf_task();
|
|
414
|
+
t.add_full_wf_task();
|
|
415
|
+
t.add_local_activity_result_marker(1, "1", "done".into());
|
|
416
|
+
t.add_get_event_id(EventType::TimerStarted, None);
|
|
417
|
+
t.add_full_wf_task();
|
|
418
|
+
|
|
419
|
+
let wf_id = "fakeid";
|
|
420
|
+
let mock = mock_workflow_client();
|
|
421
|
+
// Bug only repros when seeing history up to third wft
|
|
422
|
+
let mh = MockPollCfg::from_resp_batches(wf_id, t, [3], mock);
|
|
423
|
+
let mut worker = mock_sdk_cfg(mh, |w| w.max_cached_workflows = 0);
|
|
424
|
+
|
|
425
|
+
worker.register_wf(
|
|
426
|
+
DEFAULT_WORKFLOW_TYPE.to_owned(),
|
|
427
|
+
|ctx: WfContext| async move {
|
|
428
|
+
ctx.local_activity(LocalActivityOptions {
|
|
429
|
+
activity_type: "nullres".to_string(),
|
|
430
|
+
input: "hi".as_json_payload().expect("serializes fine"),
|
|
431
|
+
..Default::default()
|
|
432
|
+
})
|
|
433
|
+
.await;
|
|
434
|
+
ctx.timer(Duration::from_secs(1)).await;
|
|
435
|
+
Ok(().into())
|
|
436
|
+
},
|
|
437
|
+
);
|
|
438
|
+
worker.register_activity("nullres", |_ctx: ActContext, _: String| async { Ok(()) });
|
|
439
|
+
worker
|
|
440
|
+
.submit_wf(
|
|
441
|
+
wf_id.to_owned(),
|
|
442
|
+
DEFAULT_WORKFLOW_TYPE.to_owned(),
|
|
443
|
+
vec![],
|
|
444
|
+
WorkflowOptions::default(),
|
|
445
|
+
)
|
|
446
|
+
.await
|
|
447
|
+
.unwrap();
|
|
448
|
+
worker.run_until_done().await.unwrap();
|
|
449
|
+
}
|
|
450
|
+
|
|
401
451
|
#[tokio::test]
|
|
402
452
|
async fn query_during_wft_heartbeat_doesnt_accidentally_fail_to_continue_heartbeat() {
|
|
403
453
|
let wfid = "fake_wf_id";
|
|
@@ -411,11 +461,11 @@ async fn query_during_wft_heartbeat_doesnt_accidentally_fail_to_continue_heartbe
|
|
|
411
461
|
t.add_full_wf_task();
|
|
412
462
|
// get query here
|
|
413
463
|
t.add_full_wf_task();
|
|
414
|
-
t.
|
|
464
|
+
t.add_local_activity_result_marker(1, "1", "done".into());
|
|
415
465
|
t.add_workflow_execution_completed();
|
|
416
466
|
|
|
417
467
|
let query_with_hist_task = {
|
|
418
|
-
let mut pr = hist_to_poll_resp(&t, wfid, ResponseType::ToTaskNum(1)
|
|
468
|
+
let mut pr = hist_to_poll_resp(&t, wfid, ResponseType::ToTaskNum(1));
|
|
419
469
|
pr.queries = HashMap::new();
|
|
420
470
|
pr.queries.insert(
|
|
421
471
|
"the-query".to_string(),
|
|
@@ -441,7 +491,6 @@ async fn query_during_wft_heartbeat_doesnt_accidentally_fail_to_continue_heartbe
|
|
|
441
491
|
.boxed(),
|
|
442
492
|
3,
|
|
443
493
|
),
|
|
444
|
-
TEST_Q,
|
|
445
494
|
),
|
|
446
495
|
];
|
|
447
496
|
let mock = mock_workflow_client();
|
|
@@ -513,3 +562,364 @@ async fn query_during_wft_heartbeat_doesnt_accidentally_fail_to_continue_heartbe
|
|
|
513
562
|
|
|
514
563
|
tokio::join!(wf_fut, act_fut);
|
|
515
564
|
}
|
|
565
|
+
|
|
566
|
+
#[rstest::rstest]
|
|
567
|
+
#[case::impossible_query_in_task(true)]
|
|
568
|
+
#[case::real_history(false)]
|
|
569
|
+
#[tokio::test]
|
|
570
|
+
async fn la_resolve_during_legacy_query_does_not_combine(#[case] impossible_query_in_task: bool) {
|
|
571
|
+
// Ensures we do not send an activation with a legacy query and any other work, which should
|
|
572
|
+
// never happen, but there was an issue where an LA resolving could trigger that.
|
|
573
|
+
let wfid = "fake_wf_id";
|
|
574
|
+
let mut t = TestHistoryBuilder::default();
|
|
575
|
+
let wes_short_wft_timeout = default_wes_attribs();
|
|
576
|
+
t.add(
|
|
577
|
+
EventType::WorkflowExecutionStarted,
|
|
578
|
+
wes_short_wft_timeout.into(),
|
|
579
|
+
);
|
|
580
|
+
// Since we don't send queries with start workflow, need one workflow task of something else
|
|
581
|
+
// b/c we want to get an activation with a job and a nonlegacy query
|
|
582
|
+
t.add_full_wf_task();
|
|
583
|
+
let timer_started_event_id = t.add_get_event_id(EventType::TimerStarted, None);
|
|
584
|
+
t.add_timer_fired(timer_started_event_id, "1".to_string());
|
|
585
|
+
|
|
586
|
+
// nonlegacy query got here & LA started here
|
|
587
|
+
t.add_full_wf_task();
|
|
588
|
+
// legacy query got here, at the same time that the LA is resolved
|
|
589
|
+
t.add_local_activity_result_marker(1, "1", "whatever".into());
|
|
590
|
+
t.add_workflow_execution_completed();
|
|
591
|
+
|
|
592
|
+
let barr = Arc::new(Barrier::new(2));
|
|
593
|
+
let barr_c = barr.clone();
|
|
594
|
+
|
|
595
|
+
let tasks = [
|
|
596
|
+
hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::ToTaskNum(1)),
|
|
597
|
+
{
|
|
598
|
+
let mut pr = hist_to_poll_resp(&t, wfid.to_owned(), ResponseType::OneTask(2));
|
|
599
|
+
pr.queries = HashMap::new();
|
|
600
|
+
pr.queries.insert(
|
|
601
|
+
"q1".to_string(),
|
|
602
|
+
WorkflowQuery {
|
|
603
|
+
query_type: "query-type".to_string(),
|
|
604
|
+
query_args: Some(b"hi".into()),
|
|
605
|
+
header: None,
|
|
606
|
+
},
|
|
607
|
+
);
|
|
608
|
+
pr
|
|
609
|
+
},
|
|
610
|
+
{
|
|
611
|
+
let mut pr = hist_to_poll_resp(
|
|
612
|
+
&t,
|
|
613
|
+
wfid.to_owned(),
|
|
614
|
+
ResponseType::UntilResolved(
|
|
615
|
+
async move {
|
|
616
|
+
barr_c.wait().await;
|
|
617
|
+
// This sleep is the only not-incredibly-invasive way to ensure the LA
|
|
618
|
+
// resolves & updates machines before we process this task
|
|
619
|
+
tokio::time::sleep(Duration::from_secs(1)).await;
|
|
620
|
+
}
|
|
621
|
+
.boxed(),
|
|
622
|
+
2,
|
|
623
|
+
),
|
|
624
|
+
);
|
|
625
|
+
// Strip history, we need to look like we hit the cache
|
|
626
|
+
pr.history = Some(History { events: vec![] });
|
|
627
|
+
// In the nonsense server response case, we attach a legacy query, otherwise this
|
|
628
|
+
// response looks like a normal response to a forced WFT heartbeat.
|
|
629
|
+
if impossible_query_in_task {
|
|
630
|
+
pr.query = Some(WorkflowQuery {
|
|
631
|
+
query_type: "query-type".to_string(),
|
|
632
|
+
query_args: Some(b"hi".into()),
|
|
633
|
+
header: None,
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
pr
|
|
637
|
+
},
|
|
638
|
+
];
|
|
639
|
+
let mut mock = mock_workflow_client();
|
|
640
|
+
if impossible_query_in_task {
|
|
641
|
+
mock.expect_respond_legacy_query()
|
|
642
|
+
.times(1)
|
|
643
|
+
.returning(move |_, _| Ok(Default::default()));
|
|
644
|
+
}
|
|
645
|
+
let mut mock = single_hist_mock_sg(wfid, t, tasks, mock, true);
|
|
646
|
+
mock.worker_cfg(|wc| wc.max_cached_workflows = 1);
|
|
647
|
+
let core = mock_worker(mock);
|
|
648
|
+
|
|
649
|
+
let wf_fut = async {
|
|
650
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
651
|
+
assert_matches!(
|
|
652
|
+
task.jobs.as_slice(),
|
|
653
|
+
&[WorkflowActivationJob {
|
|
654
|
+
variant: Some(workflow_activation_job::Variant::StartWorkflow(_)),
|
|
655
|
+
},]
|
|
656
|
+
);
|
|
657
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
658
|
+
task.run_id,
|
|
659
|
+
start_timer_cmd(1, Duration::from_secs(1)),
|
|
660
|
+
))
|
|
661
|
+
.await
|
|
662
|
+
.unwrap();
|
|
663
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
664
|
+
assert_matches!(
|
|
665
|
+
task.jobs.as_slice(),
|
|
666
|
+
&[
|
|
667
|
+
WorkflowActivationJob {
|
|
668
|
+
variant: Some(workflow_activation_job::Variant::FireTimer(_)),
|
|
669
|
+
},
|
|
670
|
+
WorkflowActivationJob {
|
|
671
|
+
variant: Some(workflow_activation_job::Variant::QueryWorkflow(_)),
|
|
672
|
+
}
|
|
673
|
+
]
|
|
674
|
+
);
|
|
675
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
676
|
+
task.run_id,
|
|
677
|
+
vec![
|
|
678
|
+
schedule_local_activity_cmd(
|
|
679
|
+
1,
|
|
680
|
+
"act-id",
|
|
681
|
+
ActivityCancellationType::TryCancel,
|
|
682
|
+
Duration::from_secs(60),
|
|
683
|
+
),
|
|
684
|
+
QueryResult {
|
|
685
|
+
query_id: "q1".to_string(),
|
|
686
|
+
variant: Some(
|
|
687
|
+
QuerySuccess {
|
|
688
|
+
response: Some("whatev".into()),
|
|
689
|
+
}
|
|
690
|
+
.into(),
|
|
691
|
+
),
|
|
692
|
+
}
|
|
693
|
+
.into(),
|
|
694
|
+
],
|
|
695
|
+
))
|
|
696
|
+
.await
|
|
697
|
+
.unwrap();
|
|
698
|
+
barr.wait().await;
|
|
699
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
700
|
+
// The next task needs to be resolve, since the LA is completed immediately
|
|
701
|
+
assert_matches!(
|
|
702
|
+
task.jobs.as_slice(),
|
|
703
|
+
[WorkflowActivationJob {
|
|
704
|
+
variant: Some(workflow_activation_job::Variant::ResolveActivity(_)),
|
|
705
|
+
}]
|
|
706
|
+
);
|
|
707
|
+
// Complete workflow
|
|
708
|
+
core.complete_execution(&task.run_id).await;
|
|
709
|
+
if impossible_query_in_task {
|
|
710
|
+
// finish last query
|
|
711
|
+
let task = core.poll_workflow_activation().await.unwrap();
|
|
712
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
713
|
+
task.run_id,
|
|
714
|
+
vec![QueryResult {
|
|
715
|
+
query_id: LEGACY_QUERY_ID.to_string(),
|
|
716
|
+
variant: Some(
|
|
717
|
+
QuerySuccess {
|
|
718
|
+
response: Some("whatev".into()),
|
|
719
|
+
}
|
|
720
|
+
.into(),
|
|
721
|
+
),
|
|
722
|
+
}
|
|
723
|
+
.into()],
|
|
724
|
+
))
|
|
725
|
+
.await
|
|
726
|
+
.unwrap();
|
|
727
|
+
}
|
|
728
|
+
};
|
|
729
|
+
let act_fut = async {
|
|
730
|
+
let act_task = core.poll_activity_task().await.unwrap();
|
|
731
|
+
core.complete_activity_task(ActivityTaskCompletion {
|
|
732
|
+
task_token: act_task.task_token,
|
|
733
|
+
result: Some(ActivityExecutionResult::ok(vec![1].into())),
|
|
734
|
+
})
|
|
735
|
+
.await
|
|
736
|
+
.unwrap();
|
|
737
|
+
};
|
|
738
|
+
|
|
739
|
+
tokio::join!(wf_fut, act_fut);
|
|
740
|
+
core.shutdown().await;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
#[tokio::test]
|
|
744
|
+
async fn test_schedule_to_start_timeout() {
|
|
745
|
+
let mut t = TestHistoryBuilder::default();
|
|
746
|
+
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
747
|
+
t.add_full_wf_task();
|
|
748
|
+
|
|
749
|
+
let wf_id = "fakeid";
|
|
750
|
+
let mock = mock_workflow_client();
|
|
751
|
+
let mh = MockPollCfg::from_resp_batches(wf_id, t, [ResponseType::ToTaskNum(1)], mock);
|
|
752
|
+
let mut worker = mock_sdk_cfg(mh, |w| w.max_cached_workflows = 1);
|
|
753
|
+
|
|
754
|
+
worker.register_wf(
|
|
755
|
+
DEFAULT_WORKFLOW_TYPE.to_owned(),
|
|
756
|
+
|ctx: WfContext| async move {
|
|
757
|
+
let la_res = ctx
|
|
758
|
+
.local_activity(LocalActivityOptions {
|
|
759
|
+
activity_type: "echo".to_string(),
|
|
760
|
+
input: "hi".as_json_payload().expect("serializes fine"),
|
|
761
|
+
// Impossibly small timeout so we timeout in the queue
|
|
762
|
+
schedule_to_start_timeout: prost_dur!(from_nanos(1)),
|
|
763
|
+
..Default::default()
|
|
764
|
+
})
|
|
765
|
+
.await;
|
|
766
|
+
assert_eq!(la_res.timed_out(), Some(TimeoutType::ScheduleToStart));
|
|
767
|
+
Ok(().into())
|
|
768
|
+
},
|
|
769
|
+
);
|
|
770
|
+
worker.register_activity(
|
|
771
|
+
"echo",
|
|
772
|
+
move |_ctx: ActContext, _: String| async move { Ok(()) },
|
|
773
|
+
);
|
|
774
|
+
worker
|
|
775
|
+
.submit_wf(
|
|
776
|
+
wf_id.to_owned(),
|
|
777
|
+
DEFAULT_WORKFLOW_TYPE.to_owned(),
|
|
778
|
+
vec![],
|
|
779
|
+
WorkflowOptions::default(),
|
|
780
|
+
)
|
|
781
|
+
.await
|
|
782
|
+
.unwrap();
|
|
783
|
+
worker.run_until_done().await.unwrap();
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
#[tokio::test]
|
|
787
|
+
async fn test_schedule_to_start_timeout_not_based_on_original_time() {
|
|
788
|
+
// We used to carry over the schedule time of LAs from the "original" schedule time if these LAs
|
|
789
|
+
// created newly after backing off across a timer. That was a mistake, since schedule-to-start
|
|
790
|
+
// timeouts should apply to when the new attempt was scheduled. This test verifies we don't
|
|
791
|
+
// time out on s-t-s timeouts because of that.
|
|
792
|
+
let mut t = TestHistoryBuilder::default();
|
|
793
|
+
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
794
|
+
t.add_full_wf_task();
|
|
795
|
+
let orig_sched = SystemTime::now().sub(Duration::from_secs(60 * 20));
|
|
796
|
+
t.add_local_activity_marker(
|
|
797
|
+
1,
|
|
798
|
+
"1",
|
|
799
|
+
None,
|
|
800
|
+
Some(Failure::application_failure("la failed".to_string(), false)),
|
|
801
|
+
|deets| {
|
|
802
|
+
// Really old schedule time, which should _not_ count against schedule_to_start
|
|
803
|
+
deets.original_schedule_time = Some(orig_sched.into());
|
|
804
|
+
// Backoff value must be present since we're simulating timer backoff
|
|
805
|
+
deets.backoff = Some(prost_dur!(from_secs(100)));
|
|
806
|
+
},
|
|
807
|
+
);
|
|
808
|
+
let timer_started_event_id = t.add_get_event_id(EventType::TimerStarted, None);
|
|
809
|
+
t.add_timer_fired(timer_started_event_id, "1".to_string());
|
|
810
|
+
t.add_workflow_task_scheduled_and_started();
|
|
811
|
+
|
|
812
|
+
let wf_id = "fakeid";
|
|
813
|
+
let mock = mock_workflow_client();
|
|
814
|
+
let mh = MockPollCfg::from_resp_batches(wf_id, t, [ResponseType::AllHistory], mock);
|
|
815
|
+
let mut worker = mock_sdk_cfg(mh, |w| w.max_cached_workflows = 1);
|
|
816
|
+
|
|
817
|
+
worker.register_wf(
|
|
818
|
+
DEFAULT_WORKFLOW_TYPE.to_owned(),
|
|
819
|
+
|ctx: WfContext| async move {
|
|
820
|
+
let la_res = ctx
|
|
821
|
+
.local_activity(LocalActivityOptions {
|
|
822
|
+
activity_type: "echo".to_string(),
|
|
823
|
+
input: "hi".as_json_payload().expect("serializes fine"),
|
|
824
|
+
retry_policy: RetryPolicy {
|
|
825
|
+
initial_interval: Some(prost_dur!(from_millis(50))),
|
|
826
|
+
backoff_coefficient: 1.2,
|
|
827
|
+
maximum_interval: None,
|
|
828
|
+
maximum_attempts: 5,
|
|
829
|
+
non_retryable_error_types: vec![],
|
|
830
|
+
},
|
|
831
|
+
schedule_to_start_timeout: Some(Duration::from_secs(60)),
|
|
832
|
+
schedule_to_close_timeout: Some(Duration::from_secs(60 * 60)),
|
|
833
|
+
..Default::default()
|
|
834
|
+
})
|
|
835
|
+
.await;
|
|
836
|
+
assert!(la_res.completed_ok());
|
|
837
|
+
Ok(().into())
|
|
838
|
+
},
|
|
839
|
+
);
|
|
840
|
+
worker.register_activity(
|
|
841
|
+
"echo",
|
|
842
|
+
move |_ctx: ActContext, _: String| async move { Ok(()) },
|
|
843
|
+
);
|
|
844
|
+
worker
|
|
845
|
+
.submit_wf(
|
|
846
|
+
wf_id.to_owned(),
|
|
847
|
+
DEFAULT_WORKFLOW_TYPE.to_owned(),
|
|
848
|
+
vec![],
|
|
849
|
+
WorkflowOptions::default(),
|
|
850
|
+
)
|
|
851
|
+
.await
|
|
852
|
+
.unwrap();
|
|
853
|
+
worker.run_until_done().await.unwrap();
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
#[tokio::test]
|
|
857
|
+
async fn test_schedule_to_close_timeout_based_on_original_time() {
|
|
858
|
+
// We used to carry over the schedule time of LAs from the "original" schedule time if these LAs
|
|
859
|
+
// created newly after backing off across a timer. That was a mistake, since schedule-to-start
|
|
860
|
+
// timeouts should apply to when the new attempt was scheduled. This test verifies we don't
|
|
861
|
+
// time out on s-t-s timeouts because of that.
|
|
862
|
+
let mut t = TestHistoryBuilder::default();
|
|
863
|
+
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
864
|
+
t.add_full_wf_task();
|
|
865
|
+
let orig_sched = SystemTime::now().sub(Duration::from_secs(60 * 20));
|
|
866
|
+
t.add_local_activity_marker(
|
|
867
|
+
1,
|
|
868
|
+
"1",
|
|
869
|
+
None,
|
|
870
|
+
Some(Failure::application_failure("la failed".to_string(), false)),
|
|
871
|
+
|deets| {
|
|
872
|
+
// Really old schedule time, which should _not_ count against schedule_to_start
|
|
873
|
+
deets.original_schedule_time = Some(orig_sched.into());
|
|
874
|
+
// Backoff value must be present since we're simulating timer backoff
|
|
875
|
+
deets.backoff = Some(prost_dur!(from_secs(100)));
|
|
876
|
+
},
|
|
877
|
+
);
|
|
878
|
+
let timer_started_event_id = t.add_get_event_id(EventType::TimerStarted, None);
|
|
879
|
+
t.add_timer_fired(timer_started_event_id, "1".to_string());
|
|
880
|
+
t.add_workflow_task_scheduled_and_started();
|
|
881
|
+
|
|
882
|
+
let wf_id = "fakeid";
|
|
883
|
+
let mock = mock_workflow_client();
|
|
884
|
+
let mh = MockPollCfg::from_resp_batches(wf_id, t, [ResponseType::AllHistory], mock);
|
|
885
|
+
let mut worker = mock_sdk_cfg(mh, |w| w.max_cached_workflows = 1);
|
|
886
|
+
|
|
887
|
+
worker.register_wf(
|
|
888
|
+
DEFAULT_WORKFLOW_TYPE.to_owned(),
|
|
889
|
+
|ctx: WfContext| async move {
|
|
890
|
+
let la_res = ctx
|
|
891
|
+
.local_activity(LocalActivityOptions {
|
|
892
|
+
activity_type: "echo".to_string(),
|
|
893
|
+
input: "hi".as_json_payload().expect("serializes fine"),
|
|
894
|
+
retry_policy: RetryPolicy {
|
|
895
|
+
initial_interval: Some(prost_dur!(from_millis(50))),
|
|
896
|
+
backoff_coefficient: 1.2,
|
|
897
|
+
maximum_interval: None,
|
|
898
|
+
maximum_attempts: 5,
|
|
899
|
+
non_retryable_error_types: vec![],
|
|
900
|
+
},
|
|
901
|
+
// This 10 minute timeout will have already elapsed according to the original
|
|
902
|
+
// schedule time in the history.
|
|
903
|
+
schedule_to_close_timeout: Some(Duration::from_secs(10 * 60)),
|
|
904
|
+
..Default::default()
|
|
905
|
+
})
|
|
906
|
+
.await;
|
|
907
|
+
assert_eq!(la_res.timed_out(), Some(TimeoutType::ScheduleToClose));
|
|
908
|
+
Ok(().into())
|
|
909
|
+
},
|
|
910
|
+
);
|
|
911
|
+
worker.register_activity(
|
|
912
|
+
"echo",
|
|
913
|
+
move |_ctx: ActContext, _: String| async move { Ok(()) },
|
|
914
|
+
);
|
|
915
|
+
worker
|
|
916
|
+
.submit_wf(
|
|
917
|
+
wf_id.to_owned(),
|
|
918
|
+
DEFAULT_WORKFLOW_TYPE.to_owned(),
|
|
919
|
+
vec![],
|
|
920
|
+
WorkflowOptions::default(),
|
|
921
|
+
)
|
|
922
|
+
.await
|
|
923
|
+
.unwrap();
|
|
924
|
+
worker.run_until_done().await.unwrap();
|
|
925
|
+
}
|