temporalio 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +180 -7
- data/bridge/Cargo.lock +208 -76
- data/bridge/Cargo.toml +5 -2
- data/bridge/sdk-core/Cargo.toml +1 -1
- data/bridge/sdk-core/README.md +20 -10
- data/bridge/sdk-core/client/Cargo.toml +1 -1
- data/bridge/sdk-core/client/src/lib.rs +227 -59
- data/bridge/sdk-core/client/src/metrics.rs +17 -8
- data/bridge/sdk-core/client/src/raw.rs +13 -12
- data/bridge/sdk-core/client/src/retry.rs +132 -43
- data/bridge/sdk-core/core/Cargo.toml +28 -15
- data/bridge/sdk-core/core/benches/workflow_replay.rs +13 -10
- data/bridge/sdk-core/core/src/abstractions.rs +225 -36
- data/bridge/sdk-core/core/src/core_tests/activity_tasks.rs +217 -79
- data/bridge/sdk-core/core/src/core_tests/determinism.rs +165 -2
- data/bridge/sdk-core/core/src/core_tests/local_activities.rs +565 -34
- data/bridge/sdk-core/core/src/core_tests/queries.rs +247 -90
- data/bridge/sdk-core/core/src/core_tests/workers.rs +3 -5
- data/bridge/sdk-core/core/src/core_tests/workflow_cancels.rs +1 -1
- data/bridge/sdk-core/core/src/core_tests/workflow_tasks.rs +430 -67
- data/bridge/sdk-core/core/src/ephemeral_server/mod.rs +106 -12
- data/bridge/sdk-core/core/src/internal_flags.rs +136 -0
- data/bridge/sdk-core/core/src/lib.rs +148 -34
- data/bridge/sdk-core/core/src/protosext/mod.rs +1 -1
- data/bridge/sdk-core/core/src/replay/mod.rs +185 -41
- data/bridge/sdk-core/core/src/telemetry/log_export.rs +190 -0
- data/bridge/sdk-core/core/src/telemetry/metrics.rs +219 -140
- data/bridge/sdk-core/core/src/telemetry/mod.rs +326 -315
- data/bridge/sdk-core/core/src/telemetry/prometheus_server.rs +20 -14
- data/bridge/sdk-core/core/src/test_help/mod.rs +85 -21
- data/bridge/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +112 -156
- data/bridge/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +89 -0
- data/bridge/sdk-core/core/src/worker/activities/local_activities.rs +364 -128
- data/bridge/sdk-core/core/src/worker/activities.rs +263 -170
- data/bridge/sdk-core/core/src/worker/client/mocks.rs +23 -3
- data/bridge/sdk-core/core/src/worker/client.rs +48 -6
- data/bridge/sdk-core/core/src/worker/mod.rs +186 -75
- data/bridge/sdk-core/core/src/worker/workflow/bridge.rs +1 -3
- data/bridge/sdk-core/core/src/worker/workflow/driven_workflow.rs +13 -24
- data/bridge/sdk-core/core/src/worker/workflow/history_update.rs +879 -226
- data/bridge/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +101 -48
- data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +8 -12
- data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +6 -9
- data/bridge/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +90 -32
- data/bridge/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +6 -9
- data/bridge/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +7 -10
- data/bridge/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +6 -9
- data/bridge/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +160 -83
- data/bridge/sdk-core/core/src/worker/workflow/machines/mod.rs +36 -54
- data/bridge/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +179 -0
- data/bridge/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +104 -157
- data/bridge/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +8 -12
- data/bridge/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +9 -13
- data/bridge/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +10 -4
- data/bridge/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +14 -11
- data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +6 -17
- data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +395 -299
- data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +12 -20
- data/bridge/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +33 -18
- data/bridge/sdk-core/core/src/worker/workflow/managed_run.rs +1032 -374
- data/bridge/sdk-core/core/src/worker/workflow/mod.rs +525 -392
- data/bridge/sdk-core/core/src/worker/workflow/run_cache.rs +40 -57
- data/bridge/sdk-core/core/src/worker/workflow/wft_extraction.rs +125 -0
- data/bridge/sdk-core/core/src/worker/workflow/wft_poller.rs +3 -6
- data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +117 -0
- data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +24 -0
- data/bridge/sdk-core/core/src/worker/workflow/workflow_stream.rs +456 -681
- data/bridge/sdk-core/core-api/Cargo.toml +6 -4
- data/bridge/sdk-core/core-api/src/errors.rs +1 -34
- data/bridge/sdk-core/core-api/src/lib.rs +7 -45
- data/bridge/sdk-core/core-api/src/telemetry.rs +141 -0
- data/bridge/sdk-core/core-api/src/worker.rs +27 -1
- data/bridge/sdk-core/etc/deps.svg +115 -140
- data/bridge/sdk-core/etc/regen-depgraph.sh +5 -0
- data/bridge/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +18 -15
- data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +1 -1
- data/bridge/sdk-core/fsm/rustfsm_trait/src/lib.rs +8 -3
- data/bridge/sdk-core/histories/evict_while_la_running_no_interference-16_history.bin +0 -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/protos/api_upstream/buf.yaml +0 -3
- data/bridge/sdk-core/protos/api_upstream/build/go.mod +7 -0
- data/bridge/sdk-core/protos/api_upstream/build/go.sum +5 -0
- data/bridge/sdk-core/protos/api_upstream/{temporal/api/enums/v1/cluster.proto → build/tools.go} +7 -18
- data/bridge/sdk-core/protos/api_upstream/go.mod +6 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +12 -9
- data/bridge/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +15 -26
- data/bridge/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +13 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +3 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +4 -9
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +3 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +10 -8
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +28 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/query.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +24 -19
- data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/filter/v1/message.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +62 -26
- data/bridge/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +4 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +24 -61
- data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +2 -21
- data/bridge/sdk-core/protos/api_upstream/temporal/api/protocol/v1/message.proto +57 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +110 -31
- data/bridge/sdk-core/protos/api_upstream/temporal/api/sdk/v1/task_complete_metadata.proto +63 -0
- data/bridge/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +4 -4
- data/bridge/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +71 -6
- data/bridge/sdk-core/protos/api_upstream/temporal/api/version/v1/message.proto +2 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +3 -2
- data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +111 -36
- data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +19 -5
- data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +1 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +1 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +1 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/common/common.proto +1 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +1 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +1 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +9 -0
- data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +9 -1
- data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +6 -0
- data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +2 -2
- data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +2 -2
- data/bridge/sdk-core/sdk/Cargo.toml +4 -3
- data/bridge/sdk-core/sdk/src/interceptors.rs +36 -3
- data/bridge/sdk-core/sdk/src/lib.rs +94 -25
- data/bridge/sdk-core/sdk/src/workflow_context.rs +13 -2
- data/bridge/sdk-core/sdk/src/workflow_future.rs +10 -13
- data/bridge/sdk-core/sdk-core-protos/Cargo.toml +5 -2
- data/bridge/sdk-core/sdk-core-protos/build.rs +36 -2
- data/bridge/sdk-core/sdk-core-protos/src/history_builder.rs +164 -104
- data/bridge/sdk-core/sdk-core-protos/src/history_info.rs +27 -23
- data/bridge/sdk-core/sdk-core-protos/src/lib.rs +252 -74
- data/bridge/sdk-core/sdk-core-protos/src/task_token.rs +12 -2
- data/bridge/sdk-core/test-utils/Cargo.toml +4 -1
- data/bridge/sdk-core/test-utils/src/canned_histories.rs +106 -296
- data/bridge/sdk-core/test-utils/src/histfetch.rs +1 -1
- data/bridge/sdk-core/test-utils/src/lib.rs +161 -50
- data/bridge/sdk-core/test-utils/src/wf_input_saver.rs +50 -0
- data/bridge/sdk-core/test-utils/src/workflows.rs +29 -0
- data/bridge/sdk-core/tests/fuzzy_workflow.rs +130 -0
- data/bridge/sdk-core/tests/{load_tests.rs → heavy_tests.rs} +125 -51
- data/bridge/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +25 -3
- data/bridge/sdk-core/tests/integ_tests/heartbeat_tests.rs +10 -5
- data/bridge/sdk-core/tests/integ_tests/metrics_tests.rs +239 -0
- data/bridge/sdk-core/tests/integ_tests/polling_tests.rs +4 -60
- data/bridge/sdk-core/tests/integ_tests/queries_tests.rs +5 -128
- data/bridge/sdk-core/tests/integ_tests/visibility_tests.rs +83 -25
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/activities.rs +93 -69
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +6 -13
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +1 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +6 -2
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -10
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +151 -116
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +54 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/patches.rs +7 -28
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/replay.rs +115 -24
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -0
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/signals.rs +18 -14
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +6 -20
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/timers.rs +10 -21
- data/bridge/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +6 -4
- data/bridge/sdk-core/tests/integ_tests/workflow_tests.rs +27 -18
- data/bridge/sdk-core/tests/main.rs +8 -16
- data/bridge/sdk-core/tests/runner.rs +75 -36
- data/bridge/sdk-core/tests/wf_input_replay.rs +32 -0
- data/bridge/src/connection.rs +117 -82
- data/bridge/src/lib.rs +356 -42
- data/bridge/src/runtime.rs +10 -3
- data/bridge/src/test_server.rs +153 -0
- data/bridge/src/worker.rs +133 -9
- data/lib/gen/temporal/api/batch/v1/message_pb.rb +8 -6
- data/lib/gen/temporal/api/command/v1/message_pb.rb +10 -16
- data/lib/gen/temporal/api/common/v1/message_pb.rb +5 -1
- data/lib/gen/temporal/api/enums/v1/batch_operation_pb.rb +2 -1
- data/lib/gen/temporal/api/enums/v1/command_type_pb.rb +3 -3
- data/lib/gen/temporal/api/enums/v1/common_pb.rb +2 -1
- data/lib/gen/temporal/api/enums/v1/event_type_pb.rb +5 -4
- data/lib/gen/temporal/api/enums/v1/failed_cause_pb.rb +9 -1
- data/lib/gen/temporal/api/enums/v1/namespace_pb.rb +1 -1
- data/lib/gen/temporal/api/enums/v1/query_pb.rb +1 -1
- data/lib/gen/temporal/api/enums/v1/reset_pb.rb +1 -1
- data/lib/gen/temporal/api/enums/v1/schedule_pb.rb +1 -1
- data/lib/gen/temporal/api/enums/v1/task_queue_pb.rb +1 -1
- data/lib/gen/temporal/api/enums/v1/update_pb.rb +7 -10
- data/lib/gen/temporal/api/enums/v1/workflow_pb.rb +1 -1
- data/lib/gen/temporal/api/errordetails/v1/message_pb.rb +1 -1
- data/lib/gen/temporal/api/failure/v1/message_pb.rb +1 -1
- data/lib/gen/temporal/api/filter/v1/message_pb.rb +1 -1
- data/lib/gen/temporal/api/history/v1/message_pb.rb +34 -25
- data/lib/gen/temporal/api/namespace/v1/message_pb.rb +2 -1
- data/lib/gen/temporal/api/operatorservice/v1/request_response_pb.rb +14 -51
- data/lib/gen/temporal/api/operatorservice/v1/service_pb.rb +1 -1
- data/lib/gen/temporal/api/protocol/v1/message_pb.rb +30 -0
- data/lib/gen/temporal/api/query/v1/message_pb.rb +1 -1
- data/lib/gen/temporal/api/replication/v1/message_pb.rb +1 -1
- data/lib/gen/temporal/api/schedule/v1/message_pb.rb +22 -1
- data/lib/gen/temporal/api/sdk/v1/task_complete_metadata_pb.rb +23 -0
- data/lib/gen/temporal/api/taskqueue/v1/message_pb.rb +2 -2
- data/lib/gen/temporal/api/testservice/v1/request_response_pb.rb +49 -0
- data/lib/gen/temporal/api/testservice/v1/service_pb.rb +21 -0
- data/lib/gen/temporal/api/update/v1/message_pb.rb +49 -3
- data/lib/gen/temporal/api/version/v1/message_pb.rb +1 -1
- data/lib/gen/temporal/api/workflow/v1/message_pb.rb +2 -1
- data/lib/gen/temporal/api/workflowservice/v1/request_response_pb.rb +47 -20
- data/lib/gen/temporal/api/workflowservice/v1/service_pb.rb +1 -1
- data/lib/gen/temporal/sdk/core/activity_result/activity_result_pb.rb +13 -9
- data/lib/gen/temporal/sdk/core/activity_task/activity_task_pb.rb +10 -6
- data/lib/gen/temporal/sdk/core/child_workflow/child_workflow_pb.rb +13 -9
- data/lib/gen/temporal/sdk/core/common/common_pb.rb +7 -3
- data/lib/gen/temporal/sdk/core/core_interface_pb.rb +9 -3
- data/lib/gen/temporal/sdk/core/external_data/external_data_pb.rb +7 -3
- data/lib/gen/temporal/sdk/core/workflow_activation/workflow_activation_pb.rb +28 -21
- data/lib/gen/temporal/sdk/core/workflow_commands/workflow_commands_pb.rb +32 -24
- data/lib/gen/temporal/sdk/core/workflow_completion/workflow_completion_pb.rb +12 -5
- data/lib/temporalio/activity/context.rb +102 -0
- data/lib/temporalio/activity/info.rb +67 -0
- data/lib/temporalio/activity.rb +85 -0
- data/lib/temporalio/bridge/connect_options.rb +15 -0
- data/lib/temporalio/bridge/error.rb +8 -0
- data/lib/temporalio/bridge/retry_config.rb +24 -0
- data/lib/temporalio/bridge/tls_options.rb +19 -0
- data/lib/temporalio/bridge.rb +14 -0
- data/lib/{temporal → temporalio}/client/implementation.rb +57 -56
- data/lib/{temporal → temporalio}/client/workflow_handle.rb +35 -35
- data/lib/{temporal → temporalio}/client.rb +19 -32
- data/lib/temporalio/connection/retry_config.rb +44 -0
- data/lib/temporalio/connection/service.rb +20 -0
- data/lib/temporalio/connection/test_service.rb +92 -0
- data/lib/temporalio/connection/tls_options.rb +51 -0
- data/lib/temporalio/connection/workflow_service.rb +731 -0
- data/lib/temporalio/connection.rb +86 -0
- data/lib/{temporal → temporalio}/data_converter.rb +76 -35
- data/lib/{temporal → temporalio}/error/failure.rb +6 -6
- data/lib/{temporal → temporalio}/error/workflow_failure.rb +4 -2
- data/lib/{temporal → temporalio}/errors.rb +19 -1
- data/lib/{temporal → temporalio}/failure_converter/base.rb +5 -5
- data/lib/{temporal → temporalio}/failure_converter/basic.rb +58 -52
- data/lib/temporalio/failure_converter.rb +7 -0
- data/lib/temporalio/interceptor/activity_inbound.rb +22 -0
- data/lib/temporalio/interceptor/activity_outbound.rb +24 -0
- data/lib/{temporal → temporalio}/interceptor/chain.rb +7 -6
- data/lib/{temporal → temporalio}/interceptor/client.rb +27 -2
- data/lib/temporalio/interceptor.rb +22 -0
- data/lib/{temporal → temporalio}/payload_codec/base.rb +5 -5
- data/lib/{temporal → temporalio}/payload_converter/base.rb +3 -3
- data/lib/{temporal → temporalio}/payload_converter/bytes.rb +4 -3
- data/lib/{temporal → temporalio}/payload_converter/composite.rb +7 -5
- data/lib/{temporal → temporalio}/payload_converter/encoding_base.rb +4 -4
- data/lib/{temporal → temporalio}/payload_converter/json.rb +4 -3
- data/lib/{temporal → temporalio}/payload_converter/nil.rb +4 -3
- data/lib/temporalio/payload_converter.rb +14 -0
- data/lib/{temporal → temporalio}/retry_policy.rb +17 -7
- data/lib/{temporal → temporalio}/retry_state.rb +1 -1
- data/lib/temporalio/runtime.rb +25 -0
- data/lib/temporalio/testing/time_skipping_handle.rb +32 -0
- data/lib/temporalio/testing/time_skipping_interceptor.rb +23 -0
- data/lib/temporalio/testing/workflow_environment.rb +112 -0
- data/lib/temporalio/testing.rb +175 -0
- data/lib/{temporal → temporalio}/timeout_type.rb +2 -2
- data/lib/temporalio/version.rb +3 -0
- data/lib/temporalio/worker/activity_runner.rb +114 -0
- data/lib/temporalio/worker/activity_worker.rb +164 -0
- data/lib/temporalio/worker/reactor.rb +46 -0
- data/lib/temporalio/worker/runner.rb +63 -0
- data/lib/temporalio/worker/sync_worker.rb +124 -0
- data/lib/temporalio/worker/thread_pool_executor.rb +51 -0
- data/lib/temporalio/worker.rb +204 -0
- data/lib/temporalio/workflow/async.rb +46 -0
- data/lib/{temporal → temporalio}/workflow/execution_info.rb +4 -4
- data/lib/{temporal → temporalio}/workflow/execution_status.rb +1 -1
- data/lib/temporalio/workflow/future.rb +138 -0
- data/lib/{temporal → temporalio}/workflow/id_reuse_policy.rb +6 -6
- data/lib/temporalio/workflow/info.rb +76 -0
- data/lib/{temporal → temporalio}/workflow/query_reject_condition.rb +5 -5
- data/lib/temporalio.rb +12 -3
- data/temporalio.gemspec +11 -6
- metadata +137 -64
- data/bridge/sdk-core/Cargo.lock +0 -2606
- data/bridge/sdk-core/bridge-ffi/Cargo.toml +0 -24
- data/bridge/sdk-core/bridge-ffi/LICENSE.txt +0 -23
- data/bridge/sdk-core/bridge-ffi/build.rs +0 -25
- data/bridge/sdk-core/bridge-ffi/include/sdk-core-bridge.h +0 -249
- data/bridge/sdk-core/bridge-ffi/src/lib.rs +0 -825
- data/bridge/sdk-core/bridge-ffi/src/wrappers.rs +0 -211
- data/bridge/sdk-core/core/src/log_export.rs +0 -62
- data/bridge/sdk-core/core/src/worker/workflow/machines/mutable_side_effect_state_machine.rs +0 -127
- data/bridge/sdk-core/core/src/worker/workflow/machines/side_effect_state_machine.rs +0 -71
- data/bridge/sdk-core/protos/api_upstream/temporal/api/cluster/v1/message.proto +0 -83
- data/bridge/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +0 -210
- data/bridge/sdk-core/sdk/src/conversions.rs +0 -8
- data/lib/bridge.so +0 -0
- data/lib/gen/temporal/api/cluster/v1/message_pb.rb +0 -67
- data/lib/gen/temporal/api/enums/v1/cluster_pb.rb +0 -26
- data/lib/gen/temporal/sdk/core/bridge/bridge_pb.rb +0 -222
- data/lib/temporal/bridge.rb +0 -14
- data/lib/temporal/connection.rb +0 -736
- data/lib/temporal/failure_converter.rb +0 -8
- data/lib/temporal/payload_converter.rb +0 -14
- data/lib/temporal/runtime.rb +0 -22
- data/lib/temporal/version.rb +0 -3
- data/lib/temporal.rb +0 -8
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
require 'temporalio/bridge'
|
|
2
|
+
require 'temporalio/connection'
|
|
3
|
+
require 'temporalio/runtime'
|
|
4
|
+
require 'temporalio/testing/workflow_environment'
|
|
5
|
+
require 'temporalio/version'
|
|
6
|
+
|
|
7
|
+
module Temporalio
|
|
8
|
+
module Testing
|
|
9
|
+
DEFAULT_NAMESPACE = 'default'.freeze
|
|
10
|
+
|
|
11
|
+
class << self
|
|
12
|
+
# Start a full Temporal server locally, downloading if necessary.
|
|
13
|
+
#
|
|
14
|
+
# This environment is good for testing full server capabilities, but does not support time
|
|
15
|
+
# skipping like {.start_time_skipping} does.
|
|
16
|
+
# {Temporalio::Testing::WorkflowEnvironment#supports_time_skipping} will always return `false`
|
|
17
|
+
# for this environment. {Temporalio::Testing::WorkflowEnvironment#sleep} will sleep the actual
|
|
18
|
+
# amount of time and {Temporalio::Testing::WorkflowEnvironment#get_current_time}` will return
|
|
19
|
+
# the current time.
|
|
20
|
+
#
|
|
21
|
+
# Internally, this uses [Temporalite](https://github.com/temporalio/temporalite). Which is a
|
|
22
|
+
# self-contained binary for Temporal using Sqlite persistence. This will download Temporalite
|
|
23
|
+
# to a temporary directory by default if it has not already been downloaded before and
|
|
24
|
+
# `:existing_path` is not set.
|
|
25
|
+
#
|
|
26
|
+
# In the future, the Temporalite implementation may be changed to another implementation.
|
|
27
|
+
# Therefore, all `temporalite_` prefixed parameters are Temporalite specific and may not apply
|
|
28
|
+
# to newer versions.
|
|
29
|
+
#
|
|
30
|
+
# @param namespace [String] Namespace name to use for this environment.
|
|
31
|
+
# @param ip [String] IP address to bind to, or 127.0.0.1 by default.
|
|
32
|
+
# @param port [Integer] Port number to bind to, or an OS-provided port by default.
|
|
33
|
+
# @param download_dir [String] Directory to download binary to if a download is needed. If
|
|
34
|
+
# unset, this is the system's temporary directory.
|
|
35
|
+
# @param ui [Boolean] If `true`, will start a UI in Temporalite.
|
|
36
|
+
# @param temporalite_existing_path [String] Existing path to the Temporalite binary. If
|
|
37
|
+
# present, no download will be attempted to fetch the binary.
|
|
38
|
+
# @param temporalite_database_filename [String] Path to the Sqlite database to use for
|
|
39
|
+
# Temporalite. Unset default means only in-memory Sqlite will be used.
|
|
40
|
+
# @param temporalite_log_format [String] Log format for Temporalite.
|
|
41
|
+
# @param temporalite_log_level [String] Log level to use for Temporalite.
|
|
42
|
+
# @param temporalite_download_version [String] Specific Temporalite version to download.
|
|
43
|
+
# Defaults to `default` which downloads the version known to work best with this SDK.
|
|
44
|
+
# @param temporalite_extra_args [Array<String>] Extra arguments for the Temporalite binary.
|
|
45
|
+
#
|
|
46
|
+
# @yield Optionally you can provide a block which will ensure that the environment has been
|
|
47
|
+
# shut down after. The newly created {Temporalio::Testing::WorkflowEnvironment} will be
|
|
48
|
+
# passed into the block as a single argument. Alternatively you will need to call
|
|
49
|
+
# {Temporalio::Testing::WorkflowEnvironment#shutdown} explicitly after you're done with it.
|
|
50
|
+
#
|
|
51
|
+
# @return [Temporalio::Testing::WorkflowEnvironment] The newly started Temporalite workflow
|
|
52
|
+
# environment.
|
|
53
|
+
def start_local_environment(
|
|
54
|
+
namespace: DEFAULT_NAMESPACE,
|
|
55
|
+
ip: '127.0.0.1',
|
|
56
|
+
port: nil,
|
|
57
|
+
download_dir: nil,
|
|
58
|
+
ui: false,
|
|
59
|
+
temporalite_existing_path: nil,
|
|
60
|
+
temporalite_database_filename: nil,
|
|
61
|
+
temporalite_log_format: 'pretty',
|
|
62
|
+
temporalite_log_level: 'warn',
|
|
63
|
+
temporalite_download_version: 'default',
|
|
64
|
+
temporalite_extra_args: [],
|
|
65
|
+
&block
|
|
66
|
+
)
|
|
67
|
+
# TODO: Sync with the SDK's logger level when implemented
|
|
68
|
+
runtime = Temporalio::Runtime.instance
|
|
69
|
+
server = Temporalio::Bridge::TestServer.start_temporalite(
|
|
70
|
+
runtime.core_runtime,
|
|
71
|
+
temporalite_existing_path,
|
|
72
|
+
'sdk-ruby',
|
|
73
|
+
Temporalio::VERSION,
|
|
74
|
+
temporalite_download_version,
|
|
75
|
+
download_dir,
|
|
76
|
+
namespace,
|
|
77
|
+
ip,
|
|
78
|
+
port,
|
|
79
|
+
temporalite_database_filename,
|
|
80
|
+
ui,
|
|
81
|
+
temporalite_log_format,
|
|
82
|
+
temporalite_log_level,
|
|
83
|
+
temporalite_extra_args,
|
|
84
|
+
)
|
|
85
|
+
env = init_workflow_environment_for(server, namespace)
|
|
86
|
+
|
|
87
|
+
return env unless block
|
|
88
|
+
|
|
89
|
+
run_server(server, env, &block)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Start a time skipping workflow environment.
|
|
93
|
+
#
|
|
94
|
+
# Time can be manually skipped forward using {Temporalio::Testing::WorkflowEnvironment#sleep}.
|
|
95
|
+
# The currently known time can be obtained via
|
|
96
|
+
# {Temporalio::Testing::WorkflowEnvironment#get_current_time}.
|
|
97
|
+
#
|
|
98
|
+
# @note Auto time skipping is not yet implemented.
|
|
99
|
+
#
|
|
100
|
+
# Internally, this environment lazily downloads a test-server binary for the current OS/arch
|
|
101
|
+
# into the temp directory if it is not already there. Then the executable is started and will
|
|
102
|
+
# be killed when {Temporalio::Testing::WorkflowEnvironment#shutdown} is called (which is
|
|
103
|
+
# implicitly done if a block is provided to this method).
|
|
104
|
+
#
|
|
105
|
+
# Users can reuse this environment for testing multiple independent workflows, but not
|
|
106
|
+
# concurrently. Time skipping, which is automatically done when awaiting a workflow result
|
|
107
|
+
# (pending implementation) and manually done on
|
|
108
|
+
# {Temporalio::Testing::WorkflowEnvironment#sleep}, is global to the environment, not to the
|
|
109
|
+
# workflow under test.
|
|
110
|
+
#
|
|
111
|
+
# In the future, the test server implementation may be changed to another implementation.
|
|
112
|
+
# Therefore, all `test_server_` prefixed parameters are test server specific and may not apply
|
|
113
|
+
# to newer versions.
|
|
114
|
+
#
|
|
115
|
+
# @param port [Integer] Port number to bind to, or an OS-provided port by default.
|
|
116
|
+
# @param download_dir [String] Directory to download binary to if a download is needed.
|
|
117
|
+
# If unset, this is the system's temporary directory.
|
|
118
|
+
# @param test_server_existing_path [String] Existing path to the test server binary. If
|
|
119
|
+
# present, no download will be attempted to fetch the binary.
|
|
120
|
+
# @param test_server_download_version [String] Specific test server version to download.
|
|
121
|
+
# Defaults to `default` which downloads the version known to work best with this SDK.
|
|
122
|
+
# @param test_server_extra_args [Array<String>] Extra arguments for the test server binary.
|
|
123
|
+
#
|
|
124
|
+
# @yield Optionally you can provide a block which will ensure that the environment has been
|
|
125
|
+
# shut down after. The newly created {Temporalio::Testing::WorkflowEnvironment} will be
|
|
126
|
+
# passed into the block as a single argument. Alternatively you will need to call
|
|
127
|
+
# {Temporalio::Testing::WorkflowEnvironment#shutdown} explicitly after you're done with it.
|
|
128
|
+
#
|
|
129
|
+
# @return [Temporalio::Testing::WorkflowEnvironment] The newly started TestServer workflow
|
|
130
|
+
# environment.
|
|
131
|
+
def start_time_skipping_environment(
|
|
132
|
+
port: nil,
|
|
133
|
+
download_dir: nil,
|
|
134
|
+
test_server_existing_path: nil,
|
|
135
|
+
test_server_download_version: 'default',
|
|
136
|
+
test_server_extra_args: [],
|
|
137
|
+
&block
|
|
138
|
+
)
|
|
139
|
+
# TODO: Use interceptors to inject a time skipping WorkflowHandle.
|
|
140
|
+
runtime = Temporalio::Runtime.instance
|
|
141
|
+
server = Temporalio::Bridge::TestServer.start(
|
|
142
|
+
runtime.core_runtime,
|
|
143
|
+
test_server_existing_path,
|
|
144
|
+
'sdk-ruby',
|
|
145
|
+
Temporalio::VERSION,
|
|
146
|
+
test_server_download_version,
|
|
147
|
+
download_dir,
|
|
148
|
+
port,
|
|
149
|
+
test_server_extra_args,
|
|
150
|
+
)
|
|
151
|
+
env = init_workflow_environment_for(server, DEFAULT_NAMESPACE)
|
|
152
|
+
|
|
153
|
+
return env unless block
|
|
154
|
+
|
|
155
|
+
run_server(server, env, &block)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
private
|
|
159
|
+
|
|
160
|
+
def init_workflow_environment_for(server, namespace)
|
|
161
|
+
connection = Temporalio::Connection.new(server.target)
|
|
162
|
+
Temporalio::Testing::WorkflowEnvironment.new(server, connection, namespace)
|
|
163
|
+
rescue Temporalio::Bridge::Error # Shutdown if unable to connect to the server
|
|
164
|
+
server.shutdown
|
|
165
|
+
raise
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def run_server(server, env, &block)
|
|
169
|
+
block.call(env)
|
|
170
|
+
ensure
|
|
171
|
+
server.shutdown
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
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
|
+
require 'temporalio/interceptor/activity_inbound'
|
|
7
|
+
|
|
8
|
+
module Temporalio
|
|
9
|
+
class Worker
|
|
10
|
+
# The main class for handling activity processing. It is expected to be executed from
|
|
11
|
+
# some threaded or async executor's context since methods called here might be blocking
|
|
12
|
+
# and this should not affect the main worker reactor.
|
|
13
|
+
#
|
|
14
|
+
# @api private
|
|
15
|
+
class ActivityRunner
|
|
16
|
+
def initialize(
|
|
17
|
+
activity_class,
|
|
18
|
+
start,
|
|
19
|
+
task_queue,
|
|
20
|
+
task_token,
|
|
21
|
+
worker,
|
|
22
|
+
converter,
|
|
23
|
+
inbound_interceptors,
|
|
24
|
+
outbound_interceptors
|
|
25
|
+
)
|
|
26
|
+
@activity_class = activity_class
|
|
27
|
+
@start = start
|
|
28
|
+
@task_queue = task_queue
|
|
29
|
+
@task_token = task_token
|
|
30
|
+
@worker = worker
|
|
31
|
+
@converter = converter
|
|
32
|
+
@inbound_interceptors = inbound_interceptors
|
|
33
|
+
@outbound_interceptors = outbound_interceptors
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def run
|
|
37
|
+
activity = activity_class.new(context)
|
|
38
|
+
args = converter.from_payload_array(start.input.to_a)
|
|
39
|
+
headers = converter.from_payload_map(start.header_fields)
|
|
40
|
+
input = Temporalio::Interceptor::ActivityInbound::ExecuteActivityInput.new(
|
|
41
|
+
activity: activity_class,
|
|
42
|
+
args: args,
|
|
43
|
+
headers: headers || {},
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
result = inbound_interceptors.invoke(:execute_activity, input) do |i|
|
|
47
|
+
activity.execute(*i.args)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
converter.to_payload(result)
|
|
51
|
+
rescue StandardError => e
|
|
52
|
+
# Temporal server ignores cancellation failures that were not requested by the server.
|
|
53
|
+
# However within the SDK cancellations are also used during the worker shutdown. In order
|
|
54
|
+
# to provide a seamless handling experience (same error raised within the Activity) we are
|
|
55
|
+
# using the ActivityCancelled error and then swapping it with a CancelledError here.
|
|
56
|
+
#
|
|
57
|
+
# In the future this will be handled by the SDK Core — https://github.com/temporalio/sdk-core/issues/461
|
|
58
|
+
if e.is_a?(Temporalio::Error::ActivityCancelled) && e.by_request?
|
|
59
|
+
e = Temporalio::Error::CancelledError.new(e.message)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
converter.to_failure(e)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def cancel(reason, by_request:)
|
|
66
|
+
context.cancel(reason, by_request: by_request)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
|
|
71
|
+
attr_reader :activity_class, :start, :task_queue, :task_token, :worker, :converter,
|
|
72
|
+
:inbound_interceptors, :outbound_interceptors
|
|
73
|
+
|
|
74
|
+
def context
|
|
75
|
+
return @context if @context
|
|
76
|
+
|
|
77
|
+
heartbeat_proc = ->(*details) { heartbeat(*details) }
|
|
78
|
+
@context = Temporalio::Activity::Context.new(
|
|
79
|
+
generate_activity_info,
|
|
80
|
+
heartbeat_proc,
|
|
81
|
+
outbound_interceptors,
|
|
82
|
+
shielded: activity_class._shielded,
|
|
83
|
+
)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def generate_activity_info
|
|
87
|
+
Temporalio::Activity::Info.new(
|
|
88
|
+
activity_id: start.activity_id,
|
|
89
|
+
activity_type: start.activity_type,
|
|
90
|
+
attempt: start.attempt,
|
|
91
|
+
current_attempt_scheduled_time: start.current_attempt_scheduled_time&.to_time,
|
|
92
|
+
heartbeat_details: converter.from_payload_array(start.heartbeat_details.to_a),
|
|
93
|
+
heartbeat_timeout: start.heartbeat_timeout&.to_f,
|
|
94
|
+
local: !start.is_local.nil?,
|
|
95
|
+
schedule_to_close_timeout: start.schedule_to_close_timeout&.to_f,
|
|
96
|
+
scheduled_time: start.scheduled_time&.to_time,
|
|
97
|
+
start_to_close_timeout: start.start_to_close_timeout&.to_f,
|
|
98
|
+
started_time: start.started_time&.to_time,
|
|
99
|
+
task_queue: task_queue,
|
|
100
|
+
task_token: task_token,
|
|
101
|
+
workflow_id: start.workflow_execution&.workflow_id,
|
|
102
|
+
workflow_namespace: start.workflow_namespace,
|
|
103
|
+
workflow_run_id: start.workflow_execution&.run_id,
|
|
104
|
+
workflow_type: start.workflow_type,
|
|
105
|
+
).freeze
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def heartbeat(*details)
|
|
109
|
+
payloads = converter.to_payload_array(details)
|
|
110
|
+
worker.record_activity_heartbeat(task_token, payloads)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
require 'temporalio/error/failure'
|
|
2
|
+
require 'temporalio/errors'
|
|
3
|
+
require 'temporalio/interceptor'
|
|
4
|
+
require 'temporalio/interceptor/chain'
|
|
5
|
+
require 'temporalio/worker/activity_runner'
|
|
6
|
+
|
|
7
|
+
module Temporalio
|
|
8
|
+
class Worker
|
|
9
|
+
# @api private
|
|
10
|
+
class ActivityWorker
|
|
11
|
+
def initialize(
|
|
12
|
+
task_queue,
|
|
13
|
+
worker,
|
|
14
|
+
activities,
|
|
15
|
+
converter,
|
|
16
|
+
interceptors,
|
|
17
|
+
executor,
|
|
18
|
+
graceful_timeout
|
|
19
|
+
)
|
|
20
|
+
@task_queue = task_queue
|
|
21
|
+
@worker = worker
|
|
22
|
+
@activities = prepare_activities(activities)
|
|
23
|
+
@converter = converter
|
|
24
|
+
@inbound_interceptors = Temporalio::Interceptor::Chain.new(
|
|
25
|
+
Temporalio::Interceptor.filter(interceptors, :activity_inbound),
|
|
26
|
+
)
|
|
27
|
+
@outbound_interceptors = Temporalio::Interceptor::Chain.new(
|
|
28
|
+
Temporalio::Interceptor.filter(interceptors, :activity_outbound),
|
|
29
|
+
)
|
|
30
|
+
@executor = executor
|
|
31
|
+
@graceful_timeout = graceful_timeout
|
|
32
|
+
@running_activities = {}
|
|
33
|
+
@cancellations = []
|
|
34
|
+
@drain_queue = Queue.new
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def run(reactor)
|
|
38
|
+
# @type var outstanding_tasks: Array[Async::Task]
|
|
39
|
+
outstanding_tasks = []
|
|
40
|
+
|
|
41
|
+
loop do
|
|
42
|
+
activity_task = worker.poll_activity_task
|
|
43
|
+
outstanding_tasks << reactor.async do |async_task|
|
|
44
|
+
if activity_task.start
|
|
45
|
+
handle_start_activity(activity_task.task_token, activity_task.start)
|
|
46
|
+
elsif activity_task.cancel
|
|
47
|
+
handle_cancel_activity(activity_task.task_token, activity_task.cancel)
|
|
48
|
+
end
|
|
49
|
+
ensure
|
|
50
|
+
outstanding_tasks.delete(async_task)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
rescue Temporalio::Bridge::Error::WorkerShutdown
|
|
54
|
+
# No need to re-raise this error, it's a part of a normal shutdown
|
|
55
|
+
ensure
|
|
56
|
+
outstanding_tasks.each(&:wait)
|
|
57
|
+
@cancelation_task&.wait
|
|
58
|
+
drain_queue.close
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def setup_graceful_shutdown_timer(reactor)
|
|
62
|
+
if graceful_timeout
|
|
63
|
+
reactor.async do |async_task|
|
|
64
|
+
@cancelation_task = async_task.async do
|
|
65
|
+
sleep graceful_timeout
|
|
66
|
+
@running_activities.each_value do |activity_runner|
|
|
67
|
+
activity_runner.cancel('Worker is shutting down', by_request: false)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def drain
|
|
75
|
+
drain_queue.pop
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
attr_reader :task_queue, :worker, :activities, :converter, :inbound_interceptors,
|
|
81
|
+
:outbound_interceptors, :executor, :graceful_timeout, :running_activities,
|
|
82
|
+
:cancellations, :drain_queue
|
|
83
|
+
|
|
84
|
+
def prepare_activities(activities)
|
|
85
|
+
activities.each_with_object({}) do |activity, result|
|
|
86
|
+
unless activity.ancestors.include?(Temporalio::Activity)
|
|
87
|
+
raise ArgumentError, 'Activity must be a subclass of Temporalio::Activity'
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
if result[activity._name]
|
|
91
|
+
raise ArgumentError, "More than one activity named #{activity._name}"
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
result[activity._name] = activity
|
|
95
|
+
result
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def lookup_activity(activity_type)
|
|
100
|
+
activities.fetch(activity_type) do
|
|
101
|
+
activity_names = activities.keys.sort.join(', ')
|
|
102
|
+
raise Temporalio::Error::ApplicationError.new(
|
|
103
|
+
"Activity #{activity_type} is not registered on this worker, available activities: #{activity_names}",
|
|
104
|
+
type: 'NotFoundError',
|
|
105
|
+
)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def run_activity(token, start)
|
|
110
|
+
activity_class = lookup_activity(start.activity_type)
|
|
111
|
+
runner = ActivityRunner.new(
|
|
112
|
+
activity_class,
|
|
113
|
+
start,
|
|
114
|
+
task_queue,
|
|
115
|
+
token,
|
|
116
|
+
worker,
|
|
117
|
+
converter,
|
|
118
|
+
inbound_interceptors,
|
|
119
|
+
outbound_interceptors,
|
|
120
|
+
)
|
|
121
|
+
running_activities[token] = runner
|
|
122
|
+
queue = Queue.new
|
|
123
|
+
|
|
124
|
+
executor.schedule do
|
|
125
|
+
queue << runner.run
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
queue.pop
|
|
129
|
+
rescue StandardError => e
|
|
130
|
+
converter.to_failure(e)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def handle_start_activity(task_token, start)
|
|
134
|
+
result = run_activity(task_token, start)
|
|
135
|
+
|
|
136
|
+
case result
|
|
137
|
+
when Temporalio::Api::Common::V1::Payload
|
|
138
|
+
worker.complete_activity_task_with_success(task_token, result)
|
|
139
|
+
when Temporalio::Api::Failure::V1::Failure
|
|
140
|
+
# only respond with a cancellation when it was requested, otherwise it's a regular failure
|
|
141
|
+
if result.canceled_failure_info && cancellations.include?(task_token)
|
|
142
|
+
worker.complete_activity_task_with_cancellation(task_token, result)
|
|
143
|
+
else
|
|
144
|
+
worker.complete_activity_task_with_failure(task_token, result)
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
running_activities.delete(task_token)
|
|
149
|
+
cancellations.delete(task_token)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def handle_cancel_activity(task_token, _cancel)
|
|
153
|
+
runner = running_activities.fetch(task_token) do
|
|
154
|
+
# TODO: Use logger instead when implemented
|
|
155
|
+
warn "Cannot find activity to cancel for token #{task_token}"
|
|
156
|
+
return # early escape
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
cancellations << task_token
|
|
160
|
+
runner&.cancel('Activity cancellation requested', by_request: true)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
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
|