prefect-client 3.8.3.dev3__tar.gz → 3.8.4.dev2__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.3.dev3 → prefect_client-3.8.4.dev2}/PKG-INFO +1 -1
- prefect_client-3.8.4.dev2/src/prefect/_build_info.py +5 -0
- prefect_client-3.8.4.dev2/src/prefect/_internal/attempt_control.py +158 -0
- prefect_client-3.8.4.dev2/src/prefect/_internal/control_listener.py +457 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/engine.py +11 -3
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/flow_engine.py +203 -164
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/AGENTS.md +11 -8
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/_cancellation_manager.py +12 -1
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/_control_channel.py +212 -90
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/_flow_run_executor.py +52 -18
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/_scheduled_run_poller.py +5 -1
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/_starter_bundle.py +2 -1
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/runner.py +118 -107
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/workers/AGENTS.md +2 -2
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/workers/process.py +55 -22
- prefect_client-3.8.3.dev3/src/prefect/_build_info.py +0 -5
- prefect_client-3.8.3.dev3/src/prefect/_internal/control_listener.py +0 -225
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/.gitignore +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/LICENSE +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/README.md +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/hatch_build.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/pyproject.toml +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/.prefectignore +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/AGENTS.md +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/__main__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_experimental/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_experimental/_launchers.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_experimental/bundles/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_experimental/bundles/execute.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_experimental/plugins/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_experimental/plugins/apply.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_experimental/plugins/diagnostics.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_experimental/plugins/manager.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_experimental/plugins/spec.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_experimental/sla/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_experimental/sla/client.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_experimental/sla/objects.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_flow_run_suspension.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/_logging.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/analytics/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/analytics/ci_detection.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/analytics/client.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/analytics/device_id.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/analytics/emit.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/analytics/enabled.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/analytics/events.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/analytics/milestones.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/analytics/notice.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/analytics/service.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/ast_utils.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/buildx.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/compatibility/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/compatibility/async_dispatch.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/compatibility/backports.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/compatibility/blocks.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/compatibility/deprecated.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/compatibility/deprecated_paths.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/compatibility/migration.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/compatibility/starlette.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/concurrency/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/concurrency/api.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/concurrency/calls.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/concurrency/cancellation.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/concurrency/event_loop.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/concurrency/inspection.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/concurrency/primitives.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/concurrency/services.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/concurrency/threads.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/concurrency/waiters.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/deprecated.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/engine.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/git.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/infrastructure_exit_codes.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/installation.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/integrations.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/launchers.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/lazy.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/metrics.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/observability.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/observers.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/plugins/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/plugins/apply.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/plugins/collections.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/plugins/diagnostics.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/plugins/manager.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/plugins/spec.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/plugins/startup.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/pydantic/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/pydantic/schemas.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/pydantic/v1_schema.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/pydantic/v2_schema.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/pydantic/validated_func.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/pytz.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/result_records.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/retries.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/schema.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/schemas/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/schemas/_registry.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/schemas/bases.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/schemas/fields.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/schemas/serializers.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/schemas/validators.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/send_entrypoint_logs.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/states.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/testing.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/urls.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/uuid7.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/version_checking.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/versioning.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/waiters.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_internal/websockets.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_sdk/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_sdk/fetcher.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_sdk/generator.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_sdk/models.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_sdk/naming.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_sdk/renderer.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_sdk/schema_converter.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_sdk/templates/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_sdk/templates/sdk.py.jinja +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_sdk/types.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_sdk/unions.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_vendor/croniter/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/_vendor/croniter/croniter.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/agent.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/analytics/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/artifacts.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/assets/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/assets/core.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/assets/materialize.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/automations.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/blocks/AGENTS.md +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/blocks/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/blocks/abstract.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/blocks/core.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/blocks/fields.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/blocks/notifications.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/blocks/redis.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/blocks/system.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/blocks/webhook.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/bundles/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/bundles/_file_collector.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/bundles/_ignore_filter.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/bundles/_path_resolver.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/bundles/_zip_builder.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/bundles/_zip_extractor.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/bundles/execute.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/cache_policies.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/AGENTS.md +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/attribution.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/base.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/cloud.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/collections.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/constants.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_artifacts/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_artifacts/client.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_automations/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_automations/client.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_blocks_documents/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_blocks_documents/client.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_blocks_schemas/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_blocks_schemas/client.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_blocks_types/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_blocks_types/client.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_concurrency_limits/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_concurrency_limits/client.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_deployments/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_deployments/client.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_events/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_events/client.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_flow_runs/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_flow_runs/client.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_flows/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_flows/client.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_logs/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_logs/client.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_variables/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_variables/client.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_work_pools/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/_work_pools/client.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/base.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/orchestration/routes.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/schemas/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/schemas/actions.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/schemas/events.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/schemas/filters.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/schemas/objects.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/schemas/responses.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/schemas/schedules.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/schemas/sorting.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/schemas/worker_channel.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/subscriptions.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/types/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/types/flexible_schedule_list.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/client/utilities.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/concurrency/AGENTS.md +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/concurrency/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/concurrency/_asyncio.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/concurrency/_events.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/concurrency/_leases.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/concurrency/_sync.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/concurrency/asyncio.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/concurrency/context.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/concurrency/services.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/concurrency/sync.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/concurrency/v1/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/concurrency/v1/_asyncio.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/concurrency/v1/_events.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/concurrency/v1/asyncio.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/concurrency/v1/context.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/concurrency/v1/services.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/concurrency/v1/sync.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/context.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/deployments/AGENTS.md +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/deployments/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/deployments/base.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/deployments/deployments.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/deployments/flow_runs.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/deployments/runner.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/deployments/schedules.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/deployments/steps/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/deployments/steps/core.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/deployments/steps/pull.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/deployments/steps/utility.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/docker/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/docker/_buildx.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/docker/docker_image.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/events/AGENTS.md +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/events/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/events/actions.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/events/clients.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/events/filters.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/events/related.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/events/schemas/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/events/schemas/automations.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/events/schemas/deployment_triggers.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/events/schemas/events.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/events/schemas/labelling.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/events/subscribers.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/events/utilities.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/events/worker.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/exceptions.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/filesystems.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/flow_runs.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/flows.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/futures.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/infrastructure/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/infrastructure/base.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/infrastructure/provisioners/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/infrastructure/provisioners/cloud_run.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/infrastructure/provisioners/coiled.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/infrastructure/provisioners/container_instance.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/infrastructure/provisioners/ecs.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/infrastructure/provisioners/modal.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/input/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/input/actions.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/input/run_input.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/locking/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/locking/_filelock.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/locking/filesystem.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/locking/memory.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/locking/protocol.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/logging/AGENTS.md +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/logging/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/logging/clients.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/logging/configuration.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/logging/filters.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/logging/formatters.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/logging/handlers.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/logging/highlighters.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/logging/loggers.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/logging/logging.yml +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/main.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/plugins.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/py.typed +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/results.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/_cancel_finalizer.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/_deployment_registry.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/_event_emitter.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/_flow_resolver.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/_hook_runner.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/_limit_manager.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/_process_manager.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/_starter_direct.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/_starter_engine.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/_state_proposer.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/_uv_command.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/_workspace_resolver.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/_workspace_starter.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/server.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runner/storage.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runtime/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runtime/deployment.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runtime/flow_run.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/runtime/task_run.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/schedules.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/serializers.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/_ui_static.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/admin.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/artifacts.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/automations.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/background_workers.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/block_capabilities.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/block_documents.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/block_schemas.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/block_types.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/clients.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/collections.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/collections_data/views/aggregate-worker-metadata.json +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/concurrency_limits.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/concurrency_limits_v2.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/csrf_token.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/dependencies.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/deployments.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/events.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/flow_run_states.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/flow_runs.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/flows.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/logs.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/middleware.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/root.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/run_history.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/saved_searches.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/server.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/static/prefect-logo-mark-gradient.png +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/task_run_states.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/task_runs.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/task_workers.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/templates.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/ui/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/ui/flow_runs.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/ui/flows.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/ui/schemas.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/ui/task_runs.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/validation.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/variables.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/work_queues.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/server/api/workers.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/AGENTS.md +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/_types.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/base.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/constants.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/context.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/legacy.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/_defaults.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/api.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/cli.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/client.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/cloud.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/deployments.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/events.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/experiments.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/flows.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/internal.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/logging.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/plugins.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/results.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/root.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/runner.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/server/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/server/api.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/server/concurrency.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/server/database.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/server/deployments.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/server/docket.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/server/ephemeral.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/server/events.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/server/flow_run_graph.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/server/logs.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/server/root.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/server/services.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/server/tasks.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/server/ui.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/server/worker_channel.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/tasks.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/telemetry.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/testing.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/models/worker.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/profiles.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/profiles.toml +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/settings/sources.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/states.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/task_engine.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/task_runners.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/task_runs.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/task_worker.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/tasks.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/telemetry/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/telemetry/run_telemetry.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/transactions.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/types/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/types/_concurrency.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/types/_datetime.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/types/entrypoint.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/types/names.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/AGENTS.md +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/annotations.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/asyncutils/AGENTS.md +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/asyncutils/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/callables/AGENTS.md +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/callables/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/collections.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/compat.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/context.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/dispatch.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/dockerutils.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/engine/AGENTS.md +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/engine/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/filesystem/AGENTS.md +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/filesystem/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/generics.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/hashing.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/importtools.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/math.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/names.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/processutils/AGENTS.md +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/processutils/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/pydantic.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/render_swagger.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/schema_tools/AGENTS.md +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/schema_tools/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/schema_tools/hydration.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/schema_tools/validation.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/services.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/slugify.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/templating/AGENTS.md +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/templating/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/text.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/timeout.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/urls.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/utilities/visualization.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/variables.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/workers/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/workers/_cleanup.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/workers/_cleanup_handlers.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/workers/_worker_channel/__init__.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/workers/_worker_channel/_protocol.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/workers/_worker_channel/_state.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/workers/_worker_channel/_sync.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/workers/_worker_channel/_transport.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/workers/base.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/workers/block.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/workers/cloud.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/workers/server.py +0 -0
- {prefect_client-3.8.3.dev3 → prefect_client-3.8.4.dev2}/src/prefect/workers/utilities.py +0 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"""Shared types and wire framing for the internal Attempt Control Session."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import struct
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from enum import Enum
|
|
9
|
+
from typing import Literal, TypeAlias
|
|
10
|
+
from uuid import UUID
|
|
11
|
+
|
|
12
|
+
Intent = Literal["cancel", "reschedule", "relinquish"]
|
|
13
|
+
|
|
14
|
+
BYTE_FOR_INTENT: dict[Intent, bytes] = {
|
|
15
|
+
"cancel": b"c",
|
|
16
|
+
"reschedule": b"r",
|
|
17
|
+
"relinquish": b"q",
|
|
18
|
+
}
|
|
19
|
+
INTENT_FOR_BYTE: dict[bytes, Intent] = {
|
|
20
|
+
value: key for key, value in BYTE_FOR_INTENT.items()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
LEGACY_PROTOCOL_VERSION = 1
|
|
24
|
+
CURRENT_PROTOCOL_VERSION = 2
|
|
25
|
+
RECEIPT_CAPABILITY = 1 << 0
|
|
26
|
+
|
|
27
|
+
# The child-initiated hello deliberately contains no legacy acknowledgement byte
|
|
28
|
+
# (`b"a"`), so a version-one supervisor can safely ignore it.
|
|
29
|
+
NEGOTIATION_PREFIX = b"\x00PF"
|
|
30
|
+
NEGOTIATION_FRAME_SIZE = len(NEGOTIATION_PREFIX) + 2
|
|
31
|
+
RECEIPT_PREFIX = b"\x01"
|
|
32
|
+
RECEIPT_ACK = b"\x02"
|
|
33
|
+
MAX_RECEIPT_SIZE = 4096
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class EngineDisposition(str, Enum):
|
|
37
|
+
STATE_REPORTED = "STATE_REPORTED"
|
|
38
|
+
ORCHESTRATION_ABORTED = "ORCHESTRATION_ABORTED"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass(frozen=True)
|
|
42
|
+
class EngineOutcomeReceipt:
|
|
43
|
+
"""Sanitized evidence that an engine concluded an execution attempt."""
|
|
44
|
+
|
|
45
|
+
disposition: EngineDisposition
|
|
46
|
+
state_id: UUID | None = None
|
|
47
|
+
state_type: str | None = None
|
|
48
|
+
state_name: str | None = None
|
|
49
|
+
|
|
50
|
+
def __post_init__(self) -> None:
|
|
51
|
+
if not isinstance(self.disposition, EngineDisposition):
|
|
52
|
+
raise TypeError("Receipt disposition must be an EngineDisposition")
|
|
53
|
+
state_fields = (self.state_id, self.state_type, self.state_name)
|
|
54
|
+
if self.disposition is EngineDisposition.STATE_REPORTED:
|
|
55
|
+
if any(value is None for value in state_fields):
|
|
56
|
+
raise ValueError("STATE_REPORTED receipts require all state fields")
|
|
57
|
+
if not isinstance(self.state_id, UUID):
|
|
58
|
+
raise TypeError("Receipt state ID must be a UUID")
|
|
59
|
+
if not isinstance(self.state_type, str) or not isinstance(
|
|
60
|
+
self.state_name, str
|
|
61
|
+
):
|
|
62
|
+
raise TypeError("Receipt state type and name must be strings")
|
|
63
|
+
if not self.state_type:
|
|
64
|
+
raise ValueError("Receipt state type must not be empty")
|
|
65
|
+
if len(self.state_type) > 64:
|
|
66
|
+
raise ValueError("Receipt state type is too long")
|
|
67
|
+
elif any(value is not None for value in state_fields):
|
|
68
|
+
raise ValueError(
|
|
69
|
+
"ORCHESTRATION_ABORTED receipts cannot include state fields"
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
@classmethod
|
|
73
|
+
def state_reported(
|
|
74
|
+
cls, *, state_id: UUID, state_type: str, state_name: str
|
|
75
|
+
) -> EngineOutcomeReceipt:
|
|
76
|
+
return cls(
|
|
77
|
+
disposition=EngineDisposition.STATE_REPORTED,
|
|
78
|
+
state_id=state_id,
|
|
79
|
+
state_type=state_type,
|
|
80
|
+
state_name=state_name,
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
@classmethod
|
|
84
|
+
def orchestration_aborted(cls) -> EngineOutcomeReceipt:
|
|
85
|
+
return cls(disposition=EngineDisposition.ORCHESTRATION_ABORTED)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@dataclass(frozen=True)
|
|
89
|
+
class StateOwnershipDelegation:
|
|
90
|
+
"""Evidence that the supervisor's acknowledged control intent won."""
|
|
91
|
+
|
|
92
|
+
intent: Intent
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
AttemptConclusion: TypeAlias = EngineOutcomeReceipt | StateOwnershipDelegation
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def encode_negotiation(version: int, capabilities: int) -> bytes:
|
|
99
|
+
if not 0 <= version <= 255 or not 0 <= capabilities <= 255:
|
|
100
|
+
raise ValueError("Protocol version and capabilities must fit in one byte")
|
|
101
|
+
return NEGOTIATION_PREFIX + bytes((version, capabilities))
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def decode_negotiation(frame: bytes) -> tuple[int, int]:
|
|
105
|
+
if len(frame) != NEGOTIATION_FRAME_SIZE or not frame.startswith(NEGOTIATION_PREFIX):
|
|
106
|
+
raise ValueError("Malformed Attempt Control Session negotiation")
|
|
107
|
+
return frame[-2], frame[-1]
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def encode_receipt(receipt: EngineOutcomeReceipt) -> bytes:
|
|
111
|
+
payload: dict[str, str] = {"disposition": receipt.disposition.value}
|
|
112
|
+
if receipt.disposition is EngineDisposition.STATE_REPORTED:
|
|
113
|
+
assert receipt.state_id is not None
|
|
114
|
+
assert receipt.state_type is not None
|
|
115
|
+
assert receipt.state_name is not None
|
|
116
|
+
payload.update(
|
|
117
|
+
{
|
|
118
|
+
"state_id": str(receipt.state_id),
|
|
119
|
+
"state_type": receipt.state_type,
|
|
120
|
+
"state_name": receipt.state_name,
|
|
121
|
+
}
|
|
122
|
+
)
|
|
123
|
+
encoded = json.dumps(payload, separators=(",", ":"), sort_keys=True).encode()
|
|
124
|
+
if len(encoded) > MAX_RECEIPT_SIZE:
|
|
125
|
+
raise ValueError("Receipt payload is too large")
|
|
126
|
+
return RECEIPT_PREFIX + struct.pack("!I", len(encoded)) + encoded
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def decode_receipt(payload: bytes) -> EngineOutcomeReceipt:
|
|
130
|
+
if len(payload) > MAX_RECEIPT_SIZE:
|
|
131
|
+
raise ValueError("Receipt payload is too large")
|
|
132
|
+
try:
|
|
133
|
+
decoded = json.loads(payload)
|
|
134
|
+
except (UnicodeDecodeError, json.JSONDecodeError) as exc:
|
|
135
|
+
raise ValueError("Malformed receipt payload") from exc
|
|
136
|
+
if not isinstance(decoded, dict):
|
|
137
|
+
raise TypeError("Receipt payload must be an object")
|
|
138
|
+
|
|
139
|
+
try:
|
|
140
|
+
disposition = EngineDisposition(decoded["disposition"])
|
|
141
|
+
except (KeyError, TypeError, ValueError) as exc:
|
|
142
|
+
raise ValueError("Receipt disposition is invalid") from exc
|
|
143
|
+
|
|
144
|
+
if disposition is EngineDisposition.ORCHESTRATION_ABORTED:
|
|
145
|
+
if set(decoded) != {"disposition"}:
|
|
146
|
+
raise ValueError("Aborted receipt contains unexpected fields")
|
|
147
|
+
return EngineOutcomeReceipt.orchestration_aborted()
|
|
148
|
+
|
|
149
|
+
if set(decoded) != {"disposition", "state_id", "state_type", "state_name"}:
|
|
150
|
+
raise ValueError("State receipt fields are invalid")
|
|
151
|
+
try:
|
|
152
|
+
return EngineOutcomeReceipt.state_reported(
|
|
153
|
+
state_id=UUID(decoded["state_id"]),
|
|
154
|
+
state_type=decoded["state_type"],
|
|
155
|
+
state_name=decoded["state_name"],
|
|
156
|
+
)
|
|
157
|
+
except (AttributeError, TypeError, ValueError) as exc:
|
|
158
|
+
raise ValueError("State receipt fields are invalid") from exc
|
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Child side of the internal Attempt Control Session.
|
|
3
|
+
|
|
4
|
+
This module is intentionally small. It only supports steady-state graceful
|
|
5
|
+
control delivery after Prefect has already installed its SIGTERM bridge via
|
|
6
|
+
`capture_sigterm()`.
|
|
7
|
+
|
|
8
|
+
The version-one protocol remains intact: the supervisor sends one-byte control
|
|
9
|
+
intents and the child acknowledges a committed intent with `b"a"`. Version-two
|
|
10
|
+
peers additionally negotiate outcome receipts over the same authenticated,
|
|
11
|
+
full-duplex loopback connection.
|
|
12
|
+
|
|
13
|
+
Session outline:
|
|
14
|
+
|
|
15
|
+
1. The runner injects `PREFECT__CONTROL_PORT` and `PREFECT__CONTROL_TOKEN`
|
|
16
|
+
into the child environment.
|
|
17
|
+
2. Process entrypoints call `configure_from_env()` early to consume those
|
|
18
|
+
one-shot env vars without connecting yet.
|
|
19
|
+
3. The outermost `capture_sigterm()` calls `start()`, which connects back to
|
|
20
|
+
the runner and spawns a daemon thread blocked on the socket.
|
|
21
|
+
4. The child sends a reserved negotiation hello. A version-one supervisor
|
|
22
|
+
ignores it; a version-two supervisor selects the protocol and capabilities.
|
|
23
|
+
5. The first terminal exchange is either an existing control intent plus
|
|
24
|
+
`b"a"`, or a structured engine outcome receipt plus a receipt ack.
|
|
25
|
+
6. For control, the runner then sends its normal external termination signal.
|
|
26
|
+
On POSIX, that real `SIGTERM` remains the only trigger that interrupts
|
|
27
|
+
blocking code.
|
|
28
|
+
|
|
29
|
+
If the child is not connected yet, or can no longer safely acknowledge the
|
|
30
|
+
intent, the runner sees no ack and falls back to its existing crash-style
|
|
31
|
+
termination path. There is deliberately no startup-time graceful cancellation
|
|
32
|
+
contract in this implementation.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
from __future__ import annotations
|
|
36
|
+
|
|
37
|
+
import _thread
|
|
38
|
+
import os
|
|
39
|
+
import signal
|
|
40
|
+
import socket
|
|
41
|
+
import threading
|
|
42
|
+
import time
|
|
43
|
+
|
|
44
|
+
from prefect._internal.attempt_control import (
|
|
45
|
+
CURRENT_PROTOCOL_VERSION,
|
|
46
|
+
INTENT_FOR_BYTE,
|
|
47
|
+
NEGOTIATION_FRAME_SIZE,
|
|
48
|
+
NEGOTIATION_PREFIX,
|
|
49
|
+
RECEIPT_ACK,
|
|
50
|
+
RECEIPT_CAPABILITY,
|
|
51
|
+
EngineOutcomeReceipt,
|
|
52
|
+
Intent,
|
|
53
|
+
decode_negotiation,
|
|
54
|
+
encode_negotiation,
|
|
55
|
+
encode_receipt,
|
|
56
|
+
)
|
|
57
|
+
from prefect.logging import get_logger
|
|
58
|
+
from prefect.utilities.engine import commit_control_intent_and_ack
|
|
59
|
+
|
|
60
|
+
_NEGOTIATION_PROBE_TIMEOUT = 0.25
|
|
61
|
+
_NEGOTIATION_RESPONSE_TIMEOUT = 1.0
|
|
62
|
+
_RECEIPT_ACK_TIMEOUT = 1.0
|
|
63
|
+
|
|
64
|
+
_logger = get_logger(__name__)
|
|
65
|
+
|
|
66
|
+
_intent: Intent | None = None
|
|
67
|
+
_intent_lock = threading.Lock()
|
|
68
|
+
|
|
69
|
+
_configured = False
|
|
70
|
+
_configured_port: int | None = None
|
|
71
|
+
_configured_token: str | None = None
|
|
72
|
+
|
|
73
|
+
_started = False
|
|
74
|
+
_started_lock = threading.Lock()
|
|
75
|
+
_owner_thread_id: int | None = None
|
|
76
|
+
_socket: socket.socket | None = None
|
|
77
|
+
_reader_thread: threading.Thread | None = None
|
|
78
|
+
_send_lock = threading.Lock()
|
|
79
|
+
_negotiation_complete = threading.Event()
|
|
80
|
+
_negotiation_deadline: float | None = None
|
|
81
|
+
_receipt_acked = threading.Event()
|
|
82
|
+
_receipt_capable = False
|
|
83
|
+
_terminal_lock = threading.Lock()
|
|
84
|
+
_terminal_claimed = False
|
|
85
|
+
_receipt_in_flight = False
|
|
86
|
+
_outcome_report_started = False
|
|
87
|
+
_engine_outcome_handled = False
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def get_intent() -> Intent | None:
|
|
91
|
+
"""Return the committed control intent, if any."""
|
|
92
|
+
with _intent_lock:
|
|
93
|
+
return _intent
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def engine_outcome_is_handled() -> bool:
|
|
97
|
+
"""Return whether the engine concluded the current execution attempt."""
|
|
98
|
+
return _engine_outcome_handled
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def _set_intent(value: Intent) -> None:
|
|
102
|
+
global _intent
|
|
103
|
+
with _intent_lock:
|
|
104
|
+
_intent = value
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def _clear_intent() -> None:
|
|
108
|
+
global _intent
|
|
109
|
+
with _intent_lock:
|
|
110
|
+
_intent = None
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def clear_intent() -> None:
|
|
114
|
+
"""Clear the committed control intent after the current session consumes it."""
|
|
115
|
+
_clear_intent()
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def configure_from_env() -> None:
|
|
119
|
+
"""Consume one-shot control-channel env vars without connecting yet."""
|
|
120
|
+
global _configured, _configured_port, _configured_token, _engine_outcome_handled
|
|
121
|
+
|
|
122
|
+
with _started_lock:
|
|
123
|
+
if _configured:
|
|
124
|
+
return
|
|
125
|
+
|
|
126
|
+
_configured = True
|
|
127
|
+
_engine_outcome_handled = False
|
|
128
|
+
port_str = os.environ.pop("PREFECT__CONTROL_PORT", None)
|
|
129
|
+
token = os.environ.pop("PREFECT__CONTROL_TOKEN", None)
|
|
130
|
+
if not port_str or not token:
|
|
131
|
+
return
|
|
132
|
+
|
|
133
|
+
try:
|
|
134
|
+
_configured_port = int(port_str)
|
|
135
|
+
except ValueError:
|
|
136
|
+
_configured_port = None
|
|
137
|
+
_configured_token = None
|
|
138
|
+
return
|
|
139
|
+
|
|
140
|
+
_configured_token = token
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def _acknowledge_intent(sock: socket.socket, intent: Intent) -> bool:
|
|
144
|
+
"""Commit intent and acknowledge it to the runner."""
|
|
145
|
+
return commit_control_intent_and_ack(
|
|
146
|
+
commit_intent=lambda: _set_intent(intent),
|
|
147
|
+
clear_intent=_clear_intent,
|
|
148
|
+
send_ack=lambda: sock.sendall(b"a"),
|
|
149
|
+
trigger_cancel=(
|
|
150
|
+
(lambda: _thread.interrupt_main(signal.SIGTERM))
|
|
151
|
+
if os.name == "nt"
|
|
152
|
+
else None
|
|
153
|
+
),
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _send(sock: socket.socket, data: bytes) -> None:
|
|
158
|
+
with _send_lock:
|
|
159
|
+
sock.sendall(data)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def _recv_exactly(sock: socket.socket, size: int) -> bytes:
|
|
163
|
+
chunks = bytearray()
|
|
164
|
+
while len(chunks) < size:
|
|
165
|
+
chunk = sock.recv(size - len(chunks))
|
|
166
|
+
if not chunk:
|
|
167
|
+
raise OSError("Control session closed")
|
|
168
|
+
chunks.extend(chunk)
|
|
169
|
+
return bytes(chunks)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def _receive_negotiation_response(sock: socket.socket, first: bytes) -> None:
|
|
173
|
+
"""Apply one complete negotiation response from the supervisor."""
|
|
174
|
+
global _receipt_capable
|
|
175
|
+
|
|
176
|
+
response = first + _recv_exactly(sock, NEGOTIATION_FRAME_SIZE - 1)
|
|
177
|
+
version, capabilities = decode_negotiation(response)
|
|
178
|
+
_receipt_capable = (
|
|
179
|
+
version == CURRENT_PROTOCOL_VERSION and capabilities & RECEIPT_CAPABILITY != 0
|
|
180
|
+
)
|
|
181
|
+
_negotiation_complete.set()
|
|
182
|
+
_logger.debug(
|
|
183
|
+
"Attempt control negotiation selected protocol %d with receipt support %s",
|
|
184
|
+
version,
|
|
185
|
+
_receipt_capable,
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def _handle_intent_byte(sock: socket.socket, data: bytes) -> bool | None:
|
|
190
|
+
"""Handle an intent, returning whether the reader should close the session."""
|
|
191
|
+
global _terminal_claimed
|
|
192
|
+
|
|
193
|
+
intent = INTENT_FOR_BYTE.get(data)
|
|
194
|
+
if intent is None:
|
|
195
|
+
return None
|
|
196
|
+
|
|
197
|
+
# Serialize terminal writes so the wire order matches the local decision:
|
|
198
|
+
# an intent that claims this lock before receipt transmission wins, while
|
|
199
|
+
# an already-transmitted receipt remains authoritative.
|
|
200
|
+
with _send_lock, _terminal_lock:
|
|
201
|
+
if _terminal_claimed or _receipt_in_flight:
|
|
202
|
+
_logger.debug(
|
|
203
|
+
"Ignoring control intent after a terminal exchange has started"
|
|
204
|
+
)
|
|
205
|
+
return False
|
|
206
|
+
if _acknowledge_intent(sock, intent):
|
|
207
|
+
_terminal_claimed = True
|
|
208
|
+
return True
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def _reader_loop(sock: socket.socket) -> None:
|
|
212
|
+
"""Negotiate receipt support, then handle session responses and intent."""
|
|
213
|
+
global _receipt_capable
|
|
214
|
+
|
|
215
|
+
negotiation_pending = True
|
|
216
|
+
try:
|
|
217
|
+
first = b""
|
|
218
|
+
try:
|
|
219
|
+
_send(
|
|
220
|
+
sock,
|
|
221
|
+
encode_negotiation(CURRENT_PROTOCOL_VERSION, RECEIPT_CAPABILITY),
|
|
222
|
+
)
|
|
223
|
+
sock.settimeout(_NEGOTIATION_PROBE_TIMEOUT)
|
|
224
|
+
first = sock.recv(1)
|
|
225
|
+
if not first:
|
|
226
|
+
return
|
|
227
|
+
intent_handled = _handle_intent_byte(sock, first)
|
|
228
|
+
if intent_handled is not None:
|
|
229
|
+
if intent_handled:
|
|
230
|
+
return
|
|
231
|
+
first = b""
|
|
232
|
+
if first != NEGOTIATION_PREFIX[:1]:
|
|
233
|
+
_logger.warning("Attempt control negotiation response was malformed")
|
|
234
|
+
return
|
|
235
|
+
_receive_negotiation_response(sock, first)
|
|
236
|
+
negotiation_pending = False
|
|
237
|
+
except TimeoutError:
|
|
238
|
+
if first:
|
|
239
|
+
_logger.warning("Attempt control negotiation response was malformed")
|
|
240
|
+
# A version-one supervisor sends no response to the reserved hello.
|
|
241
|
+
# Keep accepting a late response so scheduler latency does not
|
|
242
|
+
# permanently downgrade a version-two peer.
|
|
243
|
+
_receipt_capable = False
|
|
244
|
+
except OSError:
|
|
245
|
+
# The owning context may close the socket while negotiation is blocked.
|
|
246
|
+
return
|
|
247
|
+
except ValueError:
|
|
248
|
+
_logger.warning("Attempt control negotiation response was malformed")
|
|
249
|
+
return
|
|
250
|
+
finally:
|
|
251
|
+
try:
|
|
252
|
+
sock.settimeout(None)
|
|
253
|
+
except OSError:
|
|
254
|
+
pass
|
|
255
|
+
|
|
256
|
+
while True:
|
|
257
|
+
try:
|
|
258
|
+
data = sock.recv(1)
|
|
259
|
+
except OSError:
|
|
260
|
+
return
|
|
261
|
+
if not data:
|
|
262
|
+
return
|
|
263
|
+
intent_handled = _handle_intent_byte(sock, data)
|
|
264
|
+
if intent_handled is not None:
|
|
265
|
+
if intent_handled:
|
|
266
|
+
return
|
|
267
|
+
continue
|
|
268
|
+
if data == NEGOTIATION_PREFIX[:1] and negotiation_pending:
|
|
269
|
+
try:
|
|
270
|
+
_receive_negotiation_response(sock, data)
|
|
271
|
+
except OSError:
|
|
272
|
+
return
|
|
273
|
+
except ValueError:
|
|
274
|
+
_logger.warning(
|
|
275
|
+
"Attempt control negotiation response was malformed"
|
|
276
|
+
)
|
|
277
|
+
return
|
|
278
|
+
negotiation_pending = False
|
|
279
|
+
continue
|
|
280
|
+
if data == RECEIPT_ACK:
|
|
281
|
+
global _receipt_in_flight, _terminal_claimed
|
|
282
|
+
with _terminal_lock:
|
|
283
|
+
if not _receipt_in_flight:
|
|
284
|
+
_logger.debug(
|
|
285
|
+
"Ignoring receipt acknowledgement after terminal exchange"
|
|
286
|
+
)
|
|
287
|
+
continue
|
|
288
|
+
_receipt_in_flight = False
|
|
289
|
+
_terminal_claimed = True
|
|
290
|
+
_receipt_acked.set()
|
|
291
|
+
return
|
|
292
|
+
_logger.warning("Attempt control session received a malformed message")
|
|
293
|
+
return
|
|
294
|
+
finally:
|
|
295
|
+
_negotiation_complete.set()
|
|
296
|
+
try:
|
|
297
|
+
sock.close()
|
|
298
|
+
except OSError:
|
|
299
|
+
pass
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
def report_engine_outcome(receipt: EngineOutcomeReceipt) -> bool:
|
|
303
|
+
"""Send one negotiated outcome receipt without changing engine semantics."""
|
|
304
|
+
global _outcome_report_started, _receipt_in_flight, _engine_outcome_handled
|
|
305
|
+
|
|
306
|
+
if _owner_thread_id is not None and threading.get_ident() != _owner_thread_id:
|
|
307
|
+
_logger.debug(
|
|
308
|
+
"Ignoring engine outcome from a thread that does not own the control session"
|
|
309
|
+
)
|
|
310
|
+
return False
|
|
311
|
+
|
|
312
|
+
# The immediate first-party engine process treats a concluded attempt as
|
|
313
|
+
# successful infrastructure execution even when its supervisor cannot
|
|
314
|
+
# negotiate or acknowledge the optional receipt transport.
|
|
315
|
+
_engine_outcome_handled = True
|
|
316
|
+
|
|
317
|
+
sock = _socket
|
|
318
|
+
if sock is None:
|
|
319
|
+
return False
|
|
320
|
+
|
|
321
|
+
negotiation_deadline = _negotiation_deadline
|
|
322
|
+
if negotiation_deadline is not None:
|
|
323
|
+
_negotiation_complete.wait(max(0.0, negotiation_deadline - time.monotonic()))
|
|
324
|
+
if not _receipt_capable:
|
|
325
|
+
return False
|
|
326
|
+
|
|
327
|
+
try:
|
|
328
|
+
encoded_receipt = encode_receipt(receipt)
|
|
329
|
+
except ValueError:
|
|
330
|
+
_logger.warning("Failed to encode engine outcome receipt")
|
|
331
|
+
return False
|
|
332
|
+
|
|
333
|
+
try:
|
|
334
|
+
with _send_lock, _terminal_lock:
|
|
335
|
+
if _terminal_claimed or _outcome_report_started:
|
|
336
|
+
return False
|
|
337
|
+
_outcome_report_started = True
|
|
338
|
+
_receipt_in_flight = True
|
|
339
|
+
_receipt_acked.clear()
|
|
340
|
+
sock.sendall(encoded_receipt)
|
|
341
|
+
except OSError:
|
|
342
|
+
with _terminal_lock:
|
|
343
|
+
_receipt_in_flight = False
|
|
344
|
+
_logger.warning("Failed to send engine outcome receipt")
|
|
345
|
+
return False
|
|
346
|
+
|
|
347
|
+
if _receipt_acked.wait(_RECEIPT_ACK_TIMEOUT):
|
|
348
|
+
return True
|
|
349
|
+
|
|
350
|
+
with _terminal_lock:
|
|
351
|
+
_receipt_in_flight = False
|
|
352
|
+
_logger.warning("Engine outcome receipt was not acknowledged")
|
|
353
|
+
return False
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
def start() -> None:
|
|
357
|
+
"""Connect to the runner's control channel if bootstrap config is present."""
|
|
358
|
+
global _started, _owner_thread_id, _socket, _reader_thread, _receipt_capable
|
|
359
|
+
global _terminal_claimed, _receipt_in_flight, _outcome_report_started
|
|
360
|
+
global _negotiation_deadline
|
|
361
|
+
|
|
362
|
+
configure_from_env()
|
|
363
|
+
|
|
364
|
+
with _started_lock:
|
|
365
|
+
if _started:
|
|
366
|
+
return
|
|
367
|
+
if _configured_port is None or _configured_token is None:
|
|
368
|
+
return
|
|
369
|
+
|
|
370
|
+
# A new listener session must not inherit a committed intent from an
|
|
371
|
+
# earlier flow run in the same interpreter.
|
|
372
|
+
_clear_intent()
|
|
373
|
+
_negotiation_complete.clear()
|
|
374
|
+
_negotiation_deadline = None
|
|
375
|
+
_receipt_acked.clear()
|
|
376
|
+
_receipt_capable = False
|
|
377
|
+
with _terminal_lock:
|
|
378
|
+
_terminal_claimed = False
|
|
379
|
+
_receipt_in_flight = False
|
|
380
|
+
_outcome_report_started = False
|
|
381
|
+
|
|
382
|
+
try:
|
|
383
|
+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
384
|
+
sock.connect(("127.0.0.1", _configured_port))
|
|
385
|
+
sock.sendall(_configured_token.encode("ascii") + b"\n")
|
|
386
|
+
except OSError:
|
|
387
|
+
try:
|
|
388
|
+
sock.close()
|
|
389
|
+
except (OSError, UnboundLocalError):
|
|
390
|
+
pass
|
|
391
|
+
return
|
|
392
|
+
|
|
393
|
+
thread = threading.Thread(
|
|
394
|
+
target=_reader_loop,
|
|
395
|
+
args=(sock,),
|
|
396
|
+
name="prefect-control-listener",
|
|
397
|
+
daemon=True,
|
|
398
|
+
)
|
|
399
|
+
_socket = sock
|
|
400
|
+
_reader_thread = thread
|
|
401
|
+
_owner_thread_id = threading.get_ident()
|
|
402
|
+
_negotiation_deadline = time.monotonic() + _NEGOTIATION_RESPONSE_TIMEOUT
|
|
403
|
+
_started = True
|
|
404
|
+
thread.start()
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
def stop() -> None:
|
|
408
|
+
"""Close the active control connection, if any."""
|
|
409
|
+
global _configured, _configured_port, _configured_token
|
|
410
|
+
global _started, _owner_thread_id, _socket, _reader_thread, _receipt_capable
|
|
411
|
+
global _terminal_claimed, _receipt_in_flight, _outcome_report_started
|
|
412
|
+
global _negotiation_deadline
|
|
413
|
+
|
|
414
|
+
with _started_lock:
|
|
415
|
+
sock = _socket
|
|
416
|
+
_socket = None
|
|
417
|
+
_reader_thread = None
|
|
418
|
+
_owner_thread_id = None
|
|
419
|
+
_started = False
|
|
420
|
+
_configured = False
|
|
421
|
+
_configured_port = None
|
|
422
|
+
_configured_token = None
|
|
423
|
+
_receipt_capable = False
|
|
424
|
+
_negotiation_complete.clear()
|
|
425
|
+
_negotiation_deadline = None
|
|
426
|
+
_receipt_acked.clear()
|
|
427
|
+
with _terminal_lock:
|
|
428
|
+
_terminal_claimed = False
|
|
429
|
+
_receipt_in_flight = False
|
|
430
|
+
_outcome_report_started = False
|
|
431
|
+
|
|
432
|
+
if sock is not None:
|
|
433
|
+
try:
|
|
434
|
+
sock.shutdown(socket.SHUT_RDWR)
|
|
435
|
+
except OSError:
|
|
436
|
+
pass
|
|
437
|
+
try:
|
|
438
|
+
sock.close()
|
|
439
|
+
except OSError:
|
|
440
|
+
pass
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
def reset_for_testing() -> None:
|
|
444
|
+
"""Reset module state. Tests only."""
|
|
445
|
+
global _intent, _configured, _configured_port, _configured_token
|
|
446
|
+
global _engine_outcome_handled
|
|
447
|
+
|
|
448
|
+
with _intent_lock:
|
|
449
|
+
_intent = None
|
|
450
|
+
|
|
451
|
+
stop()
|
|
452
|
+
|
|
453
|
+
with _started_lock:
|
|
454
|
+
_configured = False
|
|
455
|
+
_configured_port = None
|
|
456
|
+
_configured_token = None
|
|
457
|
+
_engine_outcome_handled = False
|
|
@@ -13,6 +13,7 @@ from prefect._internal.compatibility.migration import getattr_migration
|
|
|
13
13
|
from prefect._internal.control_listener import (
|
|
14
14
|
clear_intent,
|
|
15
15
|
configure_from_env,
|
|
16
|
+
engine_outcome_is_handled,
|
|
16
17
|
get_intent,
|
|
17
18
|
)
|
|
18
19
|
from prefect.exceptions import (
|
|
@@ -102,17 +103,22 @@ def handle_engine_signals(flow_run_id: UUID | None = None):
|
|
|
102
103
|
except TerminationSignal:
|
|
103
104
|
# An intent means the runner or the `prefect flow-run execute` supervisor
|
|
104
105
|
# drove this termination and owns the flow run's next state, so exit cleanly.
|
|
105
|
-
#
|
|
106
|
-
|
|
106
|
+
# An engine outcome means orchestration already handled the termination.
|
|
107
|
+
# A raw external termination with neither form of evidence must propagate.
|
|
108
|
+
intent = get_intent()
|
|
109
|
+
if intent is not None or engine_outcome_is_handled():
|
|
107
110
|
if flow_run_id:
|
|
108
111
|
msg = f"Execution of flow run '{flow_run_id}' was terminated."
|
|
109
112
|
else:
|
|
110
113
|
msg = "Execution was terminated."
|
|
111
114
|
engine_logger.info(msg)
|
|
112
|
-
|
|
115
|
+
if intent is not None:
|
|
116
|
+
clear_intent()
|
|
113
117
|
exit(0)
|
|
114
118
|
raise
|
|
115
119
|
except Exception:
|
|
120
|
+
if engine_outcome_is_handled():
|
|
121
|
+
exit(0)
|
|
116
122
|
if flow_run_id:
|
|
117
123
|
msg = f"Execution of flow run '{flow_run_id}' exited with unexpected exception"
|
|
118
124
|
else:
|
|
@@ -120,6 +126,8 @@ def handle_engine_signals(flow_run_id: UUID | None = None):
|
|
|
120
126
|
engine_logger.error(msg, exc_info=True)
|
|
121
127
|
exit(1)
|
|
122
128
|
except BaseException:
|
|
129
|
+
if engine_outcome_is_handled():
|
|
130
|
+
exit(0)
|
|
123
131
|
if flow_run_id:
|
|
124
132
|
msg = f"Execution of flow run '{flow_run_id}' interrupted by base exception"
|
|
125
133
|
else:
|