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,412 @@
|
|
1
|
+
pub(crate) mod metrics;
|
2
|
+
mod prometheus_server;
|
3
|
+
|
4
|
+
use crate::{
|
5
|
+
log_export::CoreExportLogger,
|
6
|
+
telemetry::{metrics::SDKAggSelector, prometheus_server::PromServer},
|
7
|
+
CoreLog, METRIC_METER,
|
8
|
+
};
|
9
|
+
use itertools::Itertools;
|
10
|
+
use log::LevelFilter;
|
11
|
+
use once_cell::sync::OnceCell;
|
12
|
+
use opentelemetry::{
|
13
|
+
global,
|
14
|
+
metrics::Meter,
|
15
|
+
runtime,
|
16
|
+
sdk::{
|
17
|
+
export::metrics::aggregation::{self, Temporality, TemporalitySelector},
|
18
|
+
trace::Config,
|
19
|
+
Resource,
|
20
|
+
},
|
21
|
+
KeyValue,
|
22
|
+
};
|
23
|
+
use opentelemetry_otlp::WithExportConfig;
|
24
|
+
use parking_lot::{const_mutex, Mutex};
|
25
|
+
use std::{
|
26
|
+
collections::{HashMap, VecDeque},
|
27
|
+
convert::TryInto,
|
28
|
+
net::SocketAddr,
|
29
|
+
time::Duration,
|
30
|
+
};
|
31
|
+
use temporal_sdk_core_api::CoreTelemetry;
|
32
|
+
use tonic::metadata::MetadataMap;
|
33
|
+
use tracing_subscriber::{filter::ParseError, layer::SubscriberExt, EnvFilter};
|
34
|
+
use url::Url;
|
35
|
+
|
36
|
+
const TELEM_SERVICE_NAME: &str = "temporal-core-sdk";
|
37
|
+
static DEFAULT_FILTER: &str = "temporal_sdk_core=INFO";
|
38
|
+
static GLOBAL_TELEM_DAT: OnceCell<GlobalTelemDat> = OnceCell::new();
|
39
|
+
static TELETM_MUTEX: Mutex<()> = const_mutex(());
|
40
|
+
|
41
|
+
fn default_resource_kvs() -> &'static [KeyValue] {
|
42
|
+
static INSTANCE: OnceCell<[KeyValue; 1]> = OnceCell::new();
|
43
|
+
INSTANCE.get_or_init(|| [KeyValue::new("service.name", TELEM_SERVICE_NAME)])
|
44
|
+
}
|
45
|
+
fn default_resource() -> Resource {
|
46
|
+
Resource::new(default_resource_kvs().iter().cloned())
|
47
|
+
}
|
48
|
+
|
49
|
+
/// Options for exporting to an OpenTelemetry Collector
|
50
|
+
#[derive(Debug, Clone)]
|
51
|
+
pub struct OtelCollectorOptions {
|
52
|
+
/// The url of the OTel collector to export telemetry and metrics to. Lang SDK should also
|
53
|
+
/// export to this same collector.
|
54
|
+
pub url: Url,
|
55
|
+
/// Optional set of HTTP headers to send to the Collector, e.g for authentication.
|
56
|
+
pub headers: HashMap<String, String>,
|
57
|
+
}
|
58
|
+
|
59
|
+
/// Control where traces are exported
|
60
|
+
#[derive(Debug, Clone)]
|
61
|
+
pub enum TraceExporter {
|
62
|
+
/// Export traces to an OpenTelemetry Collector <https://opentelemetry.io/docs/collector/>.
|
63
|
+
Otel(OtelCollectorOptions),
|
64
|
+
}
|
65
|
+
|
66
|
+
/// Control where metrics are exported
|
67
|
+
#[derive(Debug, Clone)]
|
68
|
+
pub enum MetricsExporter {
|
69
|
+
/// Export metrics to an OpenTelemetry Collector <https://opentelemetry.io/docs/collector/>.
|
70
|
+
Otel(OtelCollectorOptions),
|
71
|
+
/// Expose metrics directly via an embedded http server bound to the provided address.
|
72
|
+
Prometheus(SocketAddr),
|
73
|
+
}
|
74
|
+
|
75
|
+
/// Control where logs go
|
76
|
+
#[derive(Debug, Clone, Copy)]
|
77
|
+
pub enum Logger {
|
78
|
+
/// Log directly to console.
|
79
|
+
Console,
|
80
|
+
/// Forward logs to Lang - collectable with `fetch_global_buffered_logs`.
|
81
|
+
Forward(LevelFilter),
|
82
|
+
}
|
83
|
+
|
84
|
+
/// Telemetry configuration options. Construct with [TelemetryOptionsBuilder]
|
85
|
+
#[derive(Debug, Clone, derive_builder::Builder)]
|
86
|
+
#[non_exhaustive]
|
87
|
+
pub struct TelemetryOptions {
|
88
|
+
/// A string in the [EnvFilter] format which specifies what tracing data is included in
|
89
|
+
/// telemetry, log forwarded to lang, or console output. May be overridden by the
|
90
|
+
/// `TEMPORAL_TRACING_FILTER` env variable.
|
91
|
+
#[builder(default = "DEFAULT_FILTER.to_string()")]
|
92
|
+
pub tracing_filter: String,
|
93
|
+
|
94
|
+
/// Optional trace exporter - set as None to disable.
|
95
|
+
#[builder(setter(into, strip_option), default)]
|
96
|
+
pub tracing: Option<TraceExporter>,
|
97
|
+
/// Optional logger - set as None to disable.
|
98
|
+
#[builder(setter(into, strip_option), default)]
|
99
|
+
pub logging: Option<Logger>,
|
100
|
+
/// Optional metrics exporter - set as None to disable.
|
101
|
+
#[builder(setter(into, strip_option), default)]
|
102
|
+
pub metrics: Option<MetricsExporter>,
|
103
|
+
|
104
|
+
/// If set true, do not prefix metrics with `temporal_`. Will be removed eventually as
|
105
|
+
/// the prefix is consistent with other SDKs.
|
106
|
+
#[builder(default)]
|
107
|
+
pub no_temporal_prefix_for_metrics: bool,
|
108
|
+
|
109
|
+
/// Specifies the aggregation temporality for metric export. Defaults to cumulative.
|
110
|
+
#[builder(default = "MetricTemporality::Cumulative")]
|
111
|
+
pub metric_temporality: MetricTemporality,
|
112
|
+
}
|
113
|
+
|
114
|
+
/// Types of aggregation temporality for metric export.
|
115
|
+
/// See: <https://github.com/open-telemetry/opentelemetry-specification/blob/ce50e4634efcba8da445cc23523243cb893905cb/specification/metrics/datamodel.md#temporality>
|
116
|
+
#[derive(Debug, Clone, Copy)]
|
117
|
+
pub enum MetricTemporality {
|
118
|
+
/// Successive data points repeat the starting timestamp
|
119
|
+
Cumulative,
|
120
|
+
/// Successive data points advance the starting timestamp
|
121
|
+
Delta,
|
122
|
+
}
|
123
|
+
|
124
|
+
impl MetricTemporality {
|
125
|
+
fn to_selector(self) -> impl TemporalitySelector + Send + Sync + Clone {
|
126
|
+
match self {
|
127
|
+
MetricTemporality::Cumulative => {
|
128
|
+
aggregation::constant_temporality_selector(Temporality::Cumulative)
|
129
|
+
}
|
130
|
+
MetricTemporality::Delta => {
|
131
|
+
aggregation::constant_temporality_selector(Temporality::Delta)
|
132
|
+
}
|
133
|
+
}
|
134
|
+
}
|
135
|
+
}
|
136
|
+
|
137
|
+
impl TelemetryOptions {
|
138
|
+
/// Construct an [EnvFilter] from given `tracing_filter`.
|
139
|
+
pub fn try_get_env_filter(&self) -> Result<EnvFilter, ParseError> {
|
140
|
+
EnvFilter::try_new(if self.tracing_filter.is_empty() {
|
141
|
+
DEFAULT_FILTER
|
142
|
+
} else {
|
143
|
+
&self.tracing_filter
|
144
|
+
})
|
145
|
+
}
|
146
|
+
}
|
147
|
+
|
148
|
+
impl Default for TelemetryOptions {
|
149
|
+
fn default() -> Self {
|
150
|
+
TelemetryOptionsBuilder::default().build().unwrap()
|
151
|
+
}
|
152
|
+
}
|
153
|
+
|
154
|
+
/// Things that need to not be dropped while telemetry is ongoing
|
155
|
+
#[derive(Default)]
|
156
|
+
pub struct GlobalTelemDat {
|
157
|
+
core_export_logger: Option<CoreExportLogger>,
|
158
|
+
runtime: Option<tokio::runtime::Runtime>,
|
159
|
+
prom_srv: Option<PromServer>,
|
160
|
+
no_temporal_prefix_for_metrics: bool,
|
161
|
+
}
|
162
|
+
|
163
|
+
impl GlobalTelemDat {
|
164
|
+
fn init(&'static self) {
|
165
|
+
if let Some(loggr) = &self.core_export_logger {
|
166
|
+
let _ = log::set_logger(loggr);
|
167
|
+
}
|
168
|
+
if let Some(srv) = &self.prom_srv {
|
169
|
+
self.runtime
|
170
|
+
.as_ref()
|
171
|
+
.expect("Telemetry runtime is initted")
|
172
|
+
.spawn(srv.run());
|
173
|
+
}
|
174
|
+
}
|
175
|
+
}
|
176
|
+
|
177
|
+
impl CoreTelemetry for GlobalTelemDat {
|
178
|
+
fn fetch_buffered_logs(&self) -> Vec<CoreLog> {
|
179
|
+
fetch_global_buffered_logs()
|
180
|
+
}
|
181
|
+
|
182
|
+
fn get_metric_meter(&self) -> Option<&Meter> {
|
183
|
+
if GLOBAL_TELEM_DAT.get().is_some() {
|
184
|
+
return Some(&METRIC_METER);
|
185
|
+
}
|
186
|
+
None
|
187
|
+
}
|
188
|
+
}
|
189
|
+
|
190
|
+
/// Initialize tracing subscribers/output and logging export. If this function is called more than
|
191
|
+
/// once, subsequent calls do nothing.
|
192
|
+
///
|
193
|
+
/// See [TelemetryOptions] docs for more on configuration.
|
194
|
+
pub fn telemetry_init(opts: &TelemetryOptions) -> Result<&'static GlobalTelemDat, anyhow::Error> {
|
195
|
+
// TODO: Per-layer filtering has been implemented but does not yet support
|
196
|
+
// env-filter. When it does, allow filtering logs/telemetry separately.
|
197
|
+
|
198
|
+
// Ensure we don't pointlessly spawn threads that won't do anything or call telem dat's init 2x
|
199
|
+
let guard = TELETM_MUTEX.lock();
|
200
|
+
if let Some(gtd) = GLOBAL_TELEM_DAT.get() {
|
201
|
+
return Ok(gtd);
|
202
|
+
}
|
203
|
+
|
204
|
+
// This is a bit odd, but functional. It's desirable to create a separate tokio runtime for
|
205
|
+
// metrics handling, since tests typically use a single-threaded runtime and initializing
|
206
|
+
// pipeline requires us to know if the runtime is single or multithreaded, we will crash
|
207
|
+
// in one case or the other. There does not seem to be a way to tell from the current runtime
|
208
|
+
// handle if it is single or multithreaded. Additionally, we can isolate metrics work this
|
209
|
+
// way which is nice.
|
210
|
+
let opts = opts.clone();
|
211
|
+
std::thread::spawn(move || {
|
212
|
+
let res = GLOBAL_TELEM_DAT.get_or_try_init::<_, anyhow::Error>(move || {
|
213
|
+
// Ensure closure captures the mutex guard
|
214
|
+
let _ = &*guard;
|
215
|
+
|
216
|
+
let runtime = tokio::runtime::Builder::new_multi_thread()
|
217
|
+
.thread_name("telemetry")
|
218
|
+
.worker_threads(2)
|
219
|
+
.enable_all()
|
220
|
+
.build()?;
|
221
|
+
let mut globaldat = GlobalTelemDat {
|
222
|
+
no_temporal_prefix_for_metrics: opts.no_temporal_prefix_for_metrics,
|
223
|
+
..Default::default()
|
224
|
+
};
|
225
|
+
|
226
|
+
if let Some(ref logger) = opts.logging {
|
227
|
+
match logger {
|
228
|
+
Logger::Console => {
|
229
|
+
// TODO: this is duplicated below and is quite ugly, remove the duplication
|
230
|
+
if opts.tracing.is_none() {
|
231
|
+
let pretty_fmt = tracing_subscriber::fmt::format()
|
232
|
+
.pretty()
|
233
|
+
.with_source_location(false);
|
234
|
+
let reg = tracing_subscriber::registry()
|
235
|
+
.with((opts).try_get_env_filter()?)
|
236
|
+
.with(
|
237
|
+
tracing_subscriber::fmt::layer()
|
238
|
+
.with_target(false)
|
239
|
+
.event_format(pretty_fmt),
|
240
|
+
);
|
241
|
+
tracing::subscriber::set_global_default(reg)?;
|
242
|
+
}
|
243
|
+
}
|
244
|
+
Logger::Forward(filter) => {
|
245
|
+
log::set_max_level(*filter);
|
246
|
+
globaldat.core_export_logger = Some(CoreExportLogger::new(*filter));
|
247
|
+
}
|
248
|
+
};
|
249
|
+
};
|
250
|
+
|
251
|
+
if let Some(ref metrics) = opts.metrics {
|
252
|
+
match metrics {
|
253
|
+
MetricsExporter::Prometheus(addr) => {
|
254
|
+
let srv = PromServer::new(*addr, opts.metric_temporality.to_selector())?;
|
255
|
+
globaldat.prom_srv = Some(srv);
|
256
|
+
}
|
257
|
+
MetricsExporter::Otel(OtelCollectorOptions { url, headers }) => {
|
258
|
+
runtime.block_on(async {
|
259
|
+
let metrics = opentelemetry_otlp::new_pipeline()
|
260
|
+
.metrics(
|
261
|
+
SDKAggSelector,
|
262
|
+
opts.metric_temporality.to_selector(),
|
263
|
+
runtime::Tokio,
|
264
|
+
)
|
265
|
+
.with_period(Duration::from_secs(1))
|
266
|
+
.with_resource(default_resource())
|
267
|
+
.with_exporter(
|
268
|
+
// No joke exporter builder literally not cloneable for some insane
|
269
|
+
// reason
|
270
|
+
opentelemetry_otlp::new_exporter()
|
271
|
+
.tonic()
|
272
|
+
.with_endpoint(url.to_string())
|
273
|
+
.with_metadata(MetadataMap::from_headers(
|
274
|
+
headers.try_into()?,
|
275
|
+
)),
|
276
|
+
)
|
277
|
+
.build()?;
|
278
|
+
global::set_meter_provider(metrics);
|
279
|
+
Result::<(), anyhow::Error>::Ok(())
|
280
|
+
})?;
|
281
|
+
}
|
282
|
+
};
|
283
|
+
};
|
284
|
+
|
285
|
+
if let Some(ref tracing) = opts.tracing {
|
286
|
+
match tracing {
|
287
|
+
TraceExporter::Otel(OtelCollectorOptions { url, headers }) => {
|
288
|
+
runtime.block_on(async {
|
289
|
+
let tracer_cfg = Config::default().with_resource(default_resource());
|
290
|
+
let tracer = opentelemetry_otlp::new_pipeline()
|
291
|
+
.tracing()
|
292
|
+
.with_exporter(
|
293
|
+
opentelemetry_otlp::new_exporter()
|
294
|
+
.tonic()
|
295
|
+
.with_endpoint(url.to_string())
|
296
|
+
.with_metadata(MetadataMap::from_headers(
|
297
|
+
headers.try_into()?,
|
298
|
+
)),
|
299
|
+
)
|
300
|
+
.with_trace_config(tracer_cfg)
|
301
|
+
.install_batch(runtime::Tokio)?;
|
302
|
+
|
303
|
+
let opentelemetry = tracing_opentelemetry::layer().with_tracer(tracer);
|
304
|
+
|
305
|
+
// TODO: remove all of this duplicate code
|
306
|
+
if let Some(Logger::Console) = opts.logging {
|
307
|
+
let pretty_fmt = tracing_subscriber::fmt::format()
|
308
|
+
.pretty()
|
309
|
+
.with_source_location(false);
|
310
|
+
let reg = tracing_subscriber::registry()
|
311
|
+
.with(opentelemetry)
|
312
|
+
.with(opts.try_get_env_filter()?)
|
313
|
+
.with(
|
314
|
+
tracing_subscriber::fmt::layer()
|
315
|
+
.with_target(false)
|
316
|
+
.event_format(pretty_fmt),
|
317
|
+
);
|
318
|
+
// Can't use try_init here as it will blow away our custom logger if we do
|
319
|
+
tracing::subscriber::set_global_default(reg)?;
|
320
|
+
} else {
|
321
|
+
let reg = tracing_subscriber::registry()
|
322
|
+
.with(opentelemetry)
|
323
|
+
.with(opts.try_get_env_filter()?);
|
324
|
+
// Can't use try_init here as it will blow away our custom logger if we do
|
325
|
+
tracing::subscriber::set_global_default(reg)?;
|
326
|
+
}
|
327
|
+
Result::<(), anyhow::Error>::Ok(())
|
328
|
+
})?;
|
329
|
+
}
|
330
|
+
};
|
331
|
+
};
|
332
|
+
|
333
|
+
globaldat.runtime = Some(runtime);
|
334
|
+
Ok(globaldat)
|
335
|
+
})?;
|
336
|
+
|
337
|
+
res.init();
|
338
|
+
Result::<_, anyhow::Error>::Ok(res)
|
339
|
+
})
|
340
|
+
.join()
|
341
|
+
.expect("Telemetry initialization panicked")
|
342
|
+
}
|
343
|
+
|
344
|
+
/// Returned buffered logs for export to lang from the global logging instance.
|
345
|
+
/// If [telemetry_init] has not been called, always returns an empty vec.
|
346
|
+
pub fn fetch_global_buffered_logs() -> Vec<CoreLog> {
|
347
|
+
if let Some(loggr) = GLOBAL_TELEM_DAT
|
348
|
+
.get()
|
349
|
+
.and_then(|gd| gd.core_export_logger.as_ref())
|
350
|
+
{
|
351
|
+
loggr.drain()
|
352
|
+
} else {
|
353
|
+
vec![]
|
354
|
+
}
|
355
|
+
}
|
356
|
+
|
357
|
+
#[allow(dead_code)] // Not always used, called to enable for debugging when needed
|
358
|
+
#[cfg(test)]
|
359
|
+
pub(crate) fn test_telem_console() {
|
360
|
+
telemetry_init(&TelemetryOptions {
|
361
|
+
tracing_filter: "temporal_sdk_core=DEBUG,temporal_sdk=DEBUG".to_string(),
|
362
|
+
logging: Some(Logger::Console),
|
363
|
+
tracing: None,
|
364
|
+
metrics: None,
|
365
|
+
no_temporal_prefix_for_metrics: false,
|
366
|
+
metric_temporality: MetricTemporality::Cumulative,
|
367
|
+
})
|
368
|
+
.unwrap();
|
369
|
+
}
|
370
|
+
|
371
|
+
#[allow(dead_code)] // Not always used, called to enable for debugging when needed
|
372
|
+
#[cfg(test)]
|
373
|
+
pub(crate) fn test_telem_collector() {
|
374
|
+
telemetry_init(&TelemetryOptions {
|
375
|
+
tracing_filter: "temporal_sdk_core=DEBUG,temporal_sdk=DEBUG".to_string(),
|
376
|
+
logging: Some(Logger::Console),
|
377
|
+
tracing: Some(TraceExporter::Otel(OtelCollectorOptions {
|
378
|
+
url: "grpc://localhost:4317".parse().unwrap(),
|
379
|
+
headers: Default::default(),
|
380
|
+
})),
|
381
|
+
metrics: None,
|
382
|
+
no_temporal_prefix_for_metrics: false,
|
383
|
+
metric_temporality: MetricTemporality::Cumulative,
|
384
|
+
})
|
385
|
+
.unwrap();
|
386
|
+
}
|
387
|
+
|
388
|
+
/// A trait for using [Display] on the contents of vecs, etc, which don't implement it.
|
389
|
+
///
|
390
|
+
/// Dislike this, but, there doesn't seem to be a great alternative. Calling itertools format
|
391
|
+
/// inline in an `event!` macro can panic because it gets evaluated twice somehow.
|
392
|
+
pub(crate) trait VecDisplayer {
|
393
|
+
fn display(&self) -> String;
|
394
|
+
}
|
395
|
+
|
396
|
+
impl<T> VecDisplayer for Vec<T>
|
397
|
+
where
|
398
|
+
T: std::fmt::Display,
|
399
|
+
{
|
400
|
+
fn display(&self) -> String {
|
401
|
+
format!("[{}]", self.iter().format(","))
|
402
|
+
}
|
403
|
+
}
|
404
|
+
|
405
|
+
impl<T> VecDisplayer for VecDeque<T>
|
406
|
+
where
|
407
|
+
T: std::fmt::Display,
|
408
|
+
{
|
409
|
+
fn display(&self) -> String {
|
410
|
+
format!("[{}]", self.iter().format(","))
|
411
|
+
}
|
412
|
+
}
|
@@ -0,0 +1,77 @@
|
|
1
|
+
use crate::telemetry::{default_resource, metrics::SDKAggSelector};
|
2
|
+
use hyper::{
|
3
|
+
header::CONTENT_TYPE,
|
4
|
+
service::{make_service_fn, service_fn},
|
5
|
+
Body, Method, Request, Response, Server,
|
6
|
+
};
|
7
|
+
use opentelemetry::{
|
8
|
+
metrics::MetricsError,
|
9
|
+
sdk::{
|
10
|
+
export::metrics::aggregation::TemporalitySelector,
|
11
|
+
metrics::{controllers, processors},
|
12
|
+
},
|
13
|
+
};
|
14
|
+
use opentelemetry_prometheus::{ExporterBuilder, PrometheusExporter};
|
15
|
+
use prometheus::{Encoder, TextEncoder};
|
16
|
+
use std::{convert::Infallible, net::SocketAddr, sync::Arc};
|
17
|
+
|
18
|
+
/// Exposes prometheus metrics for scraping
|
19
|
+
pub(super) struct PromServer {
|
20
|
+
addr: SocketAddr,
|
21
|
+
pub exporter: Arc<PrometheusExporter>,
|
22
|
+
}
|
23
|
+
|
24
|
+
impl PromServer {
|
25
|
+
pub fn new(
|
26
|
+
addr: SocketAddr,
|
27
|
+
temporality: impl TemporalitySelector + Send + Sync + 'static,
|
28
|
+
) -> Result<Self, MetricsError> {
|
29
|
+
let controller =
|
30
|
+
controllers::basic(processors::factory(SDKAggSelector, temporality).with_memory(true))
|
31
|
+
.with_resource(default_resource())
|
32
|
+
.build();
|
33
|
+
let exporter = ExporterBuilder::new(controller).try_init()?;
|
34
|
+
Ok(Self {
|
35
|
+
exporter: Arc::new(exporter),
|
36
|
+
addr,
|
37
|
+
})
|
38
|
+
}
|
39
|
+
|
40
|
+
pub async fn run(&self) -> hyper::Result<()> {
|
41
|
+
// Spin up hyper server to serve metrics for scraping. We use hyper since we already depend
|
42
|
+
// on it via Tonic.
|
43
|
+
let expclone = self.exporter.clone();
|
44
|
+
let svc = make_service_fn(move |_conn| {
|
45
|
+
let expclone = expclone.clone();
|
46
|
+
async move { Ok::<_, Infallible>(service_fn(move |req| metrics_req(req, expclone.clone()))) }
|
47
|
+
});
|
48
|
+
let server = Server::bind(&self.addr).serve(svc);
|
49
|
+
server.await
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
/// Serves prometheus metrics in the expected format for scraping
|
54
|
+
async fn metrics_req(
|
55
|
+
req: Request<Body>,
|
56
|
+
exporter: Arc<PrometheusExporter>,
|
57
|
+
) -> Result<Response<Body>, hyper::Error> {
|
58
|
+
let response = match (req.method(), req.uri().path()) {
|
59
|
+
(&Method::GET, "/metrics") => {
|
60
|
+
let mut buffer = vec![];
|
61
|
+
let encoder = TextEncoder::new();
|
62
|
+
let metric_families = exporter.registry().gather();
|
63
|
+
encoder.encode(&metric_families, &mut buffer).unwrap();
|
64
|
+
|
65
|
+
Response::builder()
|
66
|
+
.status(200)
|
67
|
+
.header(CONTENT_TYPE, encoder.format_type())
|
68
|
+
.body(Body::from(buffer))
|
69
|
+
.unwrap()
|
70
|
+
}
|
71
|
+
_ => Response::builder()
|
72
|
+
.status(404)
|
73
|
+
.body(Body::empty())
|
74
|
+
.expect("Can't fail to construct empty resp"),
|
75
|
+
};
|
76
|
+
Ok(response)
|
77
|
+
}
|