@temporalio/core-bridge 1.8.5 → 1.9.0-rc.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 +189 -152
- package/Cargo.toml +1 -0
- package/lib/index.d.ts +17 -44
- package/lib/index.js.map +1 -1
- package/package.json +3 -4
- 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/.github/workflows/heavy.yml +4 -0
- package/sdk-core/.github/workflows/per-pr.yml +96 -0
- package/sdk-core/ARCHITECTURE.md +1 -1
- package/sdk-core/Cargo.toml +6 -0
- package/sdk-core/README.md +37 -21
- package/sdk-core/client/Cargo.toml +6 -3
- package/sdk-core/client/src/lib.rs +272 -138
- package/sdk-core/client/src/metrics.rs +68 -57
- package/sdk-core/client/src/raw.rs +191 -45
- package/sdk-core/client/src/retry.rs +20 -0
- package/sdk-core/client/src/worker_registry/mod.rs +264 -0
- package/sdk-core/client/src/workflow_handle/mod.rs +2 -1
- package/sdk-core/core/Cargo.toml +16 -18
- package/sdk-core/core/src/core_tests/child_workflows.rs +7 -7
- package/sdk-core/core/src/core_tests/mod.rs +1 -0
- package/sdk-core/core/src/core_tests/replay_flag.rs +29 -39
- package/sdk-core/core/src/core_tests/updates.rs +73 -0
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +52 -1
- package/sdk-core/core/src/ephemeral_server/mod.rs +34 -11
- package/sdk-core/core/src/internal_flags.rs +7 -1
- package/sdk-core/core/src/lib.rs +19 -36
- package/sdk-core/core/src/protosext/mod.rs +11 -3
- package/sdk-core/core/src/protosext/protocol_messages.rs +102 -0
- package/sdk-core/core/src/replay/mod.rs +100 -48
- package/sdk-core/core/src/telemetry/log_export.rs +161 -28
- package/sdk-core/core/src/telemetry/metrics.rs +869 -248
- package/sdk-core/core/src/telemetry/mod.rs +135 -239
- package/sdk-core/core/src/telemetry/prometheus_server.rs +36 -31
- package/sdk-core/core/src/test_help/mod.rs +63 -4
- package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +12 -2
- package/sdk-core/core/src/worker/activities.rs +276 -10
- package/sdk-core/core/src/worker/client/mocks.rs +18 -0
- package/sdk-core/core/src/worker/client.rs +16 -3
- package/sdk-core/core/src/worker/mod.rs +50 -19
- package/sdk-core/core/src/worker/slot_provider.rs +175 -0
- package/sdk-core/core/src/worker/workflow/driven_workflow.rs +27 -34
- package/sdk-core/core/src/worker/workflow/history_update.rs +4 -1
- package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +36 -94
- package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +34 -22
- package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +50 -34
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +106 -92
- package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +22 -21
- package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +386 -499
- package/sdk-core/core/src/worker/workflow/machines/mod.rs +12 -2
- package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +33 -26
- package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +198 -215
- package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +66 -62
- package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +88 -119
- package/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +3 -1
- package/sdk-core/core/src/worker/workflow/machines/update_state_machine.rs +411 -0
- package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +26 -25
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +302 -85
- package/sdk-core/core/src/worker/workflow/managed_run.rs +179 -132
- package/sdk-core/core/src/worker/workflow/mod.rs +121 -46
- package/sdk-core/core/src/worker/workflow/run_cache.rs +8 -12
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +45 -38
- package/sdk-core/core-api/Cargo.toml +7 -6
- package/sdk-core/core-api/src/lib.rs +4 -12
- package/sdk-core/core-api/src/telemetry/metrics.rs +334 -0
- package/sdk-core/core-api/src/telemetry.rs +53 -42
- package/sdk-core/core-api/src/worker.rs +7 -0
- package/sdk-core/{.buildkite/docker → docker}/docker-compose.yaml +1 -1
- package/sdk-core/etc/dynamic-config.yaml +11 -1
- package/sdk-core/fsm/rustfsm_procmacro/Cargo.toml +1 -1
- package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +1 -3
- package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +2 -2
- package/sdk-core/sdk/Cargo.toml +1 -1
- package/sdk-core/sdk/src/lib.rs +85 -7
- package/sdk-core/sdk/src/workflow_context/options.rs +4 -0
- package/sdk-core/sdk/src/workflow_context.rs +43 -15
- package/sdk-core/sdk/src/workflow_future.rs +334 -204
- package/sdk-core/sdk-core-protos/Cargo.toml +2 -2
- package/sdk-core/sdk-core-protos/build.rs +14 -14
- package/sdk-core/sdk-core-protos/protos/api_upstream/.buildkite/Dockerfile +2 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/Makefile +99 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/api-linter.yaml +56 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/buf.gen.yaml +20 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/buf.lock +11 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/buf.yaml +18 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/google/api/annotations.proto +31 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/google/api/http.proto +379 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/google/protobuf/any.proto +162 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/google/protobuf/descriptor.proto +1212 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/google/protobuf/duration.proto +115 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/google/protobuf/empty.proto +51 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/google/protobuf/timestamp.proto +144 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/google/protobuf/wrappers.proto +123 -0
- package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/batch/v1/message.proto +3 -5
- package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/command/v1/message.proto +11 -13
- package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/common/v1/message.proto +2 -4
- package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/failed_cause.proto +2 -0
- package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/reset.proto +1 -1
- package/sdk-core/{protos/api_upstream/build/tools.go → sdk-core-protos/protos/api_upstream/temporal/api/export/v1/message.proto} +22 -6
- package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/filter/v1/message.proto +2 -4
- package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/history/v1/message.proto +21 -23
- package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/namespace/v1/message.proto +2 -4
- package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/operatorservice/v1/request_response.proto +2 -0
- package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/operatorservice/v1/service.proto +4 -0
- package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/replication/v1/message.proto +1 -3
- package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/schedule/v1/message.proto +36 -20
- package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/sdk/v1/task_complete_metadata.proto +13 -0
- package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/taskqueue/v1/message.proto +2 -4
- package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/update/v1/message.proto +1 -1
- package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/version/v1/message.proto +2 -3
- package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/workflow/v1/message.proto +18 -20
- package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/workflowservice/v1/request_response.proto +84 -32
- package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/workflowservice/v1/service.proto +205 -47
- package/sdk-core/{protos → sdk-core-protos/protos}/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +57 -0
- package/sdk-core/{protos → sdk-core-protos/protos}/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +27 -0
- package/sdk-core/sdk-core-protos/src/history_builder.rs +67 -2
- package/sdk-core/sdk-core-protos/src/lib.rs +75 -2
- package/sdk-core/sdk-core-protos/src/utilities.rs +14 -0
- package/sdk-core/test-utils/Cargo.toml +5 -1
- package/sdk-core/test-utils/src/canned_histories.rs +3 -57
- package/sdk-core/test-utils/src/interceptors.rs +46 -0
- package/sdk-core/test-utils/src/lib.rs +106 -38
- package/sdk-core/tests/integ_tests/metrics_tests.rs +110 -15
- package/sdk-core/tests/integ_tests/queries_tests.rs +174 -3
- package/sdk-core/tests/integ_tests/update_tests.rs +908 -0
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +44 -1
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +4 -4
- package/sdk-core/tests/integ_tests/workflow_tests/eager.rs +61 -0
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +27 -2
- package/sdk-core/tests/integ_tests/workflow_tests.rs +1 -0
- package/sdk-core/tests/main.rs +2 -1
- package/sdk-core/tests/runner.rs +15 -2
- package/src/conversions.rs +75 -89
- package/src/helpers.rs +74 -0
- package/src/runtime.rs +17 -6
- package/src/worker.rs +14 -61
- package/ts/index.ts +21 -52
- package/sdk-core/.buildkite/docker/Dockerfile +0 -9
- package/sdk-core/.buildkite/docker/build.sh +0 -5
- package/sdk-core/.buildkite/docker/docker-compose-ci.yaml +0 -27
- package/sdk-core/.buildkite/pipeline.yml +0 -57
- package/sdk-core/.github/workflows/semgrep.yml +0 -25
- package/sdk-core/core/src/worker/workflow/bridge.rs +0 -35
- package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +0 -215
- package/sdk-core/protos/api_upstream/.buildkite/Dockerfile +0 -2
- package/sdk-core/protos/api_upstream/Makefile +0 -80
- package/sdk-core/protos/api_upstream/api-linter.yaml +0 -40
- package/sdk-core/protos/api_upstream/buf.yaml +0 -9
- package/sdk-core/protos/api_upstream/build/go.mod +0 -7
- package/sdk-core/protos/api_upstream/build/go.sum +0 -5
- package/sdk-core/protos/api_upstream/go.mod +0 -6
- package/sdk-core/protos/testsrv_upstream/dependencies/gogoproto/gogo.proto +0 -141
- /package/sdk-core/{.buildkite/docker → docker}/docker-compose-telem.yaml +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/.buildkite/docker-compose.yml +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/.buildkite/pipeline.yml +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/.github/CODEOWNERS +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/.github/workflows/publish-docs.yml +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/.github/workflows/trigger-api-go-update.yml +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/LICENSE +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/README.md +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/batch_operation.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/command_type.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/common.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/event_type.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/namespace.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/query.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/schedule.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/task_queue.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/update.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/workflow.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/errordetails/v1/message.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/failure/v1/message.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/protocol/v1/message.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/query/v1/message.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/google/rpc/status.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/grpc/health/v1/health.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/local/temporal/sdk/core/activity_result/activity_result.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/local/temporal/sdk/core/activity_task/activity_task.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/local/temporal/sdk/core/child_workflow/child_workflow.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/local/temporal/sdk/core/common/common.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/local/temporal/sdk/core/core_interface.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/local/temporal/sdk/core/external_data/external_data.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/testsrv_upstream/Makefile +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/testsrv_upstream/api-linter.yaml +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/testsrv_upstream/buf.yaml +0 -0
- /package/sdk-core/{protos/api_upstream → sdk-core-protos/protos/testsrv_upstream}/dependencies/gogoproto/gogo.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +0 -0
- /package/sdk-core/{protos → sdk-core-protos/protos}/testsrv_upstream/temporal/api/testservice/v1/service.proto +0 -0
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
//! lion's share of the complexity in Core). See the `ARCHITECTURE.md` file in the repo root for
|
|
3
3
|
//! a diagram of the internals.
|
|
4
4
|
|
|
5
|
-
mod bridge;
|
|
6
5
|
mod driven_workflow;
|
|
7
6
|
mod history_update;
|
|
8
7
|
mod machines;
|
|
@@ -15,11 +14,8 @@ mod workflow_stream;
|
|
|
15
14
|
#[cfg(feature = "save_wf_inputs")]
|
|
16
15
|
pub use workflow_stream::replay_wf_state_inputs;
|
|
17
16
|
|
|
18
|
-
pub(crate) use
|
|
19
|
-
pub(crate) use driven_workflow::{DrivenWorkflow, WorkflowFetcher};
|
|
17
|
+
pub(crate) use driven_workflow::DrivenWorkflow;
|
|
20
18
|
pub(crate) use history_update::HistoryUpdate;
|
|
21
|
-
#[cfg(test)]
|
|
22
|
-
pub(crate) use managed_run::ManagedWFFunc;
|
|
23
19
|
|
|
24
20
|
use crate::{
|
|
25
21
|
abstractions::{
|
|
@@ -27,7 +23,7 @@ use crate::{
|
|
|
27
23
|
UsedMeteredSemPermit,
|
|
28
24
|
},
|
|
29
25
|
internal_flags::InternalFlags,
|
|
30
|
-
protosext::legacy_query_failure,
|
|
26
|
+
protosext::{legacy_query_failure, protocol_messages::IncomingProtocolMessage},
|
|
31
27
|
telemetry::{set_trace_subscriber_for_current_thread, TelemetryInstance, VecDisplayer},
|
|
32
28
|
worker::{
|
|
33
29
|
activities::{ActivitiesFromWFTsHandle, LocalActivityManager, TrackedPermittedTqResp},
|
|
@@ -79,6 +75,7 @@ use temporal_sdk_core_protos::{
|
|
|
79
75
|
command::v1::{command::Attributes, Command as ProtoCommand, Command},
|
|
80
76
|
common::v1::{Memo, MeteringMetadata, RetryPolicy, SearchAttributes, WorkflowExecution},
|
|
81
77
|
enums::v1::WorkflowTaskFailedCause,
|
|
78
|
+
protocol::v1::Message as ProtocolMessage,
|
|
82
79
|
query::v1::WorkflowQuery,
|
|
83
80
|
sdk::v1::WorkflowTaskCompletedMetadata,
|
|
84
81
|
taskqueue::v1::StickyExecutionAttributes,
|
|
@@ -185,7 +182,7 @@ impl Workflows {
|
|
|
185
182
|
let (start_polling_tx, start_polling_rx) = oneshot::channel();
|
|
186
183
|
// We must spawn a task to constantly poll the activation stream, because otherwise
|
|
187
184
|
// activation completions would not cause anything to happen until the next poll.
|
|
188
|
-
let tracing_sub = telem_instance.
|
|
185
|
+
let tracing_sub = telem_instance.and_then(|ti| ti.trace_subscriber());
|
|
189
186
|
let processing_task = thread::spawn(move || {
|
|
190
187
|
if let Some(ts) = tracing_sub {
|
|
191
188
|
set_trace_subscriber_for_current_thread(ts);
|
|
@@ -266,7 +263,6 @@ impl Workflows {
|
|
|
266
263
|
}
|
|
267
264
|
stream.next().await.unwrap_or(Err(PollWfError::ShutDown))?
|
|
268
265
|
};
|
|
269
|
-
Span::current().record("run_id", al.run_id());
|
|
270
266
|
match al {
|
|
271
267
|
ActivationOrAuto::LangActivation(mut act)
|
|
272
268
|
| ActivationOrAuto::ReadyForQueries(mut act) => {
|
|
@@ -318,7 +314,7 @@ impl Workflows {
|
|
|
318
314
|
post_activate_hook: Option<impl Fn(PostActivateHookData)>,
|
|
319
315
|
) -> Result<(), CompleteWfError> {
|
|
320
316
|
let is_empty_completion = completion.is_empty();
|
|
321
|
-
let completion = validate_completion(completion)?;
|
|
317
|
+
let completion = validate_completion(completion, is_autocomplete)?;
|
|
322
318
|
let run_id = completion.run_id().to_string();
|
|
323
319
|
let (tx, rx) = oneshot::channel();
|
|
324
320
|
let was_sent = self.send_local(WFActCompleteMsg {
|
|
@@ -356,6 +352,7 @@ impl Workflows {
|
|
|
356
352
|
action:
|
|
357
353
|
ActivationAction::WftComplete {
|
|
358
354
|
mut commands,
|
|
355
|
+
messages,
|
|
359
356
|
query_responses,
|
|
360
357
|
force_new_wft,
|
|
361
358
|
sdk_metadata,
|
|
@@ -364,10 +361,12 @@ impl Workflows {
|
|
|
364
361
|
let reserved_act_permits =
|
|
365
362
|
self.reserve_activity_slots_for_outgoing_commands(commands.as_mut_slice());
|
|
366
363
|
debug!(commands=%commands.display(), query_responses=%query_responses.display(),
|
|
367
|
-
force_new_wft,
|
|
364
|
+
messages=%messages.display(), force_new_wft,
|
|
365
|
+
"Sending responses to server");
|
|
368
366
|
let mut completion = WorkflowTaskCompletion {
|
|
369
367
|
task_token,
|
|
370
368
|
commands,
|
|
369
|
+
messages,
|
|
371
370
|
query_responses,
|
|
372
371
|
sticky_attributes: None,
|
|
373
372
|
return_new_workflow_task: true,
|
|
@@ -388,26 +387,31 @@ impl Workflows {
|
|
|
388
387
|
}
|
|
389
388
|
completion.sticky_attributes = sticky_attrs;
|
|
390
389
|
|
|
390
|
+
let mut reset_last_started_to = None;
|
|
391
391
|
self.handle_wft_reporting_errs(&run_id, || async {
|
|
392
|
-
let
|
|
393
|
-
if
|
|
392
|
+
let response = self.client.complete_workflow_task(completion).await?;
|
|
393
|
+
if response.reset_history_event_id > 0 {
|
|
394
|
+
reset_last_started_to = Some(response.reset_history_event_id);
|
|
395
|
+
}
|
|
396
|
+
if let Some(wft) = response.workflow_task {
|
|
394
397
|
wft_from_complete = Some(validate_wft(wft)?);
|
|
395
398
|
}
|
|
396
|
-
self.handle_eager_activities(
|
|
397
|
-
reserved_act_permits,
|
|
398
|
-
maybe_wft.activity_tasks,
|
|
399
|
-
);
|
|
399
|
+
self.handle_eager_activities(reserved_act_permits, response.activity_tasks);
|
|
400
400
|
Ok(())
|
|
401
401
|
})
|
|
402
402
|
.await;
|
|
403
|
-
WFTReportStatus::Reported
|
|
403
|
+
WFTReportStatus::Reported {
|
|
404
|
+
reset_last_started_to,
|
|
405
|
+
}
|
|
404
406
|
}
|
|
405
407
|
ServerCommandsWithWorkflowInfo {
|
|
406
408
|
task_token,
|
|
407
409
|
action: ActivationAction::RespondLegacyQuery { result },
|
|
408
410
|
} => {
|
|
409
411
|
self.respond_legacy_query(task_token, *result).await;
|
|
410
|
-
WFTReportStatus::Reported
|
|
412
|
+
WFTReportStatus::Reported {
|
|
413
|
+
reset_last_started_to: None,
|
|
414
|
+
}
|
|
411
415
|
}
|
|
412
416
|
},
|
|
413
417
|
ActivationCompleteOutcome::ReportWFTFail(outcome) => match outcome {
|
|
@@ -419,13 +423,17 @@ impl Workflows {
|
|
|
419
423
|
.await
|
|
420
424
|
})
|
|
421
425
|
.await;
|
|
422
|
-
WFTReportStatus::Reported
|
|
426
|
+
WFTReportStatus::Reported {
|
|
427
|
+
reset_last_started_to: None,
|
|
428
|
+
}
|
|
423
429
|
}
|
|
424
430
|
FailedActivationWFTReport::ReportLegacyQueryFailure(task_token, failure) => {
|
|
425
431
|
warn!(run_id=%run_id, failure=?failure, "Failing legacy query request");
|
|
426
432
|
self.respond_legacy_query(task_token, legacy_query_failure(failure))
|
|
427
433
|
.await;
|
|
428
|
-
WFTReportStatus::Reported
|
|
434
|
+
WFTReportStatus::Reported {
|
|
435
|
+
reset_last_started_to: None,
|
|
436
|
+
}
|
|
429
437
|
}
|
|
430
438
|
},
|
|
431
439
|
ActivationCompleteOutcome::WFTFailedDontReport => WFTReportStatus::DropWft,
|
|
@@ -434,7 +442,7 @@ impl Workflows {
|
|
|
434
442
|
|
|
435
443
|
let maybe_pwft = if let Some(wft) = wft_from_complete {
|
|
436
444
|
match HistoryPaginator::from_poll(wft, self.client.clone()).await {
|
|
437
|
-
Ok((paginator,
|
|
445
|
+
Ok((paginator, wft)) => Some(WFTWithPaginator { wft, paginator }),
|
|
438
446
|
Err(e) => {
|
|
439
447
|
self.request_eviction(
|
|
440
448
|
&run_id,
|
|
@@ -623,7 +631,7 @@ impl Workflows {
|
|
|
623
631
|
}
|
|
624
632
|
let with_permits = reserved_act_permits
|
|
625
633
|
.into_iter()
|
|
626
|
-
.zip(eager_acts
|
|
634
|
+
.zip(eager_acts)
|
|
627
635
|
.map(|(permit, resp)| TrackedPermittedTqResp { permit, resp });
|
|
628
636
|
if with_permits.len() > 0 {
|
|
629
637
|
debug!(
|
|
@@ -740,18 +748,9 @@ enum ActivationOrAuto {
|
|
|
740
748
|
machines_err: WFMachinesError,
|
|
741
749
|
},
|
|
742
750
|
}
|
|
743
|
-
impl ActivationOrAuto {
|
|
744
|
-
pub fn run_id(&self) -> &str {
|
|
745
|
-
match self {
|
|
746
|
-
ActivationOrAuto::LangActivation(act) => &act.run_id,
|
|
747
|
-
ActivationOrAuto::Autocomplete { run_id, .. } => run_id,
|
|
748
|
-
ActivationOrAuto::ReadyForQueries(act) => &act.run_id,
|
|
749
|
-
ActivationOrAuto::AutoFail { run_id, .. } => run_id,
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
751
|
|
|
754
|
-
/// A
|
|
752
|
+
/// A WFT which is considered to be using a slot for metrics purposes and being or about to be
|
|
753
|
+
/// applied to workflow state.
|
|
755
754
|
#[derive(derive_more::DebugCustom)]
|
|
756
755
|
#[cfg_attr(
|
|
757
756
|
feature = "save_wf_inputs",
|
|
@@ -771,6 +770,18 @@ pub(crate) struct PermittedWFT {
|
|
|
771
770
|
)]
|
|
772
771
|
paginator: HistoryPaginator,
|
|
773
772
|
}
|
|
773
|
+
/// A WFT without a permit
|
|
774
|
+
#[derive(Debug)]
|
|
775
|
+
#[cfg_attr(
|
|
776
|
+
feature = "save_wf_inputs",
|
|
777
|
+
derive(serde::Serialize, serde::Deserialize)
|
|
778
|
+
)]
|
|
779
|
+
struct WFTWithPaginator {
|
|
780
|
+
wft: PreparedWFT,
|
|
781
|
+
paginator: HistoryPaginator,
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
/// A WFT which has been validated and had a history update extracted from it.
|
|
774
785
|
#[derive(Debug)]
|
|
775
786
|
#[cfg_attr(
|
|
776
787
|
feature = "save_wf_inputs",
|
|
@@ -784,6 +795,7 @@ struct PreparedWFT {
|
|
|
784
795
|
legacy_query: Option<WorkflowQuery>,
|
|
785
796
|
query_requests: Vec<QueryWorkflow>,
|
|
786
797
|
update: HistoryUpdate,
|
|
798
|
+
messages: Vec<IncomingProtocolMessage>,
|
|
787
799
|
}
|
|
788
800
|
impl PreparedWFT {
|
|
789
801
|
/// Returns true if the contained history update is incremental (IE: expects to hit a cached
|
|
@@ -793,6 +805,11 @@ impl PreparedWFT {
|
|
|
793
805
|
let poll_resp_is_incremental = start_event_id.map(|eid| eid > 1).unwrap_or_default();
|
|
794
806
|
poll_resp_is_incremental || start_event_id.is_none()
|
|
795
807
|
}
|
|
808
|
+
|
|
809
|
+
fn is_query_only(&self) -> bool {
|
|
810
|
+
let no_new_history = self.update.wft_started_id == 0;
|
|
811
|
+
no_new_history && self.legacy_query.is_some()
|
|
812
|
+
}
|
|
796
813
|
}
|
|
797
814
|
|
|
798
815
|
#[derive(Debug)]
|
|
@@ -880,6 +897,7 @@ pub(crate) enum ActivationAction {
|
|
|
880
897
|
/// We should respond that the workflow task is complete
|
|
881
898
|
WftComplete {
|
|
882
899
|
commands: Vec<ProtoCommand>,
|
|
900
|
+
messages: Vec<ProtocolMessage>,
|
|
883
901
|
query_responses: Vec<QueryResult>,
|
|
884
902
|
force_new_wft: bool,
|
|
885
903
|
sdk_metadata: WorkflowTaskCompletedMetadata,
|
|
@@ -938,7 +956,7 @@ struct LocalResolutionMsg {
|
|
|
938
956
|
struct PostActivationMsg {
|
|
939
957
|
run_id: String,
|
|
940
958
|
wft_report_status: WFTReportStatus,
|
|
941
|
-
wft_from_complete: Option<
|
|
959
|
+
wft_from_complete: Option<WFTWithPaginator>,
|
|
942
960
|
is_autocomplete: bool,
|
|
943
961
|
}
|
|
944
962
|
#[derive(Debug, Clone)]
|
|
@@ -993,7 +1011,9 @@ enum ActivationCompleteOutcome {
|
|
|
993
1011
|
derive(serde::Serialize, serde::Deserialize)
|
|
994
1012
|
)]
|
|
995
1013
|
enum WFTReportStatus {
|
|
996
|
-
Reported
|
|
1014
|
+
Reported {
|
|
1015
|
+
reset_last_started_to: Option<i64>,
|
|
1016
|
+
},
|
|
997
1017
|
/// The WFT completion was not reported when finishing the activation, because there's still
|
|
998
1018
|
/// work to be done. EX: Running LAs.
|
|
999
1019
|
NotReported,
|
|
@@ -1001,9 +1021,43 @@ enum WFTReportStatus {
|
|
|
1001
1021
|
/// [ActivationCompleteOutcome::WFTFailedDontReport]
|
|
1002
1022
|
DropWft,
|
|
1003
1023
|
}
|
|
1024
|
+
#[derive(Debug, Default)]
|
|
1025
|
+
struct BufferedTasks {
|
|
1026
|
+
/// There should only be one buffered actual WFT at a time, since any new one will immediately
|
|
1027
|
+
/// supersede any old one.
|
|
1028
|
+
wft: Option<PermittedWFT>,
|
|
1029
|
+
/// For query only tasks, multiple may be received concurrently and it's OK to buffer more
|
|
1030
|
+
/// than one - however they should be dropped if, by the time we try to process them, we
|
|
1031
|
+
/// have already processed a newer real WFT than the one the query was targeting (otherwise
|
|
1032
|
+
/// we'd return data from the "future").
|
|
1033
|
+
query_only_tasks: VecDeque<PermittedWFT>,
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
impl BufferedTasks {
|
|
1037
|
+
fn buffer(&mut self, task: PermittedWFT) {
|
|
1038
|
+
if task.work.is_query_only() {
|
|
1039
|
+
self.query_only_tasks.push_back(task);
|
|
1040
|
+
} else {
|
|
1041
|
+
let _ = self.wft.insert(task);
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
fn has_tasks(&self) -> bool {
|
|
1046
|
+
self.wft.is_some() || !self.query_only_tasks.is_empty()
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
/// Remove and return the next WFT from the buffer that should be applied. WFTs which would
|
|
1050
|
+
/// advance workflow state are returned before query-only tasks.
|
|
1051
|
+
fn get_next_wft(&mut self) -> Option<PermittedWFT> {
|
|
1052
|
+
self.wft
|
|
1053
|
+
.take()
|
|
1054
|
+
.or_else(|| self.query_only_tasks.pop_front())
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1004
1057
|
|
|
1005
1058
|
fn validate_completion(
|
|
1006
1059
|
completion: WorkflowActivationCompletion,
|
|
1060
|
+
is_autocomplete: bool,
|
|
1007
1061
|
) -> Result<ValidatedCompletion, CompleteWfError> {
|
|
1008
1062
|
match completion.status {
|
|
1009
1063
|
Some(workflow_activation_completion::Status::Successful(success)) => {
|
|
@@ -1015,7 +1069,7 @@ fn validate_completion(
|
|
|
1015
1069
|
.collect::<Result<Vec<_>, EmptyWorkflowCommandErr>>()
|
|
1016
1070
|
.map_err(|_| CompleteWfError::MalformedWorkflowCompletion {
|
|
1017
1071
|
reason: "At least one workflow command in the completion contained \
|
|
1018
|
-
|
|
1072
|
+
an empty variant"
|
|
1019
1073
|
.to_owned(),
|
|
1020
1074
|
run_id: completion.run_id.clone(),
|
|
1021
1075
|
})?;
|
|
@@ -1055,6 +1109,7 @@ fn validate_completion(
|
|
|
1055
1109
|
Ok(ValidatedCompletion::Fail {
|
|
1056
1110
|
run_id: completion.run_id,
|
|
1057
1111
|
failure,
|
|
1112
|
+
is_autocomplete,
|
|
1058
1113
|
})
|
|
1059
1114
|
}
|
|
1060
1115
|
None => Err(CompleteWfError::MalformedWorkflowCompletion {
|
|
@@ -1079,6 +1134,7 @@ enum ValidatedCompletion {
|
|
|
1079
1134
|
Fail {
|
|
1080
1135
|
run_id: String,
|
|
1081
1136
|
failure: Failure,
|
|
1137
|
+
is_autocomplete: bool,
|
|
1082
1138
|
},
|
|
1083
1139
|
}
|
|
1084
1140
|
|
|
@@ -1091,12 +1147,6 @@ impl ValidatedCompletion {
|
|
|
1091
1147
|
}
|
|
1092
1148
|
}
|
|
1093
1149
|
|
|
1094
|
-
#[derive(Debug)]
|
|
1095
|
-
pub struct OutgoingServerCommands {
|
|
1096
|
-
pub commands: Vec<ProtoCommand>,
|
|
1097
|
-
pub replaying: bool,
|
|
1098
|
-
}
|
|
1099
|
-
|
|
1100
1150
|
#[derive(Debug)]
|
|
1101
1151
|
#[cfg_attr(
|
|
1102
1152
|
feature = "save_wf_inputs",
|
|
@@ -1149,6 +1199,7 @@ pub enum WFCommand {
|
|
|
1149
1199
|
CancelSignalWorkflow(CancelSignalWorkflow),
|
|
1150
1200
|
UpsertSearchAttributes(UpsertWorkflowSearchAttributes),
|
|
1151
1201
|
ModifyWorkflowProperties(ModifyWorkflowProperties),
|
|
1202
|
+
UpdateResponse(UpdateResponse),
|
|
1152
1203
|
}
|
|
1153
1204
|
|
|
1154
1205
|
impl TryFrom<WorkflowCommand> for WFCommand {
|
|
@@ -1193,6 +1244,7 @@ impl TryFrom<WorkflowCommand> for WFCommand {
|
|
|
1193
1244
|
workflow_command::Variant::ModifyWorkflowProperties(s) => {
|
|
1194
1245
|
Ok(Self::ModifyWorkflowProperties(s))
|
|
1195
1246
|
}
|
|
1247
|
+
workflow_command::Variant::UpdateResponse(s) => Ok(Self::UpdateResponse(s)),
|
|
1196
1248
|
}
|
|
1197
1249
|
}
|
|
1198
1250
|
}
|
|
@@ -1340,7 +1392,7 @@ impl LocalActivityRequestSink for LAReqSink {
|
|
|
1340
1392
|
/// activations must uphold.
|
|
1341
1393
|
///
|
|
1342
1394
|
/// ## Ordering
|
|
1343
|
-
/// `patches -> signals -> other
|
|
1395
|
+
/// `patches -> signals/updates -> other -> queries -> evictions`
|
|
1344
1396
|
///
|
|
1345
1397
|
/// ## Invariants:
|
|
1346
1398
|
/// * Queries always go in their own activation
|
|
@@ -1374,10 +1426,14 @@ fn prepare_to_ship_activation(wfa: &mut WorkflowActivation) {
|
|
|
1374
1426
|
match v {
|
|
1375
1427
|
workflow_activation_job::Variant::NotifyHasPatch(_) => 1,
|
|
1376
1428
|
workflow_activation_job::Variant::SignalWorkflow(_) => 2,
|
|
1429
|
+
workflow_activation_job::Variant::DoUpdate(_) => 2,
|
|
1377
1430
|
// In principle we should never actually need to sort these with the others, since
|
|
1378
1431
|
// queries always get their own activation, but, maintaining the semantic is
|
|
1379
1432
|
// reasonable.
|
|
1380
1433
|
workflow_activation_job::Variant::QueryWorkflow(_) => 4,
|
|
1434
|
+
// Also shouldn't ever end up anywhere but the end by construction, but no harm in
|
|
1435
|
+
// double-checking.
|
|
1436
|
+
workflow_activation_job::Variant::RemoveFromCache(_) => 5,
|
|
1381
1437
|
_ => 3,
|
|
1382
1438
|
}
|
|
1383
1439
|
}
|
|
@@ -1389,6 +1445,7 @@ fn prepare_to_ship_activation(wfa: &mut WorkflowActivation) {
|
|
|
1389
1445
|
mod tests {
|
|
1390
1446
|
use super::*;
|
|
1391
1447
|
use itertools::Itertools;
|
|
1448
|
+
use temporal_sdk_core_protos::coresdk::workflow_activation::SignalWorkflow;
|
|
1392
1449
|
|
|
1393
1450
|
#[test]
|
|
1394
1451
|
fn jobs_sort() {
|
|
@@ -1396,7 +1453,10 @@ mod tests {
|
|
|
1396
1453
|
jobs: vec![
|
|
1397
1454
|
WorkflowActivationJob {
|
|
1398
1455
|
variant: Some(workflow_activation_job::Variant::SignalWorkflow(
|
|
1399
|
-
|
|
1456
|
+
SignalWorkflow {
|
|
1457
|
+
signal_name: "1".to_string(),
|
|
1458
|
+
..Default::default()
|
|
1459
|
+
},
|
|
1400
1460
|
)),
|
|
1401
1461
|
},
|
|
1402
1462
|
WorkflowActivationJob {
|
|
@@ -1414,6 +1474,19 @@ mod tests {
|
|
|
1414
1474
|
Default::default(),
|
|
1415
1475
|
)),
|
|
1416
1476
|
},
|
|
1477
|
+
WorkflowActivationJob {
|
|
1478
|
+
variant: Some(workflow_activation_job::Variant::DoUpdate(
|
|
1479
|
+
Default::default(),
|
|
1480
|
+
)),
|
|
1481
|
+
},
|
|
1482
|
+
WorkflowActivationJob {
|
|
1483
|
+
variant: Some(workflow_activation_job::Variant::SignalWorkflow(
|
|
1484
|
+
SignalWorkflow {
|
|
1485
|
+
signal_name: "2".to_string(),
|
|
1486
|
+
..Default::default()
|
|
1487
|
+
},
|
|
1488
|
+
)),
|
|
1489
|
+
},
|
|
1417
1490
|
],
|
|
1418
1491
|
..Default::default()
|
|
1419
1492
|
};
|
|
@@ -1427,10 +1500,12 @@ mod tests {
|
|
|
1427
1500
|
variants.as_slice(),
|
|
1428
1501
|
&[
|
|
1429
1502
|
workflow_activation_job::Variant::NotifyHasPatch(_),
|
|
1430
|
-
workflow_activation_job::Variant::SignalWorkflow(
|
|
1503
|
+
workflow_activation_job::Variant::SignalWorkflow(ref s1),
|
|
1504
|
+
workflow_activation_job::Variant::DoUpdate(_),
|
|
1505
|
+
workflow_activation_job::Variant::SignalWorkflow(ref s2),
|
|
1431
1506
|
workflow_activation_job::Variant::FireTimer(_),
|
|
1432
1507
|
workflow_activation_job::Variant::ResolveActivity(_),
|
|
1433
|
-
]
|
|
1508
|
+
] if s1.signal_name == "1" && s2.signal_name == "2"
|
|
1434
1509
|
)
|
|
1435
1510
|
}
|
|
1436
1511
|
|
|
@@ -7,7 +7,7 @@ use crate::{
|
|
|
7
7
|
MetricsContext,
|
|
8
8
|
};
|
|
9
9
|
use lru::LruCache;
|
|
10
|
-
use std::{
|
|
10
|
+
use std::{num::NonZeroUsize, rc::Rc};
|
|
11
11
|
use temporal_sdk_core_protos::temporal::api::workflowservice::v1::get_system_info_response;
|
|
12
12
|
|
|
13
13
|
pub(super) struct RunCache {
|
|
@@ -51,11 +51,11 @@ impl RunCache {
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
pub fn instantiate_or_update(&mut self,
|
|
54
|
+
pub fn instantiate_or_update(&mut self, pwft: PermittedWFT) -> RunUpdateAct {
|
|
55
55
|
let cur_num_cached_runs = self.runs.len();
|
|
56
|
-
let run_id =
|
|
56
|
+
let run_id = pwft.work.execution.run_id.clone();
|
|
57
57
|
|
|
58
|
-
if let Some(run_handle) = self.runs.get_mut(run_id) {
|
|
58
|
+
if let Some(run_handle) = self.runs.get_mut(&run_id) {
|
|
59
59
|
let rur = run_handle.incoming_wft(pwft);
|
|
60
60
|
self.metrics.cache_size(cur_num_cached_runs as u64);
|
|
61
61
|
return rur;
|
|
@@ -66,24 +66,20 @@ impl RunCache {
|
|
|
66
66
|
let metrics = self
|
|
67
67
|
.metrics
|
|
68
68
|
.with_new_attrs([workflow_type(pwft.work.workflow_type.clone())]);
|
|
69
|
-
|
|
70
|
-
// with the update.
|
|
71
|
-
let history_update = mem::replace(&mut pwft.work.update, HistoryUpdate::dummy());
|
|
72
|
-
let mut mrh = ManagedRun::new(
|
|
69
|
+
let (mrh, rur) = ManagedRun::new(
|
|
73
70
|
RunBasics {
|
|
74
71
|
namespace: self.namespace.clone(),
|
|
75
72
|
workflow_id: pwft.work.execution.workflow_id.clone(),
|
|
76
73
|
workflow_type: pwft.work.workflow_type.clone(),
|
|
77
|
-
run_id:
|
|
74
|
+
run_id: run_id.clone(),
|
|
78
75
|
task_queue: self.task_queue.clone(),
|
|
79
|
-
history:
|
|
76
|
+
history: HistoryUpdate::dummy(),
|
|
80
77
|
metrics,
|
|
81
78
|
capabilities: &self.server_capabilities,
|
|
82
79
|
},
|
|
80
|
+
pwft,
|
|
83
81
|
self.local_activity_request_sink.clone(),
|
|
84
82
|
);
|
|
85
|
-
let run_id = run_id.to_string();
|
|
86
|
-
let rur = mrh.incoming_wft(pwft);
|
|
87
83
|
if self.runs.push(run_id, mrh).is_some() {
|
|
88
84
|
panic!("Overflowed run cache! Cache owner is expected to avoid this!");
|
|
89
85
|
}
|
|
@@ -187,7 +187,7 @@ impl WFStream {
|
|
|
187
187
|
}
|
|
188
188
|
};
|
|
189
189
|
|
|
190
|
-
activations.extend(maybe_act
|
|
190
|
+
activations.extend(maybe_act);
|
|
191
191
|
activations.extend(state.reconcile_buffered());
|
|
192
192
|
|
|
193
193
|
// Always flush *after* actually handling the input, as this allows LA sink
|
|
@@ -301,10 +301,19 @@ impl WFStream {
|
|
|
301
301
|
None
|
|
302
302
|
}
|
|
303
303
|
},
|
|
304
|
-
ValidatedCompletion::Fail {
|
|
304
|
+
ValidatedCompletion::Fail {
|
|
305
|
+
failure,
|
|
306
|
+
is_autocomplete,
|
|
307
|
+
..
|
|
308
|
+
} => rh.failed_completion(
|
|
305
309
|
failure.force_cause(),
|
|
306
|
-
|
|
310
|
+
if is_autocomplete {
|
|
311
|
+
EvictionReason::Unspecified
|
|
312
|
+
} else {
|
|
313
|
+
EvictionReason::LangFail
|
|
314
|
+
},
|
|
307
315
|
failure,
|
|
316
|
+
is_autocomplete,
|
|
308
317
|
complete.response_tx,
|
|
309
318
|
),
|
|
310
319
|
},
|
|
@@ -324,7 +333,8 @@ impl WFStream {
|
|
|
324
333
|
fn process_post_activation(&mut self, report: PostActivationMsg) -> RunUpdateAct {
|
|
325
334
|
let run_id = &report.run_id;
|
|
326
335
|
let wft_from_complete = report.wft_from_complete;
|
|
327
|
-
if let Some(
|
|
336
|
+
if let Some(WFTWithPaginator { wft, .. }) = &wft_from_complete {
|
|
337
|
+
debug!(run_id=%wft.execution.run_id, "New WFT from completion");
|
|
328
338
|
if &wft.execution.run_id != run_id {
|
|
329
339
|
dbg_panic!(
|
|
330
340
|
"Server returned a WFT on completion for a different run ({}) than the \
|
|
@@ -339,48 +349,45 @@ impl WFStream {
|
|
|
339
349
|
|
|
340
350
|
// If we reported to server, we always want to mark it complete.
|
|
341
351
|
let maybe_t = self.complete_wft(run_id, report.wft_report_status);
|
|
352
|
+
// Augment the WFT from complete with the permit if both exist
|
|
353
|
+
let wft_from_complete = wft_from_complete.and_then(|wft| {
|
|
354
|
+
maybe_t.map(|t| PermittedWFT {
|
|
355
|
+
work: wft.wft,
|
|
356
|
+
paginator: wft.paginator,
|
|
357
|
+
permit: t.permit,
|
|
358
|
+
})
|
|
359
|
+
});
|
|
342
360
|
// Delete the activation, but only if the report came from lang, or we know the outstanding
|
|
343
361
|
// activation is expected to be completed internally.
|
|
344
|
-
if let Some(
|
|
345
|
-
rh.
|
|
362
|
+
if let Some((should_evict, mut maybe_buffered)) = self.runs.get_mut(run_id).map(|rh| {
|
|
363
|
+
rh.finish_activation(|act| {
|
|
346
364
|
!report.is_autocomplete || matches!(act, OutstandingActivation::Autocomplete)
|
|
347
365
|
})
|
|
348
366
|
}) {
|
|
349
|
-
|
|
350
|
-
let mut applied_buffered_poll_for_this_run = false;
|
|
351
|
-
if activation.has_eviction() {
|
|
367
|
+
if should_evict {
|
|
352
368
|
debug!(run_id=%run_id, "Evicting run");
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
369
|
+
self.runs.remove(run_id);
|
|
370
|
+
}
|
|
371
|
+
let maybe_ready_wft =
|
|
372
|
+
maybe_buffered
|
|
373
|
+
.get_next_wft()
|
|
374
|
+
.or(wft_from_complete)
|
|
375
|
+
.or_else(|| {
|
|
376
|
+
// Attempt to apply a buffered poll for some *other* run, if we didn't have a
|
|
377
|
+
// wft from complete or a buffered poll for *this* run and we evicted
|
|
378
|
+
if should_evict {
|
|
379
|
+
self.buffered_polls_need_cache_slot.pop_front()
|
|
380
|
+
} else {
|
|
381
|
+
None
|
|
362
382
|
}
|
|
363
|
-
}
|
|
383
|
+
});
|
|
384
|
+
if let Some(wft) = maybe_ready_wft {
|
|
385
|
+
res = self.instantiate_or_update(wft);
|
|
386
|
+
// We accept that there might be query tasks remaining in the buffer if we evicted
|
|
387
|
+
// and re-instantiated here. It's likely those tasks are now invalidated anyway.
|
|
388
|
+
if maybe_buffered.has_tasks() && should_evict {
|
|
389
|
+
panic!("There were leftover buffered tasks");
|
|
364
390
|
}
|
|
365
|
-
|
|
366
|
-
// Attempt to apply a buffered poll for some *other* run, if we didn't have a wft
|
|
367
|
-
// from complete or a buffered poll for *this* run.
|
|
368
|
-
if wft_from_complete.is_none() && !applied_buffered_poll_for_this_run {
|
|
369
|
-
if let Some(buff) = self.buffered_polls_need_cache_slot.pop_front() {
|
|
370
|
-
res = self.instantiate_or_update(buff);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
};
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
if let Some((wft, pag)) = wft_from_complete {
|
|
377
|
-
debug!(run_id=%wft.execution.run_id, "New WFT from completion");
|
|
378
|
-
if let Some(t) = maybe_t {
|
|
379
|
-
res = self.instantiate_or_update(PermittedWFT {
|
|
380
|
-
work: wft,
|
|
381
|
-
permit: t.permit,
|
|
382
|
-
paginator: pag,
|
|
383
|
-
});
|
|
384
391
|
}
|
|
385
392
|
}
|
|
386
393
|
|
|
@@ -12,22 +12,23 @@ categories = ["development-tools"]
|
|
|
12
12
|
|
|
13
13
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
14
14
|
|
|
15
|
+
[features]
|
|
16
|
+
otel_impls = ["opentelemetry"]
|
|
17
|
+
|
|
15
18
|
[dependencies]
|
|
16
19
|
async-trait = "0.1"
|
|
17
20
|
derive_builder = "0.12"
|
|
21
|
+
derive_more = "0.99"
|
|
22
|
+
opentelemetry = { workspace = true, optional = true }
|
|
18
23
|
prost-types = "0.11"
|
|
19
24
|
serde = { version = "1.0", default_features = false, features = ["derive"] }
|
|
20
25
|
serde_json = "1.0"
|
|
21
26
|
thiserror = "1.0"
|
|
22
27
|
tokio = "1.24"
|
|
23
|
-
tonic =
|
|
28
|
+
tonic = { workspace = true }
|
|
24
29
|
tracing-core = "0.1"
|
|
25
30
|
url = "2.3"
|
|
26
31
|
|
|
27
32
|
[dependencies.temporal-sdk-core-protos]
|
|
28
33
|
path = "../sdk-core-protos"
|
|
29
|
-
version = "0.1"
|
|
30
|
-
|
|
31
|
-
[dependencies.temporal-client]
|
|
32
|
-
path = "../client"
|
|
33
|
-
version = "0.1"
|
|
34
|
+
version = "0.1"
|
|
@@ -24,25 +24,17 @@ pub trait Worker: Send + Sync {
|
|
|
24
24
|
/// be one outstanding activation for a particular run of a workflow at any time. If an
|
|
25
25
|
/// activation is not responded to, it will cause that workflow to become stuck forever.
|
|
26
26
|
///
|
|
27
|
-
///
|
|
28
|
-
///
|
|
29
|
-
/// appear with other jobs, but will always appear last in the job list. In this case it is
|
|
30
|
-
/// expected that the workflow code will be invoked, and the response produced as normal, but
|
|
31
|
-
/// the caller should evict the run after doing so.
|
|
27
|
+
/// See [WorkflowActivation] for more details on the expected behavior of lang w.r.t activation
|
|
28
|
+
/// & job processing.
|
|
32
29
|
///
|
|
33
|
-
///
|
|
34
|
-
/// concurrently internally.
|
|
30
|
+
/// Do not call poll concurrently. It handles polling the server concurrently internally.
|
|
35
31
|
async fn poll_workflow_activation(&self) -> Result<WorkflowActivation, PollWfError>;
|
|
36
32
|
|
|
37
33
|
/// Ask the worker for some work, returning an [ActivityTask]. It is then the language SDK's
|
|
38
34
|
/// responsibility to call the appropriate activity code with the provided inputs. Blocks
|
|
39
35
|
/// indefinitely until such work is available or [Worker::shutdown] is called.
|
|
40
36
|
///
|
|
41
|
-
///
|
|
42
|
-
/// provided as the `task_queue` argument.
|
|
43
|
-
///
|
|
44
|
-
/// It is rarely a good idea to call poll concurrently. It handles polling the server
|
|
45
|
-
/// concurrently internally.
|
|
37
|
+
/// Do not call poll concurrently. It handles polling the server concurrently internally.
|
|
46
38
|
async fn poll_activity_task(&self) -> Result<ActivityTask, PollActivityError>;
|
|
47
39
|
|
|
48
40
|
/// Tell the worker that a workflow activation has completed. May (and should) be freely called
|