labtasker-server 2.0.0__py3-none-any.whl

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.
@@ -0,0 +1,66 @@
1
+ from __future__ import annotations
2
+
3
+ from sqlalchemy import func, select
4
+
5
+ from labtasker_server.database import Database
6
+ from labtasker_server.errors import conflict, not_found
7
+ from labtasker_server.models import QueueRow, TaskRow
8
+ from labtasker_server.schemas import Queue
9
+ from labtasker_server.validation import validate_identifier
10
+
11
+
12
+ class QueueService:
13
+ def __init__(self, database: Database) -> None:
14
+ self.database = database
15
+
16
+ def create(self, name: str) -> tuple[Queue, bool]:
17
+ name = validate_identifier(name, kind="Queue")
18
+ with self.database.write_session() as session:
19
+ existing = session.get(QueueRow, name)
20
+ if existing is not None:
21
+ return Queue(name=existing.name), False
22
+ row = QueueRow(name=name)
23
+ session.add(row)
24
+ session.flush()
25
+ return Queue(name=row.name), True
26
+
27
+ def list(self) -> list[Queue]:
28
+ with self.database.read_session() as session:
29
+ names = session.scalars(select(QueueRow.name).order_by(QueueRow.name)).all()
30
+ return [Queue(name=name) for name in names]
31
+
32
+ def require_exists(self, name: str) -> None:
33
+ name = validate_identifier(name, kind="Queue")
34
+ with self.database.read_session() as session:
35
+ if session.get(QueueRow, name) is None:
36
+ raise not_found("queue_not_found", "Queue does not exist.", queue=name)
37
+
38
+ def delete(self, name: str, *, cascade: bool) -> None:
39
+ name = validate_identifier(name, kind="Queue")
40
+ with self.database.write_session() as session:
41
+ row = session.get(QueueRow, name)
42
+ if row is None:
43
+ raise not_found("queue_not_found", "Queue does not exist.", queue=name)
44
+ running = session.scalar(
45
+ select(func.count())
46
+ .select_from(TaskRow)
47
+ .where(TaskRow.queue_name == name, TaskRow.status == "running")
48
+ )
49
+ if running:
50
+ raise conflict(
51
+ "queue_has_running_tasks",
52
+ "Queue contains running Tasks; cancel them before deletion.",
53
+ queue=name,
54
+ running=running,
55
+ )
56
+ task_count = session.scalar(
57
+ select(func.count()).select_from(TaskRow).where(TaskRow.queue_name == name)
58
+ )
59
+ if task_count and not cascade:
60
+ raise conflict(
61
+ "queue_not_empty",
62
+ "Queue is not empty; use cascade to delete its Tasks.",
63
+ queue=name,
64
+ tasks=task_count,
65
+ )
66
+ session.delete(row)