temporalio 0.0.0 → 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 +301 -0
- data/bridge/Cargo.lock +2888 -0
- data/bridge/Cargo.toml +27 -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 +104 -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/client/Cargo.toml +40 -0
- data/bridge/sdk-core/client/LICENSE.txt +23 -0
- data/bridge/sdk-core/client/src/lib.rs +1286 -0
- data/bridge/sdk-core/client/src/metrics.rs +165 -0
- data/bridge/sdk-core/client/src/raw.rs +932 -0
- data/bridge/sdk-core/client/src/retry.rs +751 -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 +76 -0
- data/bridge/sdk-core/core/src/abstractions.rs +166 -0
- data/bridge/sdk-core/core/src/core_tests/activity_tasks.rs +1014 -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 +925 -0
- data/bridge/sdk-core/core/src/core_tests/mod.rs +100 -0
- data/bridge/sdk-core/core/src/core_tests/queries.rs +894 -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 +2090 -0
- data/bridge/sdk-core/core/src/ephemeral_server/mod.rs +515 -0
- data/bridge/sdk-core/core/src/lib.rs +282 -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 +215 -0
- data/bridge/sdk-core/core/src/retry_logic.rs +202 -0
- data/bridge/sdk-core/core/src/telemetry/log_export.rs +190 -0
- data/bridge/sdk-core/core/src/telemetry/metrics.rs +428 -0
- data/bridge/sdk-core/core/src/telemetry/mod.rs +407 -0
- data/bridge/sdk-core/core/src/telemetry/prometheus_server.rs +78 -0
- data/bridge/sdk-core/core/src/test_help/mod.rs +889 -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 +1048 -0
- data/bridge/sdk-core/core/src/worker/activities.rs +481 -0
- data/bridge/sdk-core/core/src/worker/client/mocks.rs +87 -0
- data/bridge/sdk-core/core/src/worker/client.rs +373 -0
- data/bridge/sdk-core/core/src/worker/mod.rs +570 -0
- data/bridge/sdk-core/core/src/worker/workflow/bridge.rs +37 -0
- data/bridge/sdk-core/core/src/worker/workflow/driven_workflow.rs +101 -0
- data/bridge/sdk-core/core/src/worker/workflow/history_update.rs +532 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +907 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +294 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +167 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +858 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +136 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +157 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +129 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +1450 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/mod.rs +316 -0
- 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 +708 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +439 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +435 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +175 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +242 -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 +1200 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +272 -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 +655 -0
- data/bridge/sdk-core/core/src/worker/workflow/mod.rs +1200 -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 +985 -0
- data/bridge/sdk-core/core-api/Cargo.toml +32 -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 +109 -0
- data/bridge/sdk-core/core-api/src/telemetry.rs +147 -0
- data/bridge/sdk-core/core-api/src/worker.rs +148 -0
- data/bridge/sdk-core/etc/deps.svg +162 -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/etc/regen-depgraph.sh +5 -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/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/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 +9 -0
- 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/build/tools.go +29 -0
- data/bridge/sdk-core/protos/api_upstream/dependencies/gogoproto/gogo.proto +141 -0
- data/bridge/sdk-core/protos/api_upstream/go.mod +6 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +89 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +260 -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 +47 -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 +56 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +170 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +118 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/interaction_type.proto +39 -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 +40 -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 +758 -0
- 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 +97 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +121 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +80 -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 +379 -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/version/v1/message.proto +59 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +146 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +1168 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +415 -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/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 +263 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +304 -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/interceptors.rs +50 -0
- data/bridge/sdk-core/sdk/src/lib.rs +794 -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 +694 -0
- data/bridge/sdk-core/sdk/src/workflow_future.rs +499 -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 +107 -0
- data/bridge/sdk-core/sdk-core-protos/src/constants.rs +7 -0
- data/bridge/sdk-core/sdk-core-protos/src/history_builder.rs +544 -0
- data/bridge/sdk-core/sdk-core-protos/src/history_info.rs +230 -0
- data/bridge/sdk-core/sdk-core-protos/src/lib.rs +1970 -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 +36 -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 +650 -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 +221 -0
- data/bridge/sdk-core/tests/integ_tests/metrics_tests.rs +37 -0
- data/bridge/sdk-core/tests/integ_tests/polling_tests.rs +133 -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 +788 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +53 -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 +223 -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 +597 -0
- data/bridge/sdk-core/tests/load_tests.rs +191 -0
- data/bridge/sdk-core/tests/main.rs +113 -0
- data/bridge/sdk-core/tests/runner.rs +93 -0
- data/bridge/src/connection.rs +186 -0
- data/bridge/src/lib.rs +239 -0
- data/bridge/src/runtime.rs +54 -0
- data/bridge/src/worker.rs +124 -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 +50 -0
- data/lib/gen/temporal/api/command/v1/message_pb.rb +174 -0
- data/lib/gen/temporal/api/common/v1/message_pb.rb +69 -0
- data/lib/gen/temporal/api/enums/v1/batch_operation_pb.rb +33 -0
- data/lib/gen/temporal/api/enums/v1/command_type_pb.rb +39 -0
- data/lib/gen/temporal/api/enums/v1/common_pb.rb +42 -0
- data/lib/gen/temporal/api/enums/v1/event_type_pb.rb +68 -0
- data/lib/gen/temporal/api/enums/v1/failed_cause_pb.rb +77 -0
- data/lib/gen/temporal/api/enums/v1/interaction_type_pb.rb +25 -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 +23 -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 +490 -0
- data/lib/gen/temporal/api/interaction/v1/message_pb.rb +49 -0
- data/lib/gen/temporal/api/namespace/v1/message_pb.rb +63 -0
- data/lib/gen/temporal/api/operatorservice/v1/request_response_pb.rb +85 -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 +149 -0
- data/lib/gen/temporal/api/taskqueue/v1/message_pb.rb +73 -0
- data/lib/gen/temporal/api/version/v1/message_pb.rb +41 -0
- data/lib/gen/temporal/api/workflow/v1/message_pb.rb +111 -0
- data/lib/gen/temporal/api/workflowservice/v1/request_response_pb.rb +788 -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 +165 -0
- data/lib/gen/temporal/sdk/core/workflow_commands/workflow_commands_pb.rb +196 -0
- data/lib/gen/temporal/sdk/core/workflow_completion/workflow_completion_pb.rb +34 -0
- 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/temporalio/client/implementation.rb +340 -0
- data/lib/temporalio/client/workflow_handle.rb +243 -0
- data/lib/temporalio/client.rb +131 -0
- data/lib/temporalio/connection.rb +751 -0
- data/lib/temporalio/data_converter.rb +191 -0
- data/lib/temporalio/error/failure.rb +194 -0
- data/lib/temporalio/error/workflow_failure.rb +19 -0
- data/lib/temporalio/errors.rb +40 -0
- data/lib/temporalio/failure_converter/base.rb +26 -0
- data/lib/temporalio/failure_converter/basic.rb +319 -0
- data/lib/temporalio/failure_converter.rb +7 -0
- data/lib/temporalio/interceptor/chain.rb +28 -0
- data/lib/temporalio/interceptor/client.rb +123 -0
- data/lib/temporalio/payload_codec/base.rb +32 -0
- data/lib/temporalio/payload_converter/base.rb +24 -0
- data/lib/temporalio/payload_converter/bytes.rb +27 -0
- data/lib/temporalio/payload_converter/composite.rb +49 -0
- data/lib/temporalio/payload_converter/encoding_base.rb +35 -0
- data/lib/temporalio/payload_converter/json.rb +26 -0
- data/lib/temporalio/payload_converter/nil.rb +26 -0
- data/lib/temporalio/payload_converter.rb +14 -0
- data/lib/temporalio/retry_policy.rb +82 -0
- data/lib/temporalio/retry_state.rb +35 -0
- data/lib/temporalio/runtime.rb +25 -0
- data/lib/temporalio/timeout_type.rb +29 -0
- 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/temporalio/workflow/execution_info.rb +54 -0
- data/lib/temporalio/workflow/execution_status.rb +36 -0
- data/lib/temporalio/workflow/id_reuse_policy.rb +36 -0
- data/lib/temporalio/workflow/query_reject_condition.rb +33 -0
- data/lib/temporalio.rb +12 -1
- data/lib/thermite_patch.rb +23 -0
- data/temporalio.gemspec +45 -0
- metadata +566 -9
- data/lib/temporal/version.rb +0 -3
- data/lib/temporal.rb +0 -4
- data/temporal.gemspec +0 -20
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'temporalio/payload_converter/encoding_base'
|
|
2
|
+
|
|
3
|
+
module Temporalio
|
|
4
|
+
module PayloadConverter
|
|
5
|
+
# A payload converter for encoding/decoding nils.
|
|
6
|
+
class Nil < EncodingBase
|
|
7
|
+
ENCODING = 'binary/null'.freeze
|
|
8
|
+
|
|
9
|
+
def encoding
|
|
10
|
+
ENCODING
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def from_payload(_payload)
|
|
14
|
+
nil
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def to_payload(data)
|
|
18
|
+
return nil unless data.nil?
|
|
19
|
+
|
|
20
|
+
Temporalio::Api::Common::V1::Payload.new(
|
|
21
|
+
metadata: { 'encoding' => ENCODING },
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'temporalio/payload_converter/bytes'
|
|
2
|
+
require 'temporalio/payload_converter/composite'
|
|
3
|
+
require 'temporalio/payload_converter/json'
|
|
4
|
+
require 'temporalio/payload_converter/nil'
|
|
5
|
+
|
|
6
|
+
module Temporalio
|
|
7
|
+
module PayloadConverter
|
|
8
|
+
DEFAULT = Temporalio::PayloadConverter::Composite.new(
|
|
9
|
+
Temporalio::PayloadConverter::Nil.new,
|
|
10
|
+
Temporalio::PayloadConverter::Bytes.new,
|
|
11
|
+
Temporalio::PayloadConverter::JSON.new,
|
|
12
|
+
)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
require 'temporal/api/common/v1/message_pb'
|
|
2
|
+
require 'temporalio/errors'
|
|
3
|
+
|
|
4
|
+
module Temporalio
|
|
5
|
+
# Options for retrying workflows and activities.
|
|
6
|
+
#
|
|
7
|
+
# @see https://docs.temporal.io/application-development/features/#workflow-retry-policy
|
|
8
|
+
class RetryPolicy
|
|
9
|
+
class Invalid < Temporalio::Error; end
|
|
10
|
+
|
|
11
|
+
# @return [Integer] Backoff interval for the first retry.
|
|
12
|
+
attr_reader :initial_interval
|
|
13
|
+
|
|
14
|
+
# @return [Float] Coefficient to multiply previous backoff interval by to get new interval.
|
|
15
|
+
attr_reader :backoff
|
|
16
|
+
|
|
17
|
+
# @return [Integer, nil] Maximum backoff interval between retries. Default 100x
|
|
18
|
+
# {#initial_interval}.
|
|
19
|
+
attr_reader :max_interval
|
|
20
|
+
|
|
21
|
+
# @return [Integer] Maximum number of attempts. If 0, the default, there is no maximum.
|
|
22
|
+
attr_reader :max_attempts
|
|
23
|
+
|
|
24
|
+
# @return [Array<String>] List of error types that are not retryable.
|
|
25
|
+
attr_reader :non_retriable_errors
|
|
26
|
+
|
|
27
|
+
# @param initial_interval [Integer] Backoff interval (in seconds) for the first retry.
|
|
28
|
+
# @param backoff [Float] Coefficient to multiply previous backoff interval by to get new
|
|
29
|
+
# interval.
|
|
30
|
+
# @param max_interval [Integer] Maximum backoff interval between retries. Default 100x
|
|
31
|
+
# {#initial_interval}.
|
|
32
|
+
# @param max_attempts [Integer] Maximum number of attempts. If 0, there is no maximum.
|
|
33
|
+
# @param non_retriable_errors [Array<String>] List of error types that are not retryable.
|
|
34
|
+
def initialize(
|
|
35
|
+
initial_interval: 1,
|
|
36
|
+
backoff: 2.0,
|
|
37
|
+
max_interval: nil,
|
|
38
|
+
max_attempts: 0,
|
|
39
|
+
non_retriable_errors: []
|
|
40
|
+
)
|
|
41
|
+
@initial_interval = initial_interval
|
|
42
|
+
@backoff = backoff
|
|
43
|
+
@max_interval = max_interval
|
|
44
|
+
@max_attempts = max_attempts
|
|
45
|
+
@non_retriable_errors = non_retriable_errors
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def validate!
|
|
49
|
+
# Retries disabled
|
|
50
|
+
return if max_attempts == 1
|
|
51
|
+
|
|
52
|
+
# Maximum attempts
|
|
53
|
+
raise Invalid, 'Maximum attempts must be specified' unless max_attempts
|
|
54
|
+
raise Invalid, 'Maximum attempts cannot be negative' if max_attempts.negative?
|
|
55
|
+
|
|
56
|
+
# Initial interval
|
|
57
|
+
raise Invalid, 'Initial interval must be specified' unless initial_interval
|
|
58
|
+
raise Invalid, 'Initial interval cannot be negative' if initial_interval.negative?
|
|
59
|
+
raise Invalid, 'Initial interval must be in whole seconds' unless initial_interval.is_a?(Integer)
|
|
60
|
+
|
|
61
|
+
# Backoff coefficient
|
|
62
|
+
raise Invalid, 'Backoff coefficient must be specified' unless backoff
|
|
63
|
+
raise Invalid, 'Backoff coefficient cannot be less than 1' if backoff < 1
|
|
64
|
+
|
|
65
|
+
# Maximum interval
|
|
66
|
+
if max_interval
|
|
67
|
+
raise Invalid, 'Maximum interval cannot be negative' if max_interval.negative?
|
|
68
|
+
raise Invalid, 'Maximum interval cannot be less than initial interval' if max_interval < initial_interval
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def to_proto
|
|
73
|
+
Temporalio::Api::Common::V1::RetryPolicy.new(
|
|
74
|
+
initial_interval: Google::Protobuf::Duration.new(seconds: initial_interval),
|
|
75
|
+
backoff_coefficient: backoff,
|
|
76
|
+
maximum_interval: max_interval ? Google::Protobuf::Duration.new(seconds: max_interval) : nil,
|
|
77
|
+
maximum_attempts: max_attempts,
|
|
78
|
+
non_retryable_error_types: non_retriable_errors.map(&:name).compact,
|
|
79
|
+
)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Temporalio
|
|
2
|
+
# Current retry state of the workflow/activity during error.
|
|
3
|
+
module RetryState
|
|
4
|
+
STATES = [
|
|
5
|
+
IN_PROGRESS = :IN_PROGRESS,
|
|
6
|
+
NON_RETRYABLE_FAILURE = :NON_RETRYABLE_FAILURE,
|
|
7
|
+
TIMEOUT = :TIMEOUT,
|
|
8
|
+
MAXIMUM_ATTEMPTS_REACHED = :MAXIMUM_ATTEMPTS_REACHED,
|
|
9
|
+
RETRY_POLICY_NOT_SET = :RETRY_POLICY_NOT_SET,
|
|
10
|
+
INTERNAL_SERVER_ERROR = :INTERNAL_SERVER_ERROR,
|
|
11
|
+
CANCEL_REQUESTED = :CANCEL_REQUESTED,
|
|
12
|
+
].freeze
|
|
13
|
+
|
|
14
|
+
# RBS screws up style definitions when using .freeze
|
|
15
|
+
# rubocop:disable Style/MutableConstant
|
|
16
|
+
API_MAP = {
|
|
17
|
+
RETRY_STATE_IN_PROGRESS: IN_PROGRESS,
|
|
18
|
+
RETRY_STATE_NON_RETRYABLE_FAILURE: NON_RETRYABLE_FAILURE,
|
|
19
|
+
RETRY_STATE_TIMEOUT: TIMEOUT,
|
|
20
|
+
RETRY_STATE_MAXIMUM_ATTEMPTS_REACHED: MAXIMUM_ATTEMPTS_REACHED,
|
|
21
|
+
RETRY_STATE_RETRY_POLICY_NOT_SET: RETRY_POLICY_NOT_SET,
|
|
22
|
+
RETRY_STATE_INTERNAL_SERVER_ERROR: INTERNAL_SERVER_ERROR,
|
|
23
|
+
RETRY_STATE_CANCEL_REQUESTED: CANCEL_REQUESTED,
|
|
24
|
+
}
|
|
25
|
+
# rubocop:enable Style/MutableConstant
|
|
26
|
+
|
|
27
|
+
def self.to_raw(state)
|
|
28
|
+
API_MAP.invert[state] || :RETRY_STATE_UNSPECIFIED
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.from_raw(raw_state)
|
|
32
|
+
API_MAP[raw_state]
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'singleton'
|
|
2
|
+
require 'temporalio/bridge'
|
|
3
|
+
require 'temporalio/worker/reactor'
|
|
4
|
+
|
|
5
|
+
module Temporalio
|
|
6
|
+
# @api private
|
|
7
|
+
class Runtime
|
|
8
|
+
include Singleton
|
|
9
|
+
|
|
10
|
+
attr_reader :core_runtime, :reactor
|
|
11
|
+
|
|
12
|
+
def initialize
|
|
13
|
+
@core_runtime = Temporalio::Bridge::Runtime.init
|
|
14
|
+
@reactor = Temporalio::Worker::Reactor.new
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def ensure_callback_loop
|
|
18
|
+
return if @thread
|
|
19
|
+
|
|
20
|
+
@thread = Thread.new do
|
|
21
|
+
core_runtime.run_callback_loop
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Temporalio
|
|
2
|
+
# Type of timeout for {Temporalio::TimeoutError}.
|
|
3
|
+
module TimeoutType
|
|
4
|
+
TYPES = [
|
|
5
|
+
START_TO_CLOSE = :START_TO_CLOSE,
|
|
6
|
+
SCHEDULE_TO_START = :SCHEDULE_TO_START,
|
|
7
|
+
SCHEDULE_TO_CLOSE = :SCHEDULE_TO_CLOSE,
|
|
8
|
+
HEARTBEAT = :HEARTBEAT,
|
|
9
|
+
].freeze
|
|
10
|
+
|
|
11
|
+
# RBS screws up style definitions when using .freeze
|
|
12
|
+
# rubocop:disable Style/MutableConstant
|
|
13
|
+
API_MAP = {
|
|
14
|
+
TIMEOUT_TYPE_START_TO_CLOSE: START_TO_CLOSE,
|
|
15
|
+
TIMEOUT_TYPE_SCHEDULE_TO_START: SCHEDULE_TO_START,
|
|
16
|
+
TIMEOUT_TYPE_SCHEDULE_TO_CLOSE: SCHEDULE_TO_CLOSE,
|
|
17
|
+
TIMEOUT_TYPE_HEARTBEAT: HEARTBEAT,
|
|
18
|
+
}
|
|
19
|
+
# rubocop:enable Style/MutableConstant
|
|
20
|
+
|
|
21
|
+
def self.to_raw(type)
|
|
22
|
+
API_MAP.invert[type] || :TIMEOUT_TYPE_UNSPECIFIED
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.from_raw(raw_type)
|
|
26
|
+
API_MAP[raw_type]
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
require 'google/protobuf/well_known_types'
|
|
2
|
+
require 'temporalio/activity/context'
|
|
3
|
+
require 'temporalio/activity/info'
|
|
4
|
+
require 'temporalio/error/failure'
|
|
5
|
+
require 'temporalio/errors'
|
|
6
|
+
|
|
7
|
+
module Temporalio
|
|
8
|
+
class Worker
|
|
9
|
+
# The main class for handling activity processing. It is expected to be executed from
|
|
10
|
+
# some threaded or async executor's context since methods called here might be blocking
|
|
11
|
+
# and this should not affect the main worker reactor.
|
|
12
|
+
#
|
|
13
|
+
# @api private
|
|
14
|
+
class ActivityRunner
|
|
15
|
+
def initialize(activity_class, start, task_queue, task_token, worker, converter)
|
|
16
|
+
@activity_class = activity_class
|
|
17
|
+
@start = start
|
|
18
|
+
@task_queue = task_queue
|
|
19
|
+
@task_token = task_token
|
|
20
|
+
@worker = worker
|
|
21
|
+
@converter = converter
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def run
|
|
25
|
+
activity = activity_class.new(context)
|
|
26
|
+
input = converter.from_payload_array(start.input.to_a)
|
|
27
|
+
|
|
28
|
+
result = activity.execute(*input)
|
|
29
|
+
|
|
30
|
+
converter.to_payload(result)
|
|
31
|
+
rescue StandardError => e
|
|
32
|
+
# Temporal server ignores cancellation failures that were not requested by the server.
|
|
33
|
+
# However within the SDK cancellations are also used during the worker shutdown. In order
|
|
34
|
+
# to provide a seamless handling experience (same error raised within the Activity) we are
|
|
35
|
+
# using the ActivityCancelled error and then swapping it with a CancelledError here.
|
|
36
|
+
#
|
|
37
|
+
# In the future this will be handled by the SDK Core — https://github.com/temporalio/sdk-core/issues/461
|
|
38
|
+
if e.is_a?(Temporalio::Error::ActivityCancelled) && e.by_request?
|
|
39
|
+
e = Temporalio::Error::CancelledError.new(e.message)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
converter.to_failure(e)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def cancel(reason, by_request:)
|
|
46
|
+
context.cancel(reason, by_request: by_request)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
attr_reader :activity_class, :start, :task_queue, :task_token, :worker, :converter
|
|
52
|
+
|
|
53
|
+
def context
|
|
54
|
+
return @context if @context
|
|
55
|
+
|
|
56
|
+
heartbeat_proc = ->(*details) { heartbeat(*details) }
|
|
57
|
+
@context = Temporalio::Activity::Context.new(
|
|
58
|
+
generate_activity_info,
|
|
59
|
+
heartbeat_proc,
|
|
60
|
+
shielded: activity_class._shielded,
|
|
61
|
+
)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def generate_activity_info
|
|
65
|
+
Temporalio::Activity::Info.new(
|
|
66
|
+
activity_id: start.activity_id,
|
|
67
|
+
activity_type: start.activity_type,
|
|
68
|
+
attempt: start.attempt,
|
|
69
|
+
current_attempt_scheduled_time: start.current_attempt_scheduled_time&.to_time,
|
|
70
|
+
heartbeat_details: converter.from_payload_array(start.heartbeat_details.to_a),
|
|
71
|
+
heartbeat_timeout: start.heartbeat_timeout&.to_f,
|
|
72
|
+
local: !start.is_local.nil?,
|
|
73
|
+
schedule_to_close_timeout: start.schedule_to_close_timeout&.to_f,
|
|
74
|
+
scheduled_time: start.scheduled_time&.to_time,
|
|
75
|
+
start_to_close_timeout: start.start_to_close_timeout&.to_f,
|
|
76
|
+
started_time: start.started_time&.to_time,
|
|
77
|
+
task_queue: task_queue,
|
|
78
|
+
task_token: task_token,
|
|
79
|
+
workflow_id: start.workflow_execution&.workflow_id,
|
|
80
|
+
workflow_namespace: start.workflow_namespace,
|
|
81
|
+
workflow_run_id: start.workflow_execution&.run_id,
|
|
82
|
+
workflow_type: start.workflow_type,
|
|
83
|
+
).freeze
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def heartbeat(*details)
|
|
87
|
+
payloads = converter.to_payload_array(details)
|
|
88
|
+
worker.record_activity_heartbeat(task_token, payloads)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
require 'temporalio/error/failure'
|
|
2
|
+
require 'temporalio/errors'
|
|
3
|
+
require 'temporalio/worker/activity_runner'
|
|
4
|
+
require 'temporalio/worker/sync_worker'
|
|
5
|
+
|
|
6
|
+
module Temporalio
|
|
7
|
+
class Worker
|
|
8
|
+
# @api private
|
|
9
|
+
class ActivityWorker
|
|
10
|
+
def initialize(task_queue, core_worker, activities, converter, executor, graceful_timeout)
|
|
11
|
+
@task_queue = task_queue
|
|
12
|
+
@worker = SyncWorker.new(core_worker)
|
|
13
|
+
@activities = prepare_activities(activities)
|
|
14
|
+
@converter = converter
|
|
15
|
+
@executor = executor
|
|
16
|
+
@graceful_timeout = graceful_timeout
|
|
17
|
+
@running_activities = {}
|
|
18
|
+
@cancellations = []
|
|
19
|
+
@drain_queue = Queue.new
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def run(reactor)
|
|
23
|
+
# @type var outstanding_tasks: Array[Async::Task]
|
|
24
|
+
outstanding_tasks = []
|
|
25
|
+
|
|
26
|
+
loop do
|
|
27
|
+
activity_task = worker.poll_activity_task
|
|
28
|
+
outstanding_tasks << reactor.async do |async_task|
|
|
29
|
+
if activity_task.start
|
|
30
|
+
handle_start_activity(activity_task.task_token, activity_task.start)
|
|
31
|
+
elsif activity_task.cancel
|
|
32
|
+
handle_cancel_activity(activity_task.task_token, activity_task.cancel)
|
|
33
|
+
end
|
|
34
|
+
ensure
|
|
35
|
+
outstanding_tasks.delete(async_task)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
rescue Temporalio::Bridge::Error::WorkerShutdown
|
|
39
|
+
# No need to re-raise this error, it's a part of a normal shutdown
|
|
40
|
+
ensure
|
|
41
|
+
reactor.async do |async_task|
|
|
42
|
+
cancelation_task =
|
|
43
|
+
if graceful_timeout
|
|
44
|
+
async_task.async do
|
|
45
|
+
sleep graceful_timeout
|
|
46
|
+
running_activities.each_value do |activity_runner|
|
|
47
|
+
activity_runner.cancel('Worker is shutting down', by_request: false)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
outstanding_tasks.each(&:wait)
|
|
53
|
+
cancelation_task&.stop # all tasks completed, stop cancellations
|
|
54
|
+
drain_queue.close
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def drain
|
|
59
|
+
drain_queue.pop
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
attr_reader :task_queue, :worker, :activities, :converter, :executor, :graceful_timeout,
|
|
65
|
+
:running_activities, :cancellations, :drain_queue
|
|
66
|
+
|
|
67
|
+
def prepare_activities(activities)
|
|
68
|
+
activities.each_with_object({}) do |activity, result|
|
|
69
|
+
unless activity.ancestors.include?(Temporalio::Activity)
|
|
70
|
+
raise ArgumentError, 'Activity must be a subclass of Temporalio::Activity'
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
if result[activity._name]
|
|
74
|
+
raise ArgumentError, "More than one activity named #{activity._name}"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
result[activity._name] = activity
|
|
78
|
+
result
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def lookup_activity(activity_type)
|
|
83
|
+
activities.fetch(activity_type) do
|
|
84
|
+
activity_names = activities.keys.sort.join(', ')
|
|
85
|
+
raise Temporalio::Error::ApplicationError.new(
|
|
86
|
+
"Activity #{activity_type} is not registered on this worker, available activities: #{activity_names}",
|
|
87
|
+
type: 'NotFoundError',
|
|
88
|
+
)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def run_activity(token, start)
|
|
93
|
+
activity_class = lookup_activity(start.activity_type)
|
|
94
|
+
runner = ActivityRunner.new(activity_class, start, task_queue, token, worker, converter)
|
|
95
|
+
running_activities[token] = runner
|
|
96
|
+
queue = Queue.new
|
|
97
|
+
|
|
98
|
+
executor.schedule do
|
|
99
|
+
queue << runner.run
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
queue.pop
|
|
103
|
+
rescue StandardError => e
|
|
104
|
+
converter.to_failure(e)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def handle_start_activity(task_token, start)
|
|
108
|
+
result = run_activity(task_token, start)
|
|
109
|
+
|
|
110
|
+
case result
|
|
111
|
+
when Temporalio::Api::Common::V1::Payload
|
|
112
|
+
worker.complete_activity_task_with_success(task_token, result)
|
|
113
|
+
when Temporalio::Api::Failure::V1::Failure
|
|
114
|
+
# only respond with a cancellation when it was requested, otherwise it's a regular failure
|
|
115
|
+
if result.canceled_failure_info && cancellations.include?(task_token)
|
|
116
|
+
worker.complete_activity_task_with_cancellation(task_token, result)
|
|
117
|
+
else
|
|
118
|
+
worker.complete_activity_task_with_failure(task_token, result)
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
running_activities.delete(task_token)
|
|
123
|
+
cancellations.delete(task_token)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def handle_cancel_activity(task_token, _cancel)
|
|
127
|
+
runner = running_activities.fetch(task_token) do
|
|
128
|
+
# TODO: Use logger instead when implemented
|
|
129
|
+
warn "Cannot find activity to cancel for token #{task_token}"
|
|
130
|
+
return # early escape
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
cancellations << task_token
|
|
134
|
+
runner&.cancel('Activity cancellation requested', by_request: true)
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'async'
|
|
2
|
+
|
|
3
|
+
module Temporalio
|
|
4
|
+
class Worker
|
|
5
|
+
# A shared async reactor.
|
|
6
|
+
#
|
|
7
|
+
# This class allows multiple workers to access the same Async reactor
|
|
8
|
+
# without forcing the SDK users to wrap their execution in an Async block. This
|
|
9
|
+
# is handled using a queue that is polled from within a running Async reactor,
|
|
10
|
+
# so all the blocks end up being executed within it.
|
|
11
|
+
#
|
|
12
|
+
# @api private
|
|
13
|
+
class Reactor
|
|
14
|
+
def initialize
|
|
15
|
+
@queue = Queue.new
|
|
16
|
+
@thread = nil
|
|
17
|
+
@mutex = Mutex.new
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def async(&block)
|
|
21
|
+
ensure_reactor_thread
|
|
22
|
+
queue << block
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
attr_reader :queue, :mutex
|
|
28
|
+
|
|
29
|
+
def ensure_reactor_thread
|
|
30
|
+
mutex.synchronize do
|
|
31
|
+
@thread ||= Thread.new { run_loop }
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def run_loop
|
|
36
|
+
reactor = Async::Reactor.new
|
|
37
|
+
reactor.run do |task|
|
|
38
|
+
loop do
|
|
39
|
+
block = queue.pop
|
|
40
|
+
task.async { |subtask| block.call(subtask) }
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require 'temporalio/errors'
|
|
2
|
+
|
|
3
|
+
module Temporalio
|
|
4
|
+
class Worker
|
|
5
|
+
# A class used to manage the lifecycle of running any number of workers.
|
|
6
|
+
#
|
|
7
|
+
# @api private
|
|
8
|
+
class Runner
|
|
9
|
+
def initialize(*workers)
|
|
10
|
+
if workers.empty?
|
|
11
|
+
raise ArgumentError, 'Must be initialized with at least one worker'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
@workers = workers
|
|
15
|
+
@mutex = Mutex.new
|
|
16
|
+
@started = false
|
|
17
|
+
@shutdown = false
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def run(&block)
|
|
21
|
+
@thread = Thread.current
|
|
22
|
+
@started = true
|
|
23
|
+
workers.each { |worker| worker.start(self) }
|
|
24
|
+
|
|
25
|
+
block ? block.call : sleep
|
|
26
|
+
rescue Temporalio::Error::WorkerShutdown
|
|
27
|
+
# Explicit shutdown requested, no need to raise
|
|
28
|
+
ensure
|
|
29
|
+
@shutdown = true
|
|
30
|
+
shutdown_workers
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def shutdown(exception = Temporalio::Error::WorkerShutdown.new('Manual shutdown'))
|
|
34
|
+
mutex.synchronize do
|
|
35
|
+
return unless running?
|
|
36
|
+
|
|
37
|
+
@shutdown = true
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# propagate shutdown to the running thread
|
|
41
|
+
thread&.raise(exception)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
attr_reader :workers, :mutex, :thread
|
|
47
|
+
|
|
48
|
+
def running?
|
|
49
|
+
@started && !@shutdown
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def shutdown_workers
|
|
53
|
+
# Protect shutdown from any outside raises
|
|
54
|
+
Thread.handle_interrupt(StandardError => :never) do
|
|
55
|
+
workers.map do |worker|
|
|
56
|
+
# Shut down each worker (and wait for it) concurrently in separate threads
|
|
57
|
+
Thread.new { worker.shutdown }
|
|
58
|
+
end.each(&:join)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
require 'temporal/sdk/core/activity_task/activity_task_pb'
|
|
2
|
+
require 'temporal/sdk/core/core_interface_pb'
|
|
3
|
+
|
|
4
|
+
module Temporalio
|
|
5
|
+
class Worker
|
|
6
|
+
# This is a wrapper class for the Core Worker (provided via the Bridge) to abstract
|
|
7
|
+
# away its async nature allowing other modules/classes to interact with it without
|
|
8
|
+
# any callbacks (simplifying the code).
|
|
9
|
+
#
|
|
10
|
+
# CAUTION: This class will block the thread its running in unless it is used from
|
|
11
|
+
# within an Async reactor.
|
|
12
|
+
#
|
|
13
|
+
# @api private
|
|
14
|
+
class SyncWorker
|
|
15
|
+
def initialize(core_worker)
|
|
16
|
+
@core_worker = core_worker
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def poll_activity_task
|
|
20
|
+
with_queue do |done|
|
|
21
|
+
core_worker.poll_activity_task do |task, error|
|
|
22
|
+
done.call(task && Coresdk::ActivityTask::ActivityTask.decode(task), error)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def complete_activity_task_with_success(task_token, payload)
|
|
28
|
+
result = Coresdk::ActivityResult::ActivityExecutionResult.new(
|
|
29
|
+
completed: Coresdk::ActivityResult::Success.new(result: payload),
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
complete_activity_task(task_token, result)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def complete_activity_task_with_failure(task_token, failure)
|
|
36
|
+
result = Coresdk::ActivityResult::ActivityExecutionResult.new(
|
|
37
|
+
failed: Coresdk::ActivityResult::Failure.new(failure: failure),
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
complete_activity_task(task_token, result)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def complete_activity_task_with_cancellation(task_token, failure)
|
|
44
|
+
result = Coresdk::ActivityResult::ActivityExecutionResult.new(
|
|
45
|
+
cancelled: Coresdk::ActivityResult::Cancellation.new(failure: failure),
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
complete_activity_task(task_token, result)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def record_activity_heartbeat(task_token, payloads)
|
|
52
|
+
proto = Coresdk::ActivityHeartbeat.new(
|
|
53
|
+
task_token: task_token,
|
|
54
|
+
details: payloads,
|
|
55
|
+
)
|
|
56
|
+
encoded_proto = Coresdk::ActivityHeartbeat.encode(proto)
|
|
57
|
+
|
|
58
|
+
core_worker.record_activity_heartbeat(encoded_proto)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
attr_reader :core_worker
|
|
64
|
+
|
|
65
|
+
def with_queue(&block)
|
|
66
|
+
queue = Queue.new
|
|
67
|
+
done = ->(result, error = nil) { queue << [result, error] }
|
|
68
|
+
block.call(done)
|
|
69
|
+
(result, exception) = queue.pop
|
|
70
|
+
raise exception if exception
|
|
71
|
+
|
|
72
|
+
result
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def complete_activity_task(task_token, result)
|
|
76
|
+
proto = Coresdk::ActivityTaskCompletion.new(
|
|
77
|
+
task_token: task_token,
|
|
78
|
+
result: result,
|
|
79
|
+
)
|
|
80
|
+
encoded_proto = Coresdk::ActivityTaskCompletion.encode(proto)
|
|
81
|
+
|
|
82
|
+
with_queue do |done|
|
|
83
|
+
core_worker.complete_activity_task(encoded_proto, &done)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|