projection.py 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. from __future__ import annotations
  2. from dataclasses import dataclass
  3. from typing import Any, Protocol
  4. @dataclass(frozen=True)
  5. class ProjectionJob:
  6. projection_id: str
  7. external_document_id: str
  8. content: str
  9. metadata: dict[str, Any]
  10. track_id: str | None = None
  11. class ProjectionRepository(Protocol):
  12. def mark(
  13. self, projection_id: str, status: str, error: str | None = None
  14. ) -> None: ...
  15. class ProjectionWorker:
  16. def __init__(self, *, client, repository: ProjectionRepository) -> None:
  17. self._client = client
  18. self._repository = repository
  19. def project(self, job: ProjectionJob) -> str:
  20. self._repository.mark(job.projection_id, "processing")
  21. try:
  22. track_id = job.track_id
  23. if track_id is None:
  24. receipt = self._client.insert(
  25. external_document_id=job.external_document_id,
  26. content=job.content,
  27. metadata=job.metadata,
  28. )
  29. track_id = receipt.track_id
  30. if hasattr(self._repository, "set_track"):
  31. self._repository.set_track(job.projection_id, track_id)
  32. status = self._client.track_status(track_id)
  33. if status == "processed":
  34. self._repository.mark(job.projection_id, "ready")
  35. return "ready"
  36. self._repository.mark(job.projection_id, "processing")
  37. return "processing"
  38. except Exception as exc:
  39. self._repository.mark(job.projection_id, "failed", str(exc)[:1000])
  40. return "failed"
  41. def delete(self, job: ProjectionJob) -> str:
  42. self._repository.mark(job.projection_id, "deleting")
  43. try:
  44. receipt = self._client.delete(job.external_document_id)
  45. status = "deleted" if receipt.verified else "unverified"
  46. self._repository.mark(job.projection_id, status)
  47. return status
  48. except Exception as exc:
  49. self._repository.mark(job.projection_id, "failed", str(exc)[:1000])
  50. return "failed"