57 lines
2 KiB
Python
57 lines
2 KiB
Python
from dataclasses import dataclass
|
|
from typing import Protocol
|
|
from uuid import UUID
|
|
|
|
from domain.sandbox import SandboxSession
|
|
from usecase.interface import Logger, Metrics, Tracer
|
|
|
|
|
|
class SandboxSessionStateSource(Protocol):
|
|
def list_active_sessions(self) -> list[SandboxSession]: ...
|
|
|
|
|
|
class SandboxSessionRegistry(Protocol):
|
|
def replace_all(self, sessions: list[SandboxSession]) -> None: ...
|
|
|
|
def count_active(self) -> int: ...
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class SandboxSessionReconciler:
|
|
state_source: SandboxSessionStateSource
|
|
registry: SandboxSessionRegistry
|
|
logger: Logger
|
|
metrics: Metrics
|
|
tracer: Tracer
|
|
|
|
def execute(self) -> list[SandboxSession]:
|
|
with self.tracer.start_span(
|
|
'adapter.sandbox.reconcile_sessions',
|
|
) as span:
|
|
try:
|
|
sessions_by_chat_id: dict[UUID, SandboxSession] = {}
|
|
discovered_sessions = self.state_source.list_active_sessions()
|
|
span.set_attribute('sandbox.discovered_count', len(discovered_sessions))
|
|
for session in sorted(
|
|
discovered_sessions,
|
|
key=lambda item: item.created_at,
|
|
):
|
|
sessions_by_chat_id[session.chat_id] = session
|
|
|
|
sessions = list(sessions_by_chat_id.values())
|
|
self.registry.replace_all(sessions)
|
|
active_count = self.registry.count_active()
|
|
self.metrics.set('sandbox.active.count', active_count)
|
|
span.set_attribute('sandbox.active_count', active_count)
|
|
span.set_attribute('sandbox.result', 'reconciled')
|
|
self.logger.info(
|
|
'sandbox_reconciled',
|
|
attrs={
|
|
'session_count': active_count,
|
|
},
|
|
)
|
|
return sessions
|
|
except Exception as exc:
|
|
span.set_attribute('sandbox.result', 'error')
|
|
span.record_error(exc)
|
|
raise
|