"""Lifecycle dispatcher for drivers and registry hooks."""
import inspect
from collections.abc import Callable, Iterable
from typing import Any, Literal
from sqlspec.utils.logging import get_logger
__all__ = ("LifecycleContext", "LifecycleDispatcher", "LifecycleHook")
logger = get_logger("sqlspec.observability.lifecycle")
LifecycleContext = dict[str, Any]
LifecycleHook = Callable[[LifecycleContext], Any]
LifecycleEvent = Literal[
"on_pool_create",
"on_pool_destroying",
"on_pool_destroy",
"on_connection_create",
"on_connection_destroy",
"on_session_start",
"on_session_end",
"on_query_start",
"on_query_complete",
"on_error",
]
EVENT_ATTRS: tuple[LifecycleEvent, ...] = (
"on_pool_create",
"on_pool_destroying",
"on_pool_destroy",
"on_connection_create",
"on_connection_destroy",
"on_session_start",
"on_session_end",
"on_query_start",
"on_query_complete",
"on_error",
)
class LifecycleDispatcher:
"""Dispatches lifecycle hooks with guard flags and diagnostics counters."""
__slots__ = (
"_counters",
"_hooks",
"_is_enabled",
"has_connection_create",
"has_connection_destroy",
"has_error",
"has_pool_create",
"has_pool_destroy",
"has_pool_destroying",
"has_query_complete",
"has_query_start",
"has_session_end",
"has_session_start",
)
def __init__(self, hooks: "dict[str, Iterable[LifecycleHook]] | None" = None) -> None:
self.has_pool_create = False
self.has_pool_destroying = False
self.has_pool_destroy = False
self.has_connection_create = False
self.has_connection_destroy = False
self.has_session_start = False
self.has_session_end = False
self.has_query_start = False
self.has_query_complete = False
self.has_error = False
normalized: dict[LifecycleEvent, list[LifecycleHook]] = {}
for event_name in EVENT_ATTRS:
callables = hooks.get(event_name) if hooks else None
normalized[event_name] = list(callables) if callables else []
if normalized[event_name]:
self._enable_event_guard(event_name)
self._hooks: dict[LifecycleEvent, list[LifecycleHook]] = normalized
self._counters: dict[LifecycleEvent, int] = dict.fromkeys(EVENT_ATTRS, 0)
self._is_enabled = any(self._hooks.values())