temporalio 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +130 -0
- data/bridge/Cargo.lock +2865 -0
- data/bridge/Cargo.toml +26 -0
- data/bridge/sdk-core/ARCHITECTURE.md +76 -0
- data/bridge/sdk-core/Cargo.lock +2606 -0
- data/bridge/sdk-core/Cargo.toml +2 -0
- data/bridge/sdk-core/LICENSE.txt +23 -0
- data/bridge/sdk-core/README.md +107 -0
- data/bridge/sdk-core/arch_docs/diagrams/README.md +10 -0
- data/bridge/sdk-core/arch_docs/diagrams/sticky_queues.puml +40 -0
- data/bridge/sdk-core/arch_docs/diagrams/workflow_internals.svg +1 -0
- data/bridge/sdk-core/arch_docs/sticky_queues.md +51 -0
- data/bridge/sdk-core/bridge-ffi/Cargo.toml +24 -0
- data/bridge/sdk-core/bridge-ffi/LICENSE.txt +23 -0
- data/bridge/sdk-core/bridge-ffi/build.rs +25 -0
- data/bridge/sdk-core/bridge-ffi/include/sdk-core-bridge.h +249 -0
- data/bridge/sdk-core/bridge-ffi/src/lib.rs +825 -0
- data/bridge/sdk-core/bridge-ffi/src/wrappers.rs +211 -0
- data/bridge/sdk-core/client/Cargo.toml +40 -0
- data/bridge/sdk-core/client/LICENSE.txt +23 -0
- data/bridge/sdk-core/client/src/lib.rs +1294 -0
- data/bridge/sdk-core/client/src/metrics.rs +165 -0
- data/bridge/sdk-core/client/src/raw.rs +931 -0
- data/bridge/sdk-core/client/src/retry.rs +674 -0
- data/bridge/sdk-core/client/src/workflow_handle/mod.rs +185 -0
- data/bridge/sdk-core/core/Cargo.toml +116 -0
- data/bridge/sdk-core/core/LICENSE.txt +23 -0
- data/bridge/sdk-core/core/benches/workflow_replay.rs +73 -0
- data/bridge/sdk-core/core/src/abstractions.rs +166 -0
- data/bridge/sdk-core/core/src/core_tests/activity_tasks.rs +911 -0
- data/bridge/sdk-core/core/src/core_tests/child_workflows.rs +221 -0
- data/bridge/sdk-core/core/src/core_tests/determinism.rs +107 -0
- data/bridge/sdk-core/core/src/core_tests/local_activities.rs +515 -0
- data/bridge/sdk-core/core/src/core_tests/mod.rs +100 -0
- data/bridge/sdk-core/core/src/core_tests/queries.rs +736 -0
- data/bridge/sdk-core/core/src/core_tests/replay_flag.rs +65 -0
- data/bridge/sdk-core/core/src/core_tests/workers.rs +259 -0
- data/bridge/sdk-core/core/src/core_tests/workflow_cancels.rs +124 -0
- data/bridge/sdk-core/core/src/core_tests/workflow_tasks.rs +2070 -0
- data/bridge/sdk-core/core/src/ephemeral_server/mod.rs +515 -0
- data/bridge/sdk-core/core/src/lib.rs +175 -0
- data/bridge/sdk-core/core/src/log_export.rs +62 -0
- data/bridge/sdk-core/core/src/pollers/mod.rs +54 -0
- data/bridge/sdk-core/core/src/pollers/poll_buffer.rs +297 -0
- data/bridge/sdk-core/core/src/protosext/mod.rs +428 -0
- data/bridge/sdk-core/core/src/replay/mod.rs +71 -0
- data/bridge/sdk-core/core/src/retry_logic.rs +202 -0
- data/bridge/sdk-core/core/src/telemetry/metrics.rs +383 -0
- data/bridge/sdk-core/core/src/telemetry/mod.rs +412 -0
- data/bridge/sdk-core/core/src/telemetry/prometheus_server.rs +77 -0
- data/bridge/sdk-core/core/src/test_help/mod.rs +875 -0
- data/bridge/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +580 -0
- data/bridge/sdk-core/core/src/worker/activities/local_activities.rs +1042 -0
- data/bridge/sdk-core/core/src/worker/activities.rs +464 -0
- data/bridge/sdk-core/core/src/worker/client/mocks.rs +87 -0
- data/bridge/sdk-core/core/src/worker/client.rs +347 -0
- data/bridge/sdk-core/core/src/worker/mod.rs +566 -0
- data/bridge/sdk-core/core/src/worker/workflow/bridge.rs +37 -0
- data/bridge/sdk-core/core/src/worker/workflow/driven_workflow.rs +110 -0
- data/bridge/sdk-core/core/src/worker/workflow/history_update.rs +458 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +911 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +298 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +171 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +860 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +140 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +161 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +133 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +1448 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/mod.rs +342 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/mutable_side_effect_state_machine.rs +127 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +712 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/side_effect_state_machine.rs +71 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +443 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +439 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +169 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +246 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +96 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +1184 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +277 -0
- data/bridge/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +198 -0
- data/bridge/sdk-core/core/src/worker/workflow/managed_run.rs +647 -0
- data/bridge/sdk-core/core/src/worker/workflow/mod.rs +1143 -0
- data/bridge/sdk-core/core/src/worker/workflow/run_cache.rs +145 -0
- data/bridge/sdk-core/core/src/worker/workflow/wft_poller.rs +88 -0
- data/bridge/sdk-core/core/src/worker/workflow/workflow_stream.rs +940 -0
- data/bridge/sdk-core/core-api/Cargo.toml +31 -0
- data/bridge/sdk-core/core-api/LICENSE.txt +23 -0
- data/bridge/sdk-core/core-api/src/errors.rs +95 -0
- data/bridge/sdk-core/core-api/src/lib.rs +151 -0
- data/bridge/sdk-core/core-api/src/worker.rs +135 -0
- data/bridge/sdk-core/etc/deps.svg +187 -0
- data/bridge/sdk-core/etc/dynamic-config.yaml +2 -0
- data/bridge/sdk-core/etc/otel-collector-config.yaml +36 -0
- data/bridge/sdk-core/etc/prometheus.yaml +6 -0
- data/bridge/sdk-core/fsm/Cargo.toml +18 -0
- data/bridge/sdk-core/fsm/LICENSE.txt +23 -0
- data/bridge/sdk-core/fsm/README.md +3 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/Cargo.toml +27 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/LICENSE.txt +23 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +647 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/progress.rs +8 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dupe_transitions_fail.rs +18 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dupe_transitions_fail.stderr +12 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dynamic_dest_pass.rs +41 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/forgot_name_fail.rs +14 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/forgot_name_fail.stderr +11 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/handler_arg_pass.rs +32 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/handler_pass.rs +31 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/medium_complex_pass.rs +46 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.rs +29 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +12 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/simple_pass.rs +32 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/struct_event_variant_fail.rs +18 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/struct_event_variant_fail.stderr +5 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_more_item_event_variant_fail.rs +11 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_more_item_event_variant_fail.stderr +5 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_zero_item_event_variant_fail.rs +11 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_zero_item_event_variant_fail.stderr +5 -0
- data/bridge/sdk-core/fsm/rustfsm_trait/Cargo.toml +14 -0
- data/bridge/sdk-core/fsm/rustfsm_trait/LICENSE.txt +23 -0
- data/bridge/sdk-core/fsm/rustfsm_trait/src/lib.rs +249 -0
- data/bridge/sdk-core/fsm/src/lib.rs +2 -0
- data/bridge/sdk-core/histories/fail_wf_task.bin +0 -0
- data/bridge/sdk-core/histories/timer_workflow_history.bin +0 -0
- data/bridge/sdk-core/integ-with-otel.sh +7 -0
- data/bridge/sdk-core/protos/api_upstream/README.md +9 -0
- data/bridge/sdk-core/protos/api_upstream/api-linter.yaml +40 -0
- data/bridge/sdk-core/protos/api_upstream/buf.yaml +12 -0
- data/bridge/sdk-core/protos/api_upstream/dependencies/gogoproto/gogo.proto +141 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +86 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/cluster/v1/message.proto +83 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +259 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +112 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +46 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/cluster.proto +40 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +57 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +55 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +168 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +97 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +51 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/query.proto +50 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +41 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +60 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +59 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +51 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +122 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +108 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +114 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/filter/v1/message.proto +56 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +751 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +97 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +161 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +99 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +61 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +55 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +300 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +108 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +46 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/version/v1/message.proto +59 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +145 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +1124 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +401 -0
- data/bridge/sdk-core/protos/grpc/health/v1/health.proto +63 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +78 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +79 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +210 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +77 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/common/common.proto +15 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +30 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +30 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +261 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +297 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +29 -0
- data/bridge/sdk-core/protos/testsrv_upstream/api-linter.yaml +38 -0
- data/bridge/sdk-core/protos/testsrv_upstream/buf.yaml +13 -0
- data/bridge/sdk-core/protos/testsrv_upstream/dependencies/gogoproto/gogo.proto +141 -0
- data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +63 -0
- data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +90 -0
- data/bridge/sdk-core/rustfmt.toml +1 -0
- data/bridge/sdk-core/sdk/Cargo.toml +47 -0
- data/bridge/sdk-core/sdk/LICENSE.txt +23 -0
- data/bridge/sdk-core/sdk/src/activity_context.rs +230 -0
- data/bridge/sdk-core/sdk/src/app_data.rs +37 -0
- data/bridge/sdk-core/sdk/src/conversions.rs +8 -0
- data/bridge/sdk-core/sdk/src/interceptors.rs +17 -0
- data/bridge/sdk-core/sdk/src/lib.rs +792 -0
- data/bridge/sdk-core/sdk/src/payload_converter.rs +11 -0
- data/bridge/sdk-core/sdk/src/workflow_context/options.rs +295 -0
- data/bridge/sdk-core/sdk/src/workflow_context.rs +683 -0
- data/bridge/sdk-core/sdk/src/workflow_future.rs +503 -0
- data/bridge/sdk-core/sdk-core-protos/Cargo.toml +30 -0
- data/bridge/sdk-core/sdk-core-protos/LICENSE.txt +23 -0
- data/bridge/sdk-core/sdk-core-protos/build.rs +108 -0
- data/bridge/sdk-core/sdk-core-protos/src/constants.rs +7 -0
- data/bridge/sdk-core/sdk-core-protos/src/history_builder.rs +497 -0
- data/bridge/sdk-core/sdk-core-protos/src/history_info.rs +230 -0
- data/bridge/sdk-core/sdk-core-protos/src/lib.rs +1910 -0
- data/bridge/sdk-core/sdk-core-protos/src/task_token.rs +38 -0
- data/bridge/sdk-core/sdk-core-protos/src/utilities.rs +14 -0
- data/bridge/sdk-core/test-utils/Cargo.toml +35 -0
- data/bridge/sdk-core/test-utils/src/canned_histories.rs +1579 -0
- data/bridge/sdk-core/test-utils/src/histfetch.rs +28 -0
- data/bridge/sdk-core/test-utils/src/lib.rs +598 -0
- data/bridge/sdk-core/tests/integ_tests/client_tests.rs +36 -0
- data/bridge/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +128 -0
- data/bridge/sdk-core/tests/integ_tests/heartbeat_tests.rs +218 -0
- data/bridge/sdk-core/tests/integ_tests/polling_tests.rs +146 -0
- data/bridge/sdk-core/tests/integ_tests/queries_tests.rs +437 -0
- data/bridge/sdk-core/tests/integ_tests/visibility_tests.rs +93 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/activities.rs +878 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +61 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +59 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +58 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +50 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +60 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +54 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +634 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/patches.rs +113 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/replay.rs +137 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/resets.rs +93 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/signals.rs +167 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +99 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/timers.rs +131 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +75 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests.rs +587 -0
- data/bridge/sdk-core/tests/load_tests.rs +191 -0
- data/bridge/sdk-core/tests/main.rs +111 -0
- data/bridge/sdk-core/tests/runner.rs +93 -0
- data/bridge/src/connection.rs +167 -0
- data/bridge/src/lib.rs +180 -0
- data/bridge/src/runtime.rs +47 -0
- data/bridge/src/worker.rs +73 -0
- data/ext/Rakefile +9 -0
- data/lib/bridge.so +0 -0
- data/lib/gen/dependencies/gogoproto/gogo_pb.rb +14 -0
- data/lib/gen/temporal/api/batch/v1/message_pb.rb +48 -0
- data/lib/gen/temporal/api/cluster/v1/message_pb.rb +67 -0
- data/lib/gen/temporal/api/command/v1/message_pb.rb +166 -0
- data/lib/gen/temporal/api/common/v1/message_pb.rb +69 -0
- data/lib/gen/temporal/api/enums/v1/batch_operation_pb.rb +32 -0
- data/lib/gen/temporal/api/enums/v1/cluster_pb.rb +26 -0
- data/lib/gen/temporal/api/enums/v1/command_type_pb.rb +37 -0
- data/lib/gen/temporal/api/enums/v1/common_pb.rb +41 -0
- data/lib/gen/temporal/api/enums/v1/event_type_pb.rb +67 -0
- data/lib/gen/temporal/api/enums/v1/failed_cause_pb.rb +71 -0
- data/lib/gen/temporal/api/enums/v1/namespace_pb.rb +37 -0
- data/lib/gen/temporal/api/enums/v1/query_pb.rb +31 -0
- data/lib/gen/temporal/api/enums/v1/reset_pb.rb +24 -0
- data/lib/gen/temporal/api/enums/v1/schedule_pb.rb +28 -0
- data/lib/gen/temporal/api/enums/v1/task_queue_pb.rb +30 -0
- data/lib/gen/temporal/api/enums/v1/update_pb.rb +28 -0
- data/lib/gen/temporal/api/enums/v1/workflow_pb.rb +89 -0
- data/lib/gen/temporal/api/errordetails/v1/message_pb.rb +84 -0
- data/lib/gen/temporal/api/failure/v1/message_pb.rb +83 -0
- data/lib/gen/temporal/api/filter/v1/message_pb.rb +40 -0
- data/lib/gen/temporal/api/history/v1/message_pb.rb +489 -0
- data/lib/gen/temporal/api/namespace/v1/message_pb.rb +63 -0
- data/lib/gen/temporal/api/operatorservice/v1/request_response_pb.rb +125 -0
- data/lib/gen/temporal/api/operatorservice/v1/service_pb.rb +20 -0
- data/lib/gen/temporal/api/query/v1/message_pb.rb +38 -0
- data/lib/gen/temporal/api/replication/v1/message_pb.rb +37 -0
- data/lib/gen/temporal/api/schedule/v1/message_pb.rb +128 -0
- data/lib/gen/temporal/api/taskqueue/v1/message_pb.rb +73 -0
- data/lib/gen/temporal/api/update/v1/message_pb.rb +26 -0
- data/lib/gen/temporal/api/version/v1/message_pb.rb +41 -0
- data/lib/gen/temporal/api/workflow/v1/message_pb.rb +110 -0
- data/lib/gen/temporal/api/workflowservice/v1/request_response_pb.rb +771 -0
- data/lib/gen/temporal/api/workflowservice/v1/service_pb.rb +20 -0
- data/lib/gen/temporal/sdk/core/activity_result/activity_result_pb.rb +58 -0
- data/lib/gen/temporal/sdk/core/activity_task/activity_task_pb.rb +57 -0
- data/lib/gen/temporal/sdk/core/bridge/bridge_pb.rb +222 -0
- data/lib/gen/temporal/sdk/core/child_workflow/child_workflow_pb.rb +57 -0
- data/lib/gen/temporal/sdk/core/common/common_pb.rb +22 -0
- data/lib/gen/temporal/sdk/core/core_interface_pb.rb +34 -0
- data/lib/gen/temporal/sdk/core/external_data/external_data_pb.rb +27 -0
- data/lib/gen/temporal/sdk/core/workflow_activation/workflow_activation_pb.rb +164 -0
- data/lib/gen/temporal/sdk/core/workflow_commands/workflow_commands_pb.rb +192 -0
- data/lib/gen/temporal/sdk/core/workflow_completion/workflow_completion_pb.rb +34 -0
- data/lib/temporal/bridge.rb +14 -0
- data/lib/temporal/client/implementation.rb +339 -0
- data/lib/temporal/client/workflow_handle.rb +243 -0
- data/lib/temporal/client.rb +144 -0
- data/lib/temporal/connection.rb +736 -0
- data/lib/temporal/data_converter.rb +150 -0
- data/lib/temporal/error/failure.rb +194 -0
- data/lib/temporal/error/workflow_failure.rb +17 -0
- data/lib/temporal/errors.rb +22 -0
- data/lib/temporal/failure_converter/base.rb +26 -0
- data/lib/temporal/failure_converter/basic.rb +313 -0
- data/lib/temporal/failure_converter.rb +8 -0
- data/lib/temporal/interceptor/chain.rb +27 -0
- data/lib/temporal/interceptor/client.rb +102 -0
- data/lib/temporal/payload_codec/base.rb +32 -0
- data/lib/temporal/payload_converter/base.rb +24 -0
- data/lib/temporal/payload_converter/bytes.rb +26 -0
- data/lib/temporal/payload_converter/composite.rb +47 -0
- data/lib/temporal/payload_converter/encoding_base.rb +35 -0
- data/lib/temporal/payload_converter/json.rb +25 -0
- data/lib/temporal/payload_converter/nil.rb +25 -0
- data/lib/temporal/payload_converter.rb +14 -0
- data/lib/temporal/retry_policy.rb +82 -0
- data/lib/temporal/retry_state.rb +35 -0
- data/lib/temporal/runtime.rb +22 -0
- data/lib/temporal/timeout_type.rb +29 -0
- data/lib/temporal/version.rb +3 -0
- data/lib/temporal/workflow/execution_info.rb +54 -0
- data/lib/temporal/workflow/execution_status.rb +36 -0
- data/lib/temporal/workflow/id_reuse_policy.rb +36 -0
- data/lib/temporal/workflow/query_reject_condition.rb +33 -0
- data/lib/temporal.rb +8 -0
- data/lib/temporalio.rb +3 -0
- data/lib/thermite_patch.rb +23 -0
- data/temporalio.gemspec +41 -0
- metadata +583 -0
@@ -0,0 +1,503 @@
|
|
1
|
+
use crate::{
|
2
|
+
conversions::anyhow_to_fail, workflow_context::WfContextSharedData, CancellableID, RustWfCmd,
|
3
|
+
SignalData, TimerResult, UnblockEvent, WfContext, WfExitValue, WorkflowFunction,
|
4
|
+
WorkflowResult,
|
5
|
+
};
|
6
|
+
use anyhow::{anyhow, bail, Context as AnyhowContext, Error};
|
7
|
+
use crossbeam::channel::Receiver;
|
8
|
+
use futures::{future::BoxFuture, FutureExt};
|
9
|
+
use parking_lot::RwLock;
|
10
|
+
use std::{
|
11
|
+
collections::{hash_map::Entry, HashMap},
|
12
|
+
future::Future,
|
13
|
+
panic::AssertUnwindSafe,
|
14
|
+
pin::Pin,
|
15
|
+
sync::Arc,
|
16
|
+
task::{Context, Poll},
|
17
|
+
};
|
18
|
+
use temporal_sdk_core_protos::{
|
19
|
+
coresdk::{
|
20
|
+
workflow_activation::{
|
21
|
+
workflow_activation_job::Variant, FireTimer, NotifyHasPatch, ResolveActivity,
|
22
|
+
ResolveChildWorkflowExecution, ResolveChildWorkflowExecutionStart, WorkflowActivation,
|
23
|
+
WorkflowActivationJob,
|
24
|
+
},
|
25
|
+
workflow_commands::{
|
26
|
+
request_cancel_external_workflow_execution as cancel_we, workflow_command,
|
27
|
+
CancelChildWorkflowExecution, CancelSignalWorkflow, CancelTimer,
|
28
|
+
CancelWorkflowExecution, CompleteWorkflowExecution, FailWorkflowExecution,
|
29
|
+
RequestCancelActivity, RequestCancelExternalWorkflowExecution,
|
30
|
+
RequestCancelLocalActivity, ScheduleActivity, ScheduleLocalActivity,
|
31
|
+
StartChildWorkflowExecution, StartTimer,
|
32
|
+
},
|
33
|
+
workflow_completion::WorkflowActivationCompletion,
|
34
|
+
},
|
35
|
+
temporal::api::{common::v1::Payload, failure::v1::Failure},
|
36
|
+
utilities::TryIntoOrNone,
|
37
|
+
};
|
38
|
+
use tokio::sync::{
|
39
|
+
mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
|
40
|
+
oneshot, watch,
|
41
|
+
};
|
42
|
+
|
43
|
+
impl WorkflowFunction {
|
44
|
+
/// Start a workflow function, returning a future that will resolve when the workflow does,
|
45
|
+
/// and a channel that can be used to send it activations.
|
46
|
+
#[doc(hidden)]
|
47
|
+
pub fn start_workflow(
|
48
|
+
&self,
|
49
|
+
namespace: String,
|
50
|
+
task_queue: String,
|
51
|
+
args: Vec<Payload>,
|
52
|
+
outgoing_completions: UnboundedSender<WorkflowActivationCompletion>,
|
53
|
+
) -> (
|
54
|
+
impl Future<Output = WorkflowResult<()>>,
|
55
|
+
UnboundedSender<WorkflowActivation>,
|
56
|
+
) {
|
57
|
+
let (cancel_tx, cancel_rx) = watch::channel(false);
|
58
|
+
let (wf_context, cmd_receiver) = WfContext::new(namespace, task_queue, args, cancel_rx);
|
59
|
+
let (tx, incoming_activations) = unbounded_channel();
|
60
|
+
(
|
61
|
+
WorkflowFuture {
|
62
|
+
ctx_shared: wf_context.get_shared_data(),
|
63
|
+
// We need to mark the workflow future as unconstrained, otherwise Tokio will impose
|
64
|
+
// an artificial limit on how many commands we can unblock in one poll round.
|
65
|
+
// TODO: Now we *need* deadlock detection or we could hose the whole system
|
66
|
+
inner: tokio::task::unconstrained((self.wf_func)(wf_context)).boxed(),
|
67
|
+
incoming_commands: cmd_receiver,
|
68
|
+
outgoing_completions,
|
69
|
+
incoming_activations,
|
70
|
+
command_status: Default::default(),
|
71
|
+
cancel_sender: cancel_tx,
|
72
|
+
child_workflow_starts: Default::default(),
|
73
|
+
sig_chans: Default::default(),
|
74
|
+
},
|
75
|
+
tx,
|
76
|
+
)
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
struct WFCommandFutInfo {
|
81
|
+
unblocker: oneshot::Sender<UnblockEvent>,
|
82
|
+
}
|
83
|
+
|
84
|
+
// Allows the workflow to receive signals even though the signal handler may not yet be registered.
|
85
|
+
// TODO: Either make this go away by requiring all signals to be registered up-front in a more
|
86
|
+
// production-ready SDK design, or if desired to allow dynamic signal registration, prevent this
|
87
|
+
// from growing unbounded if being sent lots of unhandled signals.
|
88
|
+
enum SigChanOrBuffer {
|
89
|
+
Chan(UnboundedSender<SignalData>),
|
90
|
+
Buffer(Vec<SignalData>),
|
91
|
+
}
|
92
|
+
|
93
|
+
pub struct WorkflowFuture {
|
94
|
+
/// Future produced by calling the workflow function
|
95
|
+
inner: BoxFuture<'static, WorkflowResult<()>>,
|
96
|
+
/// Commands produced inside user's wf code
|
97
|
+
incoming_commands: Receiver<RustWfCmd>,
|
98
|
+
/// Once blocked or the workflow has finished or errored out, the result is sent here
|
99
|
+
outgoing_completions: UnboundedSender<WorkflowActivationCompletion>,
|
100
|
+
/// Activations from core
|
101
|
+
incoming_activations: UnboundedReceiver<WorkflowActivation>,
|
102
|
+
/// Commands by ID -> blocked status
|
103
|
+
command_status: HashMap<CommandID, WFCommandFutInfo>,
|
104
|
+
/// Use to notify workflow code of cancellation
|
105
|
+
cancel_sender: watch::Sender<bool>,
|
106
|
+
/// Data shared with the context
|
107
|
+
ctx_shared: Arc<RwLock<WfContextSharedData>>,
|
108
|
+
/// Mapping of sequence number to a StartChildWorkflowExecution request
|
109
|
+
child_workflow_starts: HashMap<u32, StartChildWorkflowExecution>,
|
110
|
+
/// Maps signal IDs to channels to send down when they are signaled
|
111
|
+
sig_chans: HashMap<String, SigChanOrBuffer>,
|
112
|
+
}
|
113
|
+
|
114
|
+
impl WorkflowFuture {
|
115
|
+
fn unblock(&mut self, event: UnblockEvent) -> Result<(), Error> {
|
116
|
+
let cmd_id = match event {
|
117
|
+
UnblockEvent::Timer(seq, _) => CommandID::Timer(seq),
|
118
|
+
UnblockEvent::Activity(seq, _) => CommandID::Activity(seq),
|
119
|
+
UnblockEvent::WorkflowStart(seq, _) => CommandID::ChildWorkflowStart(seq),
|
120
|
+
UnblockEvent::WorkflowComplete(seq, _) => CommandID::ChildWorkflowComplete(seq),
|
121
|
+
UnblockEvent::SignalExternal(seq, _) => CommandID::SignalExternal(seq),
|
122
|
+
UnblockEvent::CancelExternal(seq, _) => CommandID::CancelExternal(seq),
|
123
|
+
};
|
124
|
+
let unblocker = self.command_status.remove(&cmd_id);
|
125
|
+
let _ = unblocker
|
126
|
+
.ok_or_else(|| anyhow!("Command {:?} not found to unblock!", cmd_id))?
|
127
|
+
.unblocker
|
128
|
+
.send(event);
|
129
|
+
Ok(())
|
130
|
+
}
|
131
|
+
|
132
|
+
fn fail_wft(&self, run_id: String, fail: Error) {
|
133
|
+
warn!("Workflow task failed for {}: {}", run_id, fail);
|
134
|
+
self.outgoing_completions
|
135
|
+
.send(WorkflowActivationCompletion::fail(
|
136
|
+
run_id,
|
137
|
+
anyhow_to_fail(fail),
|
138
|
+
))
|
139
|
+
.expect("Completion channel intact");
|
140
|
+
}
|
141
|
+
|
142
|
+
fn send_completion(&self, run_id: String, activation_cmds: Vec<workflow_command::Variant>) {
|
143
|
+
self.outgoing_completions
|
144
|
+
.send(WorkflowActivationCompletion::from_cmds(
|
145
|
+
run_id,
|
146
|
+
activation_cmds,
|
147
|
+
))
|
148
|
+
.expect("Completion channel intact");
|
149
|
+
}
|
150
|
+
|
151
|
+
/// Handle a particular workflow activation job.
|
152
|
+
///
|
153
|
+
/// Returns Ok(true) if the workflow should be evicted. Returns an error in the event that
|
154
|
+
/// the workflow task should be failed.
|
155
|
+
///
|
156
|
+
/// Panics if internal assumptions are violated
|
157
|
+
fn handle_job(&mut self, variant: Option<Variant>) -> Result<bool, Error> {
|
158
|
+
if let Some(v) = variant {
|
159
|
+
match v {
|
160
|
+
Variant::StartWorkflow(_) => {
|
161
|
+
// TODO: Can assign randomness seed whenever needed
|
162
|
+
}
|
163
|
+
Variant::FireTimer(FireTimer { seq }) => {
|
164
|
+
self.unblock(UnblockEvent::Timer(seq, TimerResult::Fired))?
|
165
|
+
}
|
166
|
+
Variant::ResolveActivity(ResolveActivity { seq, result }) => {
|
167
|
+
self.unblock(UnblockEvent::Activity(
|
168
|
+
seq,
|
169
|
+
Box::new(result.context("Activity must have result")?),
|
170
|
+
))?;
|
171
|
+
}
|
172
|
+
Variant::ResolveChildWorkflowExecutionStart(
|
173
|
+
ResolveChildWorkflowExecutionStart { seq, status },
|
174
|
+
) => self.unblock(UnblockEvent::WorkflowStart(
|
175
|
+
seq,
|
176
|
+
Box::new(status.context("Workflow start must have status")?),
|
177
|
+
))?,
|
178
|
+
Variant::ResolveChildWorkflowExecution(ResolveChildWorkflowExecution {
|
179
|
+
seq,
|
180
|
+
result,
|
181
|
+
}) => self.unblock(UnblockEvent::WorkflowComplete(
|
182
|
+
seq,
|
183
|
+
Box::new(result.context("Child Workflow execution must have a result")?),
|
184
|
+
))?,
|
185
|
+
Variant::UpdateRandomSeed(_) => (),
|
186
|
+
Variant::QueryWorkflow(_) => {
|
187
|
+
todo!()
|
188
|
+
}
|
189
|
+
Variant::CancelWorkflow(_) => {
|
190
|
+
// TODO: Cancel pending futures, etc
|
191
|
+
self.cancel_sender
|
192
|
+
.send(true)
|
193
|
+
.expect("Cancel rx not dropped");
|
194
|
+
}
|
195
|
+
Variant::SignalWorkflow(sig) => {
|
196
|
+
let mut dat = SignalData::new(sig.input);
|
197
|
+
dat.headers = sig.headers;
|
198
|
+
match self.sig_chans.entry(sig.signal_name) {
|
199
|
+
Entry::Occupied(mut o) => match o.get_mut() {
|
200
|
+
SigChanOrBuffer::Chan(chan) => {
|
201
|
+
let _ = chan.send(dat);
|
202
|
+
}
|
203
|
+
SigChanOrBuffer::Buffer(ref mut buf) => buf.push(dat),
|
204
|
+
},
|
205
|
+
Entry::Vacant(v) => {
|
206
|
+
v.insert(SigChanOrBuffer::Buffer(vec![dat]));
|
207
|
+
}
|
208
|
+
}
|
209
|
+
}
|
210
|
+
Variant::NotifyHasPatch(NotifyHasPatch { patch_id }) => {
|
211
|
+
self.ctx_shared.write().changes.insert(patch_id, true);
|
212
|
+
}
|
213
|
+
Variant::ResolveSignalExternalWorkflow(attrs) => {
|
214
|
+
self.unblock(UnblockEvent::SignalExternal(attrs.seq, attrs.failure))?;
|
215
|
+
}
|
216
|
+
Variant::ResolveRequestCancelExternalWorkflow(attrs) => {
|
217
|
+
self.unblock(UnblockEvent::CancelExternal(attrs.seq, attrs.failure))?;
|
218
|
+
}
|
219
|
+
|
220
|
+
Variant::RemoveFromCache(_) => {
|
221
|
+
return Ok(true);
|
222
|
+
}
|
223
|
+
}
|
224
|
+
} else {
|
225
|
+
bail!("Empty activation job variant");
|
226
|
+
}
|
227
|
+
|
228
|
+
Ok(false)
|
229
|
+
}
|
230
|
+
}
|
231
|
+
|
232
|
+
impl Future for WorkflowFuture {
|
233
|
+
type Output = WorkflowResult<()>;
|
234
|
+
|
235
|
+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
236
|
+
'activations: loop {
|
237
|
+
// WF must always receive an activation first before responding with commands
|
238
|
+
let activation = match self.incoming_activations.poll_recv(cx) {
|
239
|
+
Poll::Ready(a) => match a {
|
240
|
+
Some(act) => act,
|
241
|
+
None => {
|
242
|
+
return Poll::Ready(Err(anyhow!(
|
243
|
+
"Workflow future's activation channel was lost!"
|
244
|
+
)))
|
245
|
+
}
|
246
|
+
},
|
247
|
+
Poll::Pending => return Poll::Pending,
|
248
|
+
};
|
249
|
+
|
250
|
+
let is_only_eviction = activation.is_only_eviction();
|
251
|
+
let run_id = activation.run_id;
|
252
|
+
{
|
253
|
+
let mut wlock = self.ctx_shared.write();
|
254
|
+
wlock.is_replaying = activation.is_replaying;
|
255
|
+
wlock.wf_time = activation.timestamp.try_into_or_none();
|
256
|
+
}
|
257
|
+
|
258
|
+
let mut die_of_eviction_when_done = false;
|
259
|
+
for WorkflowActivationJob { variant } in activation.jobs {
|
260
|
+
match self.handle_job(variant) {
|
261
|
+
Ok(true) => {
|
262
|
+
die_of_eviction_when_done = true;
|
263
|
+
}
|
264
|
+
Err(e) => {
|
265
|
+
self.fail_wft(run_id, e);
|
266
|
+
continue 'activations;
|
267
|
+
}
|
268
|
+
_ => (),
|
269
|
+
}
|
270
|
+
}
|
271
|
+
|
272
|
+
if is_only_eviction {
|
273
|
+
// No need to do anything with the workflow code in this case
|
274
|
+
self.outgoing_completions
|
275
|
+
.send(WorkflowActivationCompletion::from_cmds(run_id, vec![]))
|
276
|
+
.expect("Completion channel intact");
|
277
|
+
return Ok(WfExitValue::Evicted).into();
|
278
|
+
}
|
279
|
+
|
280
|
+
// TODO: Make sure this is *actually* safe before un-prototyping rust sdk
|
281
|
+
let mut res = match AssertUnwindSafe(&mut self.inner)
|
282
|
+
.catch_unwind()
|
283
|
+
.poll_unpin(cx)
|
284
|
+
{
|
285
|
+
Poll::Ready(Err(e)) => {
|
286
|
+
let errmsg = format!(
|
287
|
+
"Workflow function panicked: {:?}",
|
288
|
+
// Panics are typically strings
|
289
|
+
e.downcast::<String>()
|
290
|
+
);
|
291
|
+
warn!("{}", errmsg);
|
292
|
+
self.outgoing_completions
|
293
|
+
.send(WorkflowActivationCompletion::fail(
|
294
|
+
run_id,
|
295
|
+
Failure {
|
296
|
+
message: errmsg,
|
297
|
+
..Default::default()
|
298
|
+
},
|
299
|
+
))
|
300
|
+
.expect("Completion channel intact");
|
301
|
+
// Loop back up because we're about to get evicted
|
302
|
+
continue;
|
303
|
+
}
|
304
|
+
Poll::Ready(Ok(r)) => Poll::Ready(r),
|
305
|
+
Poll::Pending => Poll::Pending,
|
306
|
+
};
|
307
|
+
|
308
|
+
let mut activation_cmds = vec![];
|
309
|
+
while let Ok(cmd) = self.incoming_commands.try_recv() {
|
310
|
+
match cmd {
|
311
|
+
RustWfCmd::Cancel(cancellable_id) => {
|
312
|
+
match cancellable_id {
|
313
|
+
CancellableID::Timer(seq) => {
|
314
|
+
activation_cmds.push(workflow_command::Variant::CancelTimer(
|
315
|
+
CancelTimer { seq },
|
316
|
+
));
|
317
|
+
self.unblock(UnblockEvent::Timer(seq, TimerResult::Cancelled))?;
|
318
|
+
// Re-poll wf future since a timer is now unblocked
|
319
|
+
res = self.inner.poll_unpin(cx);
|
320
|
+
}
|
321
|
+
CancellableID::Activity(seq) => {
|
322
|
+
activation_cmds.push(
|
323
|
+
workflow_command::Variant::RequestCancelActivity(
|
324
|
+
RequestCancelActivity { seq },
|
325
|
+
),
|
326
|
+
);
|
327
|
+
}
|
328
|
+
CancellableID::LocalActivity(seq) => {
|
329
|
+
activation_cmds.push(
|
330
|
+
workflow_command::Variant::RequestCancelLocalActivity(
|
331
|
+
RequestCancelLocalActivity { seq },
|
332
|
+
),
|
333
|
+
);
|
334
|
+
}
|
335
|
+
CancellableID::ChildWorkflow(seq) => {
|
336
|
+
activation_cmds.push(
|
337
|
+
workflow_command::Variant::CancelChildWorkflowExecution(
|
338
|
+
CancelChildWorkflowExecution {
|
339
|
+
child_workflow_seq: seq,
|
340
|
+
},
|
341
|
+
),
|
342
|
+
);
|
343
|
+
}
|
344
|
+
CancellableID::SignalExternalWorkflow(seq) => {
|
345
|
+
activation_cmds.push(
|
346
|
+
workflow_command::Variant::CancelSignalWorkflow(
|
347
|
+
CancelSignalWorkflow { seq },
|
348
|
+
),
|
349
|
+
);
|
350
|
+
}
|
351
|
+
CancellableID::ExternalWorkflow {
|
352
|
+
seqnum,
|
353
|
+
execution,
|
354
|
+
only_child,
|
355
|
+
} => {
|
356
|
+
activation_cmds.push(
|
357
|
+
workflow_command::Variant::RequestCancelExternalWorkflowExecution(
|
358
|
+
RequestCancelExternalWorkflowExecution {
|
359
|
+
seq: seqnum,
|
360
|
+
target: Some(if only_child {
|
361
|
+
cancel_we::Target::ChildWorkflowId(execution.workflow_id)
|
362
|
+
} else {
|
363
|
+
cancel_we::Target::WorkflowExecution(execution)
|
364
|
+
}),
|
365
|
+
},
|
366
|
+
),
|
367
|
+
);
|
368
|
+
}
|
369
|
+
}
|
370
|
+
}
|
371
|
+
RustWfCmd::NewCmd(cmd) => {
|
372
|
+
activation_cmds.push(cmd.cmd.clone());
|
373
|
+
|
374
|
+
let command_id = match cmd.cmd {
|
375
|
+
workflow_command::Variant::StartTimer(StartTimer { seq, .. }) => {
|
376
|
+
CommandID::Timer(seq)
|
377
|
+
}
|
378
|
+
workflow_command::Variant::ScheduleActivity(ScheduleActivity {
|
379
|
+
seq,
|
380
|
+
..
|
381
|
+
})
|
382
|
+
| workflow_command::Variant::ScheduleLocalActivity(
|
383
|
+
ScheduleLocalActivity { seq, .. },
|
384
|
+
) => CommandID::Activity(seq),
|
385
|
+
workflow_command::Variant::SetPatchMarker(_) => {
|
386
|
+
panic!("Set patch marker should be a nonblocking command")
|
387
|
+
}
|
388
|
+
workflow_command::Variant::StartChildWorkflowExecution(req) => {
|
389
|
+
let seq = req.seq;
|
390
|
+
// Save the start request to support cancellation later
|
391
|
+
self.child_workflow_starts.insert(seq, req);
|
392
|
+
CommandID::ChildWorkflowStart(seq)
|
393
|
+
}
|
394
|
+
workflow_command::Variant::SignalExternalWorkflowExecution(req) => {
|
395
|
+
CommandID::SignalExternal(req.seq)
|
396
|
+
}
|
397
|
+
workflow_command::Variant::RequestCancelExternalWorkflowExecution(
|
398
|
+
req,
|
399
|
+
) => CommandID::CancelExternal(req.seq),
|
400
|
+
_ => unimplemented!("Command type not implemented"),
|
401
|
+
};
|
402
|
+
self.command_status.insert(
|
403
|
+
command_id,
|
404
|
+
WFCommandFutInfo {
|
405
|
+
unblocker: cmd.unblocker,
|
406
|
+
},
|
407
|
+
);
|
408
|
+
}
|
409
|
+
RustWfCmd::NewNonblockingCmd(cmd) => {
|
410
|
+
activation_cmds.push(cmd);
|
411
|
+
}
|
412
|
+
RustWfCmd::SubscribeChildWorkflowCompletion(sub) => {
|
413
|
+
self.command_status.insert(
|
414
|
+
CommandID::ChildWorkflowComplete(sub.seq),
|
415
|
+
WFCommandFutInfo {
|
416
|
+
unblocker: sub.unblocker,
|
417
|
+
},
|
418
|
+
);
|
419
|
+
}
|
420
|
+
RustWfCmd::SubscribeSignal(signame, chan) => {
|
421
|
+
// Deal with any buffered signal inputs for signals that were not yet
|
422
|
+
// registered
|
423
|
+
if let Some(SigChanOrBuffer::Buffer(buf)) = self.sig_chans.remove(&signame)
|
424
|
+
{
|
425
|
+
for input in buf {
|
426
|
+
let _ = chan.send(input);
|
427
|
+
}
|
428
|
+
// Re-poll wf future since signals may be unblocked
|
429
|
+
res = self.inner.poll_unpin(cx);
|
430
|
+
}
|
431
|
+
self.sig_chans.insert(signame, SigChanOrBuffer::Chan(chan));
|
432
|
+
}
|
433
|
+
RustWfCmd::ForceWFTFailure(err) => {
|
434
|
+
self.fail_wft(run_id, err);
|
435
|
+
continue 'activations;
|
436
|
+
}
|
437
|
+
}
|
438
|
+
}
|
439
|
+
|
440
|
+
if let Poll::Ready(res) = res {
|
441
|
+
// TODO: Auto reply with cancel when cancelled (instead of normal exit value)
|
442
|
+
match res {
|
443
|
+
Ok(exit_val) => match exit_val {
|
444
|
+
// TODO: Generic values
|
445
|
+
WfExitValue::Normal(_) => {
|
446
|
+
activation_cmds.push(
|
447
|
+
workflow_command::Variant::CompleteWorkflowExecution(
|
448
|
+
CompleteWorkflowExecution { result: None },
|
449
|
+
),
|
450
|
+
);
|
451
|
+
}
|
452
|
+
WfExitValue::ContinueAsNew(cmd) => activation_cmds.push((*cmd).into()),
|
453
|
+
WfExitValue::Cancelled => {
|
454
|
+
activation_cmds.push(
|
455
|
+
workflow_command::Variant::CancelWorkflowExecution(
|
456
|
+
CancelWorkflowExecution {},
|
457
|
+
),
|
458
|
+
);
|
459
|
+
}
|
460
|
+
WfExitValue::Evicted => {
|
461
|
+
panic!("Don't explicitly return this")
|
462
|
+
}
|
463
|
+
},
|
464
|
+
Err(e) => {
|
465
|
+
activation_cmds.push(workflow_command::Variant::FailWorkflowExecution(
|
466
|
+
FailWorkflowExecution {
|
467
|
+
failure: Some(Failure {
|
468
|
+
message: e.to_string(),
|
469
|
+
..Default::default()
|
470
|
+
}),
|
471
|
+
},
|
472
|
+
));
|
473
|
+
}
|
474
|
+
}
|
475
|
+
}
|
476
|
+
|
477
|
+
// TODO: deadlock detector
|
478
|
+
// Check if there's nothing to unblock and workflow has not completed.
|
479
|
+
// This is different from the assertion that was here before that checked that WF did
|
480
|
+
// not produce any commands which is completely viable in the case WF is waiting on
|
481
|
+
// multiple completions.
|
482
|
+
|
483
|
+
self.send_completion(run_id, activation_cmds);
|
484
|
+
|
485
|
+
if die_of_eviction_when_done {
|
486
|
+
return Ok(WfExitValue::Evicted).into();
|
487
|
+
}
|
488
|
+
|
489
|
+
// We don't actually return here, since we could be queried after finishing executing,
|
490
|
+
// and it allows us to rely on evictions for death and cache management
|
491
|
+
}
|
492
|
+
}
|
493
|
+
}
|
494
|
+
|
495
|
+
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
496
|
+
enum CommandID {
|
497
|
+
Timer(u32),
|
498
|
+
Activity(u32),
|
499
|
+
ChildWorkflowStart(u32),
|
500
|
+
ChildWorkflowComplete(u32),
|
501
|
+
SignalExternal(u32),
|
502
|
+
CancelExternal(u32),
|
503
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
[package]
|
2
|
+
name = "temporal-sdk-core-protos"
|
3
|
+
version = "0.1.0"
|
4
|
+
edition = "2021"
|
5
|
+
authors = ["Spencer Judge <spencer@temporal.io>"]
|
6
|
+
license-file = "LICENSE.txt"
|
7
|
+
description = "Protobuf definitions for Temporal SDKs Core/Lang interface"
|
8
|
+
homepage = "https://temporal.io/"
|
9
|
+
repository = "https://github.com/temporalio/sdk-core"
|
10
|
+
keywords = ["temporal", "workflow"]
|
11
|
+
categories = ["development-tools"]
|
12
|
+
|
13
|
+
[features]
|
14
|
+
history_builders = ["uuid", "rand"]
|
15
|
+
|
16
|
+
[dependencies]
|
17
|
+
anyhow = "1.0"
|
18
|
+
base64 = "0.13"
|
19
|
+
derive_more = "0.99"
|
20
|
+
prost = "0.11"
|
21
|
+
prost-types = "0.11"
|
22
|
+
rand = { version = "0.8", optional = true }
|
23
|
+
serde = { version = "1.0", features = ["derive"] }
|
24
|
+
serde_json = "1.0"
|
25
|
+
thiserror = "1.0"
|
26
|
+
tonic = "0.8"
|
27
|
+
uuid = { version = "1.1", features = ["v4"], optional = true }
|
28
|
+
|
29
|
+
[build-dependencies]
|
30
|
+
tonic-build = "0.8"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Temporal Core SDK
|
2
|
+
|
3
|
+
The MIT License
|
4
|
+
|
5
|
+
Copyright (c) 2021 Temporal Technologies, Inc. All Rights Reserved
|
6
|
+
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
of this software and associated documentation files (the "Software"), to deal
|
9
|
+
in the Software without restriction, including without limitation the rights
|
10
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
copies of the Software, and to permit persons to whom the Software is
|
12
|
+
furnished to do so, subject to the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be included in all
|
15
|
+
copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
23
|
+
SOFTWARE.
|
@@ -0,0 +1,108 @@
|
|
1
|
+
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
2
|
+
println!("cargo:rerun-if-changed=../protos");
|
3
|
+
tonic_build::configure()
|
4
|
+
// We don't actually want to build the grpc definitions - we don't need them (for now).
|
5
|
+
// Just build the message structs.
|
6
|
+
.build_server(false)
|
7
|
+
.build_client(true)
|
8
|
+
// Make conversions easier for some types
|
9
|
+
.type_attribute(
|
10
|
+
"temporal.api.history.v1.HistoryEvent.attributes",
|
11
|
+
"#[derive(::derive_more::From)]",
|
12
|
+
)
|
13
|
+
.type_attribute(
|
14
|
+
"temporal.api.history.v1.History",
|
15
|
+
"#[derive(::derive_more::From)]",
|
16
|
+
)
|
17
|
+
.type_attribute(
|
18
|
+
"temporal.api.command.v1.Command.attributes",
|
19
|
+
"#[derive(::derive_more::From)]",
|
20
|
+
)
|
21
|
+
.type_attribute(
|
22
|
+
"temporal.api.common.v1.WorkflowType",
|
23
|
+
"#[derive(::derive_more::From)]",
|
24
|
+
)
|
25
|
+
.type_attribute(
|
26
|
+
"temporal.api.common.v1.Header",
|
27
|
+
"#[derive(::derive_more::From)]",
|
28
|
+
)
|
29
|
+
.type_attribute(
|
30
|
+
"temporal.api.common.v1.Memo",
|
31
|
+
"#[derive(::derive_more::From)]",
|
32
|
+
)
|
33
|
+
.type_attribute(
|
34
|
+
"temporal.api.enums.v1.SignalExternalWorkflowExecutionFailedCause",
|
35
|
+
"#[derive(::derive_more::Display)]",
|
36
|
+
)
|
37
|
+
.type_attribute(
|
38
|
+
"temporal.api.enums.v1.CancelExternalWorkflowExecutionFailedCause",
|
39
|
+
"#[derive(::derive_more::Display)]",
|
40
|
+
)
|
41
|
+
.type_attribute(
|
42
|
+
"coresdk.workflow_commands.WorkflowCommand.variant",
|
43
|
+
"#[derive(::derive_more::From, ::derive_more::Display)]",
|
44
|
+
)
|
45
|
+
.type_attribute(
|
46
|
+
"coresdk.workflow_commands.QueryResult.variant",
|
47
|
+
"#[derive(::derive_more::From)]",
|
48
|
+
)
|
49
|
+
.type_attribute(
|
50
|
+
"coresdk.workflow_activation.workflow_activation_job",
|
51
|
+
"#[derive(::derive_more::From)]",
|
52
|
+
)
|
53
|
+
.type_attribute(
|
54
|
+
"coresdk.workflow_activation.WorkflowActivationJob.variant",
|
55
|
+
"#[derive(::derive_more::From)]",
|
56
|
+
)
|
57
|
+
.type_attribute(
|
58
|
+
"coresdk.workflow_completion.WorkflowActivationCompletion.status",
|
59
|
+
"#[derive(::derive_more::From)]",
|
60
|
+
)
|
61
|
+
.type_attribute(
|
62
|
+
"coresdk.activity_result.ActivityExecutionResult.status",
|
63
|
+
"#[derive(::derive_more::From)]",
|
64
|
+
)
|
65
|
+
.type_attribute(
|
66
|
+
"coresdk.activity_result.ActivityResolution.status",
|
67
|
+
"#[derive(::derive_more::From)]",
|
68
|
+
)
|
69
|
+
.type_attribute(
|
70
|
+
"coresdk.activity_task.ActivityCancelReason",
|
71
|
+
"#[derive(::derive_more::Display)]",
|
72
|
+
)
|
73
|
+
.type_attribute("coresdk.Task.variant", "#[derive(::derive_more::From)]")
|
74
|
+
// All external data is useful to be able to JSON serialize, so it can render in web UI
|
75
|
+
.type_attribute(
|
76
|
+
".coresdk.external_data",
|
77
|
+
"#[derive(::serde::Serialize, ::serde::Deserialize)]",
|
78
|
+
)
|
79
|
+
.field_attribute(
|
80
|
+
"coresdk.external_data.LocalActivityMarkerData.complete_time",
|
81
|
+
"#[serde(with = \"opt_timestamp\")]",
|
82
|
+
)
|
83
|
+
.field_attribute(
|
84
|
+
"coresdk.external_data.LocalActivityMarkerData.original_schedule_time",
|
85
|
+
"#[serde(with = \"opt_timestamp\")]",
|
86
|
+
)
|
87
|
+
.field_attribute(
|
88
|
+
"coresdk.external_data.LocalActivityMarkerData.backoff",
|
89
|
+
"#[serde(with = \"opt_duration\")]",
|
90
|
+
)
|
91
|
+
.compile(
|
92
|
+
&[
|
93
|
+
"../protos/local/temporal/sdk/core/core_interface.proto",
|
94
|
+
"../protos/local/temporal/sdk/core/bridge/bridge.proto",
|
95
|
+
"../protos/api_upstream/temporal/api/workflowservice/v1/service.proto",
|
96
|
+
"../protos/api_upstream/temporal/api/operatorservice/v1/service.proto",
|
97
|
+
"../protos/testsrv_upstream/temporal/api/testservice/v1/service.proto",
|
98
|
+
"../protos/grpc/health/v1/health.proto",
|
99
|
+
],
|
100
|
+
&[
|
101
|
+
"../protos/api_upstream",
|
102
|
+
"../protos/local",
|
103
|
+
"../protos/testsrv_upstream",
|
104
|
+
"../protos/grpc",
|
105
|
+
],
|
106
|
+
)?;
|
107
|
+
Ok(())
|
108
|
+
}
|
@@ -0,0 +1,7 @@
|
|
1
|
+
//! Contains various constants that are used by core when storing/serializing data
|
2
|
+
|
3
|
+
/// Used as `marker_name` field when recording patch markers
|
4
|
+
pub const PATCH_MARKER_NAME: &str = "core_patch";
|
5
|
+
|
6
|
+
/// Used as `marker_name` field when recording local activity markers
|
7
|
+
pub const LOCAL_ACTIVITY_MARKER_NAME: &str = "core_local_activity";
|