prefect-client 3.8.9.dev4__tar.gz → 3.8.9.dev5__tar.gz
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.
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/PKG-INFO +1 -1
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/AGENTS.md +1 -0
- prefect_client-3.8.9.dev5/src/prefect/_build_info.py +5 -0
- prefect_client-3.8.9.dev5/src/prefect/_internal/_observation_delivery.py +354 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/observers.py +156 -236
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/events/clients.py +10 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/flow_runs.py +9 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/logging/clients.py +10 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/collections.py +6 -4
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/templating/__init__.py +6 -3
- prefect_client-3.8.9.dev4/src/prefect/_build_info.py +0 -5
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/.gitignore +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/LICENSE +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/README.md +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/hatch_build.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/pyproject.toml +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/.prefectignore +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/__main__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_experimental/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_experimental/_launchers.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_experimental/bundles/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_experimental/bundles/execute.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_experimental/plugins/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_experimental/plugins/apply.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_experimental/plugins/diagnostics.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_experimental/plugins/manager.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_experimental/plugins/spec.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_experimental/sla/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_experimental/sla/client.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_experimental/sla/objects.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_flow_run_suspension.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/_logging.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/analytics/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/analytics/ci_detection.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/analytics/client.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/analytics/device_id.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/analytics/emit.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/analytics/enabled.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/analytics/events.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/analytics/milestones.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/analytics/notice.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/analytics/service.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/ast_utils.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/attempt_control.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/buildx.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/compatibility/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/compatibility/async_dispatch.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/compatibility/backports.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/compatibility/blocks.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/compatibility/deprecated.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/compatibility/deprecated_paths.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/compatibility/migration.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/compatibility/starlette.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/concurrency/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/concurrency/api.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/concurrency/calls.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/concurrency/cancellation.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/concurrency/event_loop.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/concurrency/inspection.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/concurrency/primitives.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/concurrency/services.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/concurrency/threads.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/concurrency/waiters.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/control_listener.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/deprecated.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/engine.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/git.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/infrastructure_exit_codes.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/installation.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/integrations.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/launchers.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/lazy.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/metrics.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/observability.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/plugins/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/plugins/apply.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/plugins/collections.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/plugins/diagnostics.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/plugins/manager.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/plugins/spec.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/plugins/startup.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/pydantic/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/pydantic/schemas.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/pydantic/v1_schema.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/pydantic/v2_schema.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/pydantic/validated_func.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/pytz.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/result_records.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/retries.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/schema.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/schemas/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/schemas/_registry.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/schemas/bases.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/schemas/fields.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/schemas/serializers.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/schemas/validators.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/send_entrypoint_logs.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/server_maintenance.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/states.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/testing.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/urls.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/uuid7.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/version_checking.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/versioning.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/waiters.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_internal/websockets.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_sdk/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_sdk/fetcher.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_sdk/generator.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_sdk/models.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_sdk/naming.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_sdk/renderer.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_sdk/schema_converter.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_sdk/templates/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_sdk/templates/sdk.py.jinja +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_sdk/types.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_sdk/unions.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_vendor/croniter/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/_vendor/croniter/croniter.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/agent.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/analytics/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/artifacts.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/assets/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/assets/core.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/assets/materialize.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/automations.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/blocks/AGENTS.md +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/blocks/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/blocks/abstract.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/blocks/core.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/blocks/fields.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/blocks/notifications.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/blocks/redis.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/blocks/system.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/blocks/webhook.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/bundles/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/bundles/_file_collector.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/bundles/_ignore_filter.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/bundles/_path_resolver.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/bundles/_zip_builder.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/bundles/_zip_extractor.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/bundles/execute.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/cache_policies.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/AGENTS.md +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/attribution.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/base.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/cloud.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/collections.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/constants.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_artifacts/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_artifacts/client.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_automations/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_automations/client.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_blocks_documents/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_blocks_documents/client.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_blocks_schemas/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_blocks_schemas/client.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_blocks_types/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_blocks_types/client.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_concurrency_limits/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_concurrency_limits/client.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_deployments/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_deployments/client.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_events/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_events/client.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_flow_runs/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_flow_runs/client.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_flows/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_flows/client.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_logs/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_logs/client.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_variables/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_variables/client.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_work_pools/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/_work_pools/client.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/base.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/orchestration/routes.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/schemas/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/schemas/actions.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/schemas/events.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/schemas/filters.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/schemas/objects.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/schemas/responses.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/schemas/schedules.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/schemas/sorting.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/schemas/worker_channel.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/subscriptions.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/types/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/types/flexible_schedule_list.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/client/utilities.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/concurrency/AGENTS.md +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/concurrency/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/concurrency/_asyncio.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/concurrency/_events.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/concurrency/_leases.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/concurrency/_sync.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/concurrency/asyncio.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/concurrency/context.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/concurrency/services.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/concurrency/sync.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/concurrency/v1/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/concurrency/v1/_asyncio.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/concurrency/v1/_events.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/concurrency/v1/asyncio.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/concurrency/v1/context.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/concurrency/v1/services.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/concurrency/v1/sync.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/context.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/deployments/AGENTS.md +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/deployments/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/deployments/base.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/deployments/deployments.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/deployments/flow_runs.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/deployments/runner.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/deployments/schedules.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/deployments/steps/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/deployments/steps/core.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/deployments/steps/pull.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/deployments/steps/utility.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/docker/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/docker/_buildx.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/docker/docker_image.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/engine.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/events/AGENTS.md +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/events/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/events/actions.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/events/filters.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/events/related.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/events/schemas/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/events/schemas/automations.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/events/schemas/deployment_triggers.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/events/schemas/events.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/events/schemas/labelling.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/events/subscribers.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/events/utilities.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/events/worker.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/exceptions.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/filesystems.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/flow_engine.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/flows.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/futures.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/infrastructure/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/infrastructure/base.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/infrastructure/provisioners/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/infrastructure/provisioners/cloud_run.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/infrastructure/provisioners/coiled.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/infrastructure/provisioners/container_instance.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/infrastructure/provisioners/ecs.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/infrastructure/provisioners/modal.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/input/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/input/actions.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/input/run_input.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/locking/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/locking/_filelock.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/locking/filesystem.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/locking/memory.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/locking/protocol.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/logging/AGENTS.md +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/logging/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/logging/configuration.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/logging/filters.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/logging/formatters.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/logging/handlers.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/logging/highlighters.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/logging/loggers.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/logging/logging.yml +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/main.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/plugins.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/py.typed +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/results.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/AGENTS.md +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/_cancel_finalizer.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/_cancellation_manager.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/_control_channel.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/_deployment_registry.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/_event_emitter.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/_flow_resolver.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/_flow_run_executor.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/_hook_runner.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/_limit_manager.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/_process_manager.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/_scheduled_run_poller.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/_starter_bundle.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/_starter_direct.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/_starter_engine.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/_state_proposer.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/_uv_command.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/_workspace_hook_runner.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/_workspace_resolver.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/_workspace_runtime.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/_workspace_runtime_bootstrap.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/_workspace_starter.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/_workspace_supervisor.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/runner.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/server.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runner/storage.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runtime/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runtime/deployment.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runtime/flow_run.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/runtime/task_run.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/schedules.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/serializers.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/_ui_static.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/admin.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/artifacts.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/automations.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/background_workers.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/block_capabilities.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/block_documents.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/block_schemas.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/block_types.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/clients.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/collections.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/collections_data/views/aggregate-worker-metadata.json +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/concurrency_limits.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/concurrency_limits_v2.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/csrf_token.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/dependencies.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/deployments.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/events.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/flow_run_states.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/flow_runs.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/flows.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/logs.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/middleware.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/root.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/run_history.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/saved_searches.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/server.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/static/prefect-logo-mark-gradient.png +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/task_run_states.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/task_runs.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/task_workers.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/templates.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/ui/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/ui/flow_runs.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/ui/flows.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/ui/schemas.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/ui/task_runs.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/validation.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/variables.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/work_queues.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/server/api/workers.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/AGENTS.md +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/_types.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/base.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/constants.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/context.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/legacy.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/_defaults.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/api.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/cli.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/client.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/cloud.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/deployments.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/events.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/experiments.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/flows.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/internal.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/logging.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/plugins.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/results.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/root.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/runner.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/server/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/server/api.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/server/concurrency.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/server/database.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/server/deployments.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/server/docket.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/server/ephemeral.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/server/events.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/server/flow_run_graph.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/server/logs.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/server/root.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/server/services.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/server/tasks.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/server/ui.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/server/worker_channel.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/tasks.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/telemetry.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/testing.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/models/worker.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/profiles.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/profiles.toml +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/settings/sources.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/states.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/task_engine.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/task_runners.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/task_runs.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/task_worker.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/tasks.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/telemetry/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/telemetry/run_telemetry.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/transactions.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/types/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/types/_concurrency.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/types/_datetime.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/types/entrypoint.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/types/names.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/AGENTS.md +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/annotations.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/asyncutils/AGENTS.md +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/asyncutils/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/callables/AGENTS.md +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/callables/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/compat.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/context.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/dispatch.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/dockerutils.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/engine/AGENTS.md +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/engine/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/filesystem/AGENTS.md +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/filesystem/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/generics.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/hashing.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/importtools.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/math.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/names.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/processutils/AGENTS.md +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/processutils/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/pydantic.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/render_swagger.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/schema_tools/AGENTS.md +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/schema_tools/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/schema_tools/hydration.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/schema_tools/validation.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/services.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/slugify.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/templating/AGENTS.md +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/text.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/timeout.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/urls.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/utilities/visualization.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/variables.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/workers/AGENTS.md +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/workers/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/workers/_cleanup.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/workers/_cleanup_handlers.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/workers/_worker_channel/__init__.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/workers/_worker_channel/_protocol.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/workers/_worker_channel/_state.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/workers/_worker_channel/_sync.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/workers/_worker_channel/_transport.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/workers/base.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/workers/block.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/workers/cloud.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/workers/process.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/workers/server.py +0 -0
- {prefect_client-3.8.9.dev4 → prefect_client-3.8.9.dev5}/src/prefect/workers/utilities.py +0 -0
|
@@ -24,6 +24,7 @@ There is no formal public/private boundary beyond the `_` prefix convention. Mod
|
|
|
24
24
|
- **Set run metadata before state transitions.** Any run attribute that event subscribers observe at the moment of a state transition (e.g., custom `flow_run_name`) must be persisted to the server *before* `set_state()` is called for that transition. Metadata set after the call appears stale to subscribers of that state event.
|
|
25
25
|
- **Sync and async must stay in sync.** Both `flow_engine.py` and `task_engine.py` have sync and async paths. Any behavior change must be applied to both.
|
|
26
26
|
- **Event and log WebSocket subscribers are parallel implementations.** `events/clients.py::PrefectEventSubscriber` and `logging/clients.py::PrefectLogsSubscriber` duplicate the same reconnect/backoff/dedup logic, including the `reconnect_on_clean_close` option (used by `events/subscribers.py::FlowRunSubscriber` so a clean disconnect doesn't hide a terminal event). Mirror any reconnection-behavior change across both.
|
|
27
|
+
- **Flow run observers own their stream recovery.** `_internal/observers.py` observers create subscribers with `reconnection_attempts=0` and delegate polling fallback, reconnect backoff, and setup deadlines to `_internal/_observation_delivery.py::ObservationDelivery`. Subscribers close any socket left by a failed or cancelled `__aenter__`, since callers never exit a context that failed to enter.
|
|
27
28
|
- **Use `whenever` compat helpers for all datetime conversions on Python 3.13+.** `types/_datetime.py` provides `now()`, `_whenever_to_stdlib()`, `_whenever_zdt_from_py()`, and `_whenever_pdt_from_py()` to abstract over API differences between whenever 0.7.x–0.9.x and ≥ 0.10.0. The `_WHENEVER_NEW_API` flag (True when whenever ≥ 0.10.0) guards version-specific code. Never call `DateTime.now()` or `pendulum.now()` directly — use `now()` from `types/_datetime.py` instead. Avoid no-argument `datetime.datetime.now()` because it returns a tz-naive datetime that raises `TypeError` when compared to the tz-aware datetimes produced by `now()`. Explicitly timezone-aware stdlib calls such as `datetime.now(ZoneInfo("UTC"))` are allowed when needed to preserve timezone information. Never call `ZonedDateTime.from_py_datetime()`, `PlainDateTime.from_py_datetime()`, or `.py_datetime()` directly — use the helpers instead. Violations will silently break on whichever whenever version the helpers weren't written for.
|
|
28
29
|
- **Flow and task engines advance state differently.** The flow engine makes blocking API calls to the server to propose and advance states. The task engine emits `prefect.task_run.*` events (delivered via WebSockets) but advances state locally through `set_state` calls with polling/backoff — do not assume the two engines work the same way.
|
|
29
30
|
- **Flow state transitions go through the server.** The flow engine proposes states to the server, which accepts or rejects them via orchestration rules. The task engine, by contrast, manages state transitions locally via `set_state` and emits `prefect.task_run.*` events — it does not propose states to the server.
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Keep observer notifications flowing while the events stream comes and goes.
|
|
3
|
+
|
|
4
|
+
`ObservationDelivery` owns the transport lifecycle shared by the flow run
|
|
5
|
+
observers: it consumes the events stream while it is healthy, polls the current
|
|
6
|
+
state while it is not, and periodically tries to restore the stream. Observers
|
|
7
|
+
supply what to do with an event, how to check the current state, and how to
|
|
8
|
+
report that neither mechanism is working; interpreting flow run state remains
|
|
9
|
+
their responsibility.
|
|
10
|
+
|
|
11
|
+
Lifecycle state machine (`_DeliveryState` selects the active phase in `_run`;
|
|
12
|
+
`start`, `stop`, and `_supervise` own startup and terminal transitions):
|
|
13
|
+
|
|
14
|
+
STARTING ---- setup succeeds -----------------------> STREAMING
|
|
15
|
+
| |
|
|
16
|
+
+--- setup fails ---> POLLING <--- consumer ends ----+
|
|
17
|
+
|
|
|
18
|
+
retry due
|
|
19
|
+
v
|
|
20
|
+
CONNECTING
|
|
21
|
+
|
|
|
22
|
+
setup succeeds
|
|
23
|
+
v
|
|
24
|
+
RECONCILING --- check succeeds -> STREAMING
|
|
25
|
+
|
|
26
|
+
Additional transitions and guards:
|
|
27
|
+
|
|
28
|
+
* CONNECTING -> POLLING when setup fails and the poller is still running.
|
|
29
|
+
* RECONCILING -> RECONCILING when a state check fails: retain the consumer,
|
|
30
|
+
wait with jittered backoff, then retry the check.
|
|
31
|
+
* RECONCILING -> POLLING when the consumer ends and the poller is still running.
|
|
32
|
+
* POLLING or CONNECTING -> FAILED when polling ends without an established
|
|
33
|
+
consumer. A completed successful setup wins over simultaneous poll failure.
|
|
34
|
+
* RECONCILING -> FAILED only when its consumer ends and polling has also ended.
|
|
35
|
+
* Any active phase -> STOPPING -> STOPPED on deliberate shutdown or cancelled
|
|
36
|
+
entry. Cancel and await owned work, then close the connection.
|
|
37
|
+
* FAILED releases owned work before reporting unavailability once. STOPPED
|
|
38
|
+
does not report unavailability or schedule further work.
|
|
39
|
+
|
|
40
|
+
Phase ownership and invariants:
|
|
41
|
+
|
|
42
|
+
* STARTING owns bounded setup; initial success needs no recovery reconciliation.
|
|
43
|
+
* POLLING owns the fallback poller and reconnect delay; CONNECTING keeps that
|
|
44
|
+
same poller while owning a bounded setup attempt.
|
|
45
|
+
* RECONCILING owns a live consumer and a state check or retry delay. The poller
|
|
46
|
+
may still be running or may have exhausted its policy; a live consumer keeps
|
|
47
|
+
delivery available in either case.
|
|
48
|
+
* RECONCILING -> STREAMING requires a successful current-state check and a
|
|
49
|
+
running consumer, followed by cancelling and awaiting any live poller.
|
|
50
|
+
* STREAMING owns only the consumer. A quiet stream has no idle deadline.
|
|
51
|
+
* STOPPED and FAILED own no running tasks or open connection.
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
from __future__ import annotations
|
|
55
|
+
|
|
56
|
+
import asyncio
|
|
57
|
+
import logging
|
|
58
|
+
import random
|
|
59
|
+
from collections.abc import Callable, Coroutine
|
|
60
|
+
from enum import Enum, auto
|
|
61
|
+
from typing import Any, TypeVar
|
|
62
|
+
|
|
63
|
+
from prefect.events import Event
|
|
64
|
+
from prefect.events.clients import PrefectEventSubscriber
|
|
65
|
+
from prefect.utilities.services import critical_service_loop
|
|
66
|
+
|
|
67
|
+
T = TypeVar("T")
|
|
68
|
+
|
|
69
|
+
# Bound on opening the socket plus the application handshake (ping, auth, filter)
|
|
70
|
+
SETUP_TIMEOUT_SECONDS = 10.0
|
|
71
|
+
RECONNECT_BASE_DELAY_SECONDS = 1.0
|
|
72
|
+
RECONNECT_MAX_DELAY_SECONDS = 300.0
|
|
73
|
+
# A stream that stays up this long resets reconnect backoff; shorter-lived
|
|
74
|
+
# streams (e.g. a handshake followed by an immediate close) keep backing off.
|
|
75
|
+
STABLE_CONNECTION_SECONDS = 60.0
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
async def _sleep(delay: float) -> None:
|
|
79
|
+
await asyncio.sleep(delay)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def reconnect_delay(attempt: int) -> float:
|
|
83
|
+
"""Jittered exponential backoff for reconnect attempt number `attempt`."""
|
|
84
|
+
ceiling = min(
|
|
85
|
+
RECONNECT_MAX_DELAY_SECONDS,
|
|
86
|
+
RECONNECT_BASE_DELAY_SECONDS * 2 ** min(attempt, 32),
|
|
87
|
+
)
|
|
88
|
+
return random.uniform(ceiling / 2, ceiling)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class _DeliveryState(Enum):
|
|
92
|
+
STOPPED = auto()
|
|
93
|
+
STARTING = auto()
|
|
94
|
+
STREAMING = auto()
|
|
95
|
+
POLLING = auto()
|
|
96
|
+
CONNECTING = auto()
|
|
97
|
+
RECONCILING = auto()
|
|
98
|
+
STOPPING = auto()
|
|
99
|
+
FAILED = auto()
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class ObservationDelivery:
|
|
103
|
+
"""
|
|
104
|
+
Deliver observations from the events stream, falling back to polling.
|
|
105
|
+
|
|
106
|
+
Polling continues while a reconnect attempt is pending. Once a new stream is
|
|
107
|
+
established and a current-state check succeeds, polling stops. If polling
|
|
108
|
+
exhausts its retry policy while no stream is established, `on_unavailable`
|
|
109
|
+
is called once and delivery stops.
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
def __init__(
|
|
113
|
+
self,
|
|
114
|
+
*,
|
|
115
|
+
name: str,
|
|
116
|
+
logger: logging.Logger,
|
|
117
|
+
subscriber_factory: Callable[[], PrefectEventSubscriber],
|
|
118
|
+
on_event: Callable[[Event], None],
|
|
119
|
+
check_current_state: Callable[[], Coroutine[Any, Any, None]],
|
|
120
|
+
on_unavailable: Callable[[BaseException], None],
|
|
121
|
+
polling_interval: float,
|
|
122
|
+
) -> None:
|
|
123
|
+
self._name = name
|
|
124
|
+
self._logger = logger
|
|
125
|
+
self._subscriber_factory = subscriber_factory
|
|
126
|
+
self._subscriber: PrefectEventSubscriber | None = None
|
|
127
|
+
self._on_event = on_event
|
|
128
|
+
self._check_current_state = check_current_state
|
|
129
|
+
self._on_unavailable = on_unavailable
|
|
130
|
+
self._polling_interval = polling_interval
|
|
131
|
+
self._state = _DeliveryState.STOPPED
|
|
132
|
+
self._connected = False
|
|
133
|
+
self._tasks: set[asyncio.Task[Any]] = set()
|
|
134
|
+
self._supervisor: asyncio.Task[None] | None = None
|
|
135
|
+
|
|
136
|
+
async def start(self) -> None:
|
|
137
|
+
"""Attempt the initial connection and begin streaming or polling."""
|
|
138
|
+
assert self._state is _DeliveryState.STOPPED
|
|
139
|
+
self._state = _DeliveryState.STARTING
|
|
140
|
+
consumer: asyncio.Task[None] | None = None
|
|
141
|
+
error = await self._connect()
|
|
142
|
+
if error is None:
|
|
143
|
+
consumer = self._spawn(self._consume())
|
|
144
|
+
self._state = _DeliveryState.STREAMING
|
|
145
|
+
else:
|
|
146
|
+
self._state = _DeliveryState.POLLING
|
|
147
|
+
self._logger.warning(
|
|
148
|
+
"%s failed to connect to the events stream. Falling back to"
|
|
149
|
+
" polling until it reconnects. Reason: %s",
|
|
150
|
+
self._name,
|
|
151
|
+
error,
|
|
152
|
+
)
|
|
153
|
+
self._supervisor = asyncio.create_task(self._supervise(consumer))
|
|
154
|
+
|
|
155
|
+
async def stop(self) -> None:
|
|
156
|
+
"""Stop delivery, awaiting owned work and closing the connection."""
|
|
157
|
+
self._state = _DeliveryState.STOPPING
|
|
158
|
+
if self._supervisor is not None:
|
|
159
|
+
self._supervisor.cancel()
|
|
160
|
+
await asyncio.wait([self._supervisor])
|
|
161
|
+
await self._shutdown_owned_work()
|
|
162
|
+
self._state = _DeliveryState.STOPPED
|
|
163
|
+
|
|
164
|
+
def _spawn(self, coroutine: Coroutine[Any, Any, T]) -> asyncio.Task[T]:
|
|
165
|
+
task = asyncio.create_task(coroutine)
|
|
166
|
+
self._tasks.add(task)
|
|
167
|
+
task.add_done_callback(self._tasks.discard)
|
|
168
|
+
return task
|
|
169
|
+
|
|
170
|
+
async def _shutdown_owned_work(self) -> None:
|
|
171
|
+
tasks = list(self._tasks)
|
|
172
|
+
for task in tasks:
|
|
173
|
+
task.cancel()
|
|
174
|
+
if tasks:
|
|
175
|
+
await asyncio.wait(tasks)
|
|
176
|
+
await self._disconnect()
|
|
177
|
+
|
|
178
|
+
async def _supervise(self, consumer: asyncio.Task[None] | None) -> None:
|
|
179
|
+
try:
|
|
180
|
+
error = await self._run(consumer)
|
|
181
|
+
except Exception as exc:
|
|
182
|
+
self._logger.exception("%s event delivery failed unexpectedly.", self._name)
|
|
183
|
+
error = exc
|
|
184
|
+
finally:
|
|
185
|
+
await self._shutdown_owned_work()
|
|
186
|
+
self._state = _DeliveryState.FAILED
|
|
187
|
+
self._on_unavailable(error)
|
|
188
|
+
|
|
189
|
+
async def _run(self, consumer: asyncio.Task[None] | None) -> BaseException:
|
|
190
|
+
"""Advance delivery states until neither transport is working."""
|
|
191
|
+
loop = asyncio.get_running_loop()
|
|
192
|
+
failed_attempts = 0
|
|
193
|
+
failed_checks = 0
|
|
194
|
+
poller: asyncio.Task[None] | None = None
|
|
195
|
+
while True:
|
|
196
|
+
match self._state:
|
|
197
|
+
case _DeliveryState.STREAMING:
|
|
198
|
+
assert consumer is not None
|
|
199
|
+
connected_at = loop.time()
|
|
200
|
+
await asyncio.wait([consumer])
|
|
201
|
+
self._log_stream_end(consumer)
|
|
202
|
+
await self._disconnect()
|
|
203
|
+
if loop.time() - connected_at >= STABLE_CONNECTION_SECONDS:
|
|
204
|
+
failed_attempts = 0
|
|
205
|
+
consumer = None
|
|
206
|
+
self._state = _DeliveryState.POLLING
|
|
207
|
+
|
|
208
|
+
case _DeliveryState.POLLING:
|
|
209
|
+
if poller is None:
|
|
210
|
+
poller = self._spawn(
|
|
211
|
+
critical_service_loop(
|
|
212
|
+
workload=self._check_current_state,
|
|
213
|
+
interval=self._polling_interval,
|
|
214
|
+
jitter_range=0.3,
|
|
215
|
+
)
|
|
216
|
+
)
|
|
217
|
+
delay = self._spawn(_sleep(reconnect_delay(failed_attempts)))
|
|
218
|
+
failed_attempts += 1
|
|
219
|
+
await asyncio.wait(
|
|
220
|
+
[delay, poller], return_when=asyncio.FIRST_COMPLETED
|
|
221
|
+
)
|
|
222
|
+
if poller.done():
|
|
223
|
+
return _polling_error(poller)
|
|
224
|
+
self._state = _DeliveryState.CONNECTING
|
|
225
|
+
|
|
226
|
+
case _DeliveryState.CONNECTING:
|
|
227
|
+
assert poller is not None
|
|
228
|
+
setup = self._spawn(self._connect())
|
|
229
|
+
await asyncio.wait(
|
|
230
|
+
[setup, poller], return_when=asyncio.FIRST_COMPLETED
|
|
231
|
+
)
|
|
232
|
+
if not setup.done():
|
|
233
|
+
# A pending connection is not working monitoring.
|
|
234
|
+
setup.cancel()
|
|
235
|
+
await asyncio.wait([setup])
|
|
236
|
+
return _polling_error(poller)
|
|
237
|
+
if (error := setup.result()) is not None:
|
|
238
|
+
self._logger.debug(
|
|
239
|
+
"%s failed to reconnect to the events stream: %r",
|
|
240
|
+
self._name,
|
|
241
|
+
error,
|
|
242
|
+
)
|
|
243
|
+
if poller.done():
|
|
244
|
+
return _polling_error(poller)
|
|
245
|
+
self._state = _DeliveryState.POLLING
|
|
246
|
+
else:
|
|
247
|
+
consumer = self._spawn(self._consume())
|
|
248
|
+
failed_checks = 0
|
|
249
|
+
self._state = _DeliveryState.RECONCILING
|
|
250
|
+
|
|
251
|
+
case _DeliveryState.RECONCILING:
|
|
252
|
+
assert consumer is not None and poller is not None
|
|
253
|
+
reconcile = self._spawn(self._check_current_state())
|
|
254
|
+
await asyncio.wait(
|
|
255
|
+
[consumer, reconcile], return_when=asyncio.FIRST_COMPLETED
|
|
256
|
+
)
|
|
257
|
+
if not consumer.done():
|
|
258
|
+
if (error := reconcile.exception()) is None:
|
|
259
|
+
if poller.done():
|
|
260
|
+
_polling_error(poller)
|
|
261
|
+
else:
|
|
262
|
+
poller.cancel()
|
|
263
|
+
await asyncio.wait([poller])
|
|
264
|
+
self._logger.info(
|
|
265
|
+
"%s reconnected to the events stream and stopped"
|
|
266
|
+
" polling.",
|
|
267
|
+
self._name,
|
|
268
|
+
)
|
|
269
|
+
poller = None
|
|
270
|
+
self._state = _DeliveryState.STREAMING
|
|
271
|
+
continue
|
|
272
|
+
|
|
273
|
+
# Keep the functioning stream while HTTP checks recover.
|
|
274
|
+
self._logger.debug(
|
|
275
|
+
"%s reconnected to the events stream, but could not"
|
|
276
|
+
" check the current state: %r",
|
|
277
|
+
self._name,
|
|
278
|
+
error,
|
|
279
|
+
)
|
|
280
|
+
retry = self._spawn(_sleep(reconnect_delay(failed_checks)))
|
|
281
|
+
failed_checks += 1
|
|
282
|
+
await asyncio.wait(
|
|
283
|
+
[consumer, retry], return_when=asyncio.FIRST_COMPLETED
|
|
284
|
+
)
|
|
285
|
+
if not consumer.done():
|
|
286
|
+
continue
|
|
287
|
+
retry.cancel()
|
|
288
|
+
await asyncio.wait([retry])
|
|
289
|
+
|
|
290
|
+
reconcile.cancel()
|
|
291
|
+
await asyncio.wait([reconcile])
|
|
292
|
+
self._logger.debug(
|
|
293
|
+
"%s reconnected to the events stream, but it ended before"
|
|
294
|
+
" polling stopped: %s",
|
|
295
|
+
self._name,
|
|
296
|
+
consumer.exception() or "the stream closed",
|
|
297
|
+
)
|
|
298
|
+
await self._disconnect()
|
|
299
|
+
consumer = None
|
|
300
|
+
if poller.done():
|
|
301
|
+
return _polling_error(poller)
|
|
302
|
+
self._state = _DeliveryState.POLLING
|
|
303
|
+
|
|
304
|
+
case _:
|
|
305
|
+
raise RuntimeError(f"Unexpected delivery state: {self._state}")
|
|
306
|
+
|
|
307
|
+
async def _connect(self) -> Exception | None:
|
|
308
|
+
"""Open the stream within the setup deadline, returning any failure."""
|
|
309
|
+
try:
|
|
310
|
+
if self._subscriber is None:
|
|
311
|
+
self._subscriber = self._subscriber_factory()
|
|
312
|
+
async with asyncio.timeout(SETUP_TIMEOUT_SECONDS):
|
|
313
|
+
await self._subscriber.__aenter__()
|
|
314
|
+
self._connected = True
|
|
315
|
+
except Exception as exc:
|
|
316
|
+
await self._disconnect()
|
|
317
|
+
return exc
|
|
318
|
+
return None
|
|
319
|
+
|
|
320
|
+
async def _disconnect(self) -> None:
|
|
321
|
+
if not self._connected or self._subscriber is None:
|
|
322
|
+
return
|
|
323
|
+
try:
|
|
324
|
+
await self._subscriber.__aexit__(None, None, None)
|
|
325
|
+
except Exception:
|
|
326
|
+
self._logger.debug(
|
|
327
|
+
"%s failed to close the events stream.", self._name, exc_info=True
|
|
328
|
+
)
|
|
329
|
+
# Left set if closing is cancelled so that final cleanup retries it
|
|
330
|
+
self._connected = False
|
|
331
|
+
|
|
332
|
+
async def _consume(self) -> None:
|
|
333
|
+
assert self._subscriber is not None
|
|
334
|
+
async for event in self._subscriber:
|
|
335
|
+
self._on_event(event)
|
|
336
|
+
|
|
337
|
+
def _log_stream_end(self, consumer: asyncio.Task[None]) -> None:
|
|
338
|
+
if error := consumer.exception():
|
|
339
|
+
self._logger.warning(
|
|
340
|
+
"The %s websocket failed with an exception. Switching to polling"
|
|
341
|
+
" mode until it reconnects.",
|
|
342
|
+
self._name,
|
|
343
|
+
exc_info=error,
|
|
344
|
+
)
|
|
345
|
+
else:
|
|
346
|
+
self._logger.warning(
|
|
347
|
+
"The %s websocket closed. Switching to polling mode until it"
|
|
348
|
+
" reconnects.",
|
|
349
|
+
self._name,
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
def _polling_error(poller: asyncio.Task[None]) -> BaseException:
|
|
354
|
+
return poller.exception() or RuntimeError("Polling stopped unexpectedly.")
|