saq 0.24.8__py3-none-any.whl → 0.24.10__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.
- saq/__init__.py +1 -1
- saq/queue/base.py +6 -1
- saq/queue/postgres.py +47 -26
- {saq-0.24.8.dist-info → saq-0.24.10.dist-info}/METADATA +1 -1
- {saq-0.24.8.dist-info → saq-0.24.10.dist-info}/RECORD +9 -9
- {saq-0.24.8.dist-info → saq-0.24.10.dist-info}/LICENSE +0 -0
- {saq-0.24.8.dist-info → saq-0.24.10.dist-info}/WHEEL +0 -0
- {saq-0.24.8.dist-info → saq-0.24.10.dist-info}/entry_points.txt +0 -0
- {saq-0.24.8.dist-info → saq-0.24.10.dist-info}/top_level.txt +0 -0
saq/__init__.py
CHANGED
saq/queue/base.py
CHANGED
@@ -219,13 +219,18 @@ class Queue(ABC):
|
|
219
219
|
def serialize(self, job: Job) -> bytes | str:
|
220
220
|
return self._dump(job.to_dict())
|
221
221
|
|
222
|
-
def deserialize(
|
222
|
+
def deserialize(
|
223
|
+
self, payload: dict | str | bytes | None, status: Status | str | None = None
|
224
|
+
) -> Job | None:
|
223
225
|
if not payload:
|
224
226
|
return None
|
225
227
|
|
226
228
|
job_dict = payload if isinstance(payload, dict) else self._load(payload)
|
227
229
|
if job_dict.pop("queue") != self.name:
|
228
230
|
raise ValueError(f"Job {job_dict} fetched by wrong queue: {self.name}")
|
231
|
+
|
232
|
+
if status:
|
233
|
+
job_dict["status"] = status
|
229
234
|
return Job(**job_dict, queue=self)
|
230
235
|
|
231
236
|
async def worker_info(
|
saq/queue/postgres.py
CHANGED
@@ -260,14 +260,14 @@ class PostgresQueue(Queue):
|
|
260
260
|
).format(stats_table=self.stats_table),
|
261
261
|
{"queue": self.name},
|
262
262
|
)
|
263
|
-
|
263
|
+
rows = await cursor.fetchall()
|
264
264
|
workers: dict[str, WorkerInfo] = {
|
265
265
|
worker_id: {
|
266
266
|
"stats": stats,
|
267
267
|
"metadata": metadata,
|
268
268
|
"queue_key": queue_key,
|
269
269
|
}
|
270
|
-
for worker_id, stats, queue_key, metadata in
|
270
|
+
for worker_id, stats, queue_key, metadata in rows
|
271
271
|
}
|
272
272
|
|
273
273
|
queued = await self.count("queued")
|
@@ -280,7 +280,7 @@ class PostgresQueue(Queue):
|
|
280
280
|
SQL(
|
281
281
|
dedent(
|
282
282
|
"""
|
283
|
-
SELECT job FROM {jobs_table}
|
283
|
+
SELECT job, status FROM {jobs_table}
|
284
284
|
WHERE status IN ('new', 'deferred', 'queued', 'active')
|
285
285
|
AND queue = %(queue)s
|
286
286
|
"""
|
@@ -288,8 +288,8 @@ class PostgresQueue(Queue):
|
|
288
288
|
).format(jobs_table=self.jobs_table),
|
289
289
|
{"queue": self.name},
|
290
290
|
)
|
291
|
-
|
292
|
-
deserialized_jobs = (self.deserialize(
|
291
|
+
rows = await cursor.fetchall()
|
292
|
+
deserialized_jobs = (self.deserialize(*row) for row in rows)
|
293
293
|
jobs_info = [job.to_dict() for job in deserialized_jobs if job]
|
294
294
|
else:
|
295
295
|
jobs_info = []
|
@@ -441,10 +441,10 @@ class PostgresQueue(Queue):
|
|
441
441
|
"job_lock_keyspace": self.job_lock_keyspace,
|
442
442
|
},
|
443
443
|
)
|
444
|
-
|
444
|
+
rows = await cursor.fetchall()
|
445
445
|
|
446
|
-
for key, job_bytes, objid, status in
|
447
|
-
job = self.deserialize(job_bytes)
|
446
|
+
for key, job_bytes, objid, status in rows:
|
447
|
+
job = self.deserialize(job_bytes, status)
|
448
448
|
assert job
|
449
449
|
if (objid or not self.job_lock_sweep) and not job.stuck:
|
450
450
|
continue
|
@@ -514,7 +514,7 @@ class PostgresQueue(Queue):
|
|
514
514
|
SQL(
|
515
515
|
dedent(
|
516
516
|
"""
|
517
|
-
SELECT job
|
517
|
+
SELECT job, status
|
518
518
|
FROM {jobs_table}
|
519
519
|
WHERE key = %(key)s AND queue = %(queue)s
|
520
520
|
"""
|
@@ -522,9 +522,9 @@ class PostgresQueue(Queue):
|
|
522
522
|
).format(jobs_table=self.jobs_table),
|
523
523
|
{"key": job_key, "queue": self.name},
|
524
524
|
)
|
525
|
-
|
526
|
-
if
|
527
|
-
return self.deserialize(
|
525
|
+
row = await cursor.fetchone()
|
526
|
+
if row:
|
527
|
+
return self.deserialize(*row)
|
528
528
|
return None
|
529
529
|
|
530
530
|
async def jobs(self, job_keys: Iterable[str]) -> t.List[Job | None]:
|
@@ -535,7 +535,7 @@ class PostgresQueue(Queue):
|
|
535
535
|
SQL(
|
536
536
|
dedent(
|
537
537
|
"""
|
538
|
-
SELECT key, job
|
538
|
+
SELECT key, job, status
|
539
539
|
FROM {jobs_table}
|
540
540
|
WHERE key = ANY(%(keys)s)
|
541
541
|
"""
|
@@ -543,8 +543,8 @@ class PostgresQueue(Queue):
|
|
543
543
|
).format(jobs_table=self.jobs_table),
|
544
544
|
{"keys": keys},
|
545
545
|
)
|
546
|
-
results:
|
547
|
-
return [self.deserialize(results.get(key)) for key in keys]
|
546
|
+
results = {r[0]: r[1:] for r in await cursor.fetchall()}
|
547
|
+
return [self.deserialize(*(results.get(key) or [None])) for key in keys]
|
548
548
|
|
549
549
|
async def iter_jobs(
|
550
550
|
self,
|
@@ -559,7 +559,7 @@ class PostgresQueue(Queue):
|
|
559
559
|
SQL(
|
560
560
|
dedent(
|
561
561
|
"""
|
562
|
-
SELECT key, job
|
562
|
+
SELECT key, job, status
|
563
563
|
FROM {jobs_table}
|
564
564
|
WHERE
|
565
565
|
status = ANY(%(statuses)s)
|
@@ -581,9 +581,9 @@ class PostgresQueue(Queue):
|
|
581
581
|
rows = await cursor.fetchall()
|
582
582
|
|
583
583
|
if rows:
|
584
|
-
for key, job_bytes in rows:
|
584
|
+
for key, job_bytes, status in rows:
|
585
585
|
last_key = key
|
586
|
-
job = self.deserialize(job_bytes)
|
586
|
+
job = self.deserialize(job_bytes, status)
|
587
587
|
if job:
|
588
588
|
yield job
|
589
589
|
else:
|
@@ -638,7 +638,7 @@ class PostgresQueue(Queue):
|
|
638
638
|
return
|
639
639
|
|
640
640
|
async with self._dequeue_lock:
|
641
|
-
async with self._get_dequeue_conn() as conn, conn.cursor() as cursor:
|
641
|
+
async with self._get_dequeue_conn() as conn, conn.transaction(), conn.cursor() as cursor:
|
642
642
|
if not self._waiting:
|
643
643
|
return
|
644
644
|
await cursor.execute(
|
@@ -659,7 +659,6 @@ class PostgresQueue(Queue):
|
|
659
659
|
AND queue = %(queue)s
|
660
660
|
AND group_key IS NOT NULL
|
661
661
|
)
|
662
|
-
AND pg_try_advisory_lock({job_lock_keyspace}, lock_key)
|
663
662
|
ORDER BY priority, scheduled
|
664
663
|
LIMIT %(limit)s
|
665
664
|
FOR UPDATE SKIP LOCKED
|
@@ -667,12 +666,11 @@ class PostgresQueue(Queue):
|
|
667
666
|
UPDATE {jobs_table} SET status = 'active'
|
668
667
|
FROM locked_job
|
669
668
|
WHERE {jobs_table}.key = locked_job.key
|
670
|
-
RETURNING job
|
669
|
+
RETURNING job, {jobs_table}.key, status
|
671
670
|
"""
|
672
671
|
)
|
673
672
|
).format(
|
674
673
|
jobs_table=self.jobs_table,
|
675
|
-
job_lock_keyspace=self.job_lock_keyspace,
|
676
674
|
),
|
677
675
|
{
|
678
676
|
"queue": self.name,
|
@@ -682,12 +680,35 @@ class PostgresQueue(Queue):
|
|
682
680
|
"phigh": self._priorities[1],
|
683
681
|
},
|
684
682
|
)
|
685
|
-
|
683
|
+
rows = await cursor.fetchall()
|
684
|
+
|
685
|
+
await conn.execute(
|
686
|
+
SQL(
|
687
|
+
dedent(
|
688
|
+
"""
|
689
|
+
SELECT key, pg_try_advisory_lock({job_lock_keyspace}, lock_key)
|
690
|
+
FROM {jobs_table}
|
691
|
+
WHERE key = ANY(%(keys)s)
|
692
|
+
"""
|
693
|
+
)
|
694
|
+
).format(
|
695
|
+
jobs_table=self.jobs_table,
|
696
|
+
job_lock_keyspace=self.job_lock_keyspace,
|
697
|
+
),
|
698
|
+
{"keys": [key for _, key, _ in rows]},
|
699
|
+
)
|
700
|
+
lock_acquisition_results = await cursor.fetchall()
|
701
|
+
for key, lock_acquired in lock_acquisition_results:
|
702
|
+
if not lock_acquired:
|
703
|
+
logger.error(
|
704
|
+
"Could not acquire lock for job %s. This may result in unexpected behavior",
|
705
|
+
key,
|
706
|
+
)
|
686
707
|
|
687
|
-
for
|
688
|
-
self._job_queue.put_nowait(self.deserialize(
|
708
|
+
for job, _, status in rows:
|
709
|
+
self._job_queue.put_nowait(self.deserialize(job, status))
|
689
710
|
|
690
|
-
if
|
711
|
+
if rows:
|
691
712
|
await self._notify(DEQUEUE)
|
692
713
|
|
693
714
|
async def _enqueue(self, job: Job) -> Job | None:
|
@@ -1,4 +1,4 @@
|
|
1
|
-
saq/__init__.py,sha256=
|
1
|
+
saq/__init__.py,sha256=vYIFEVix-39RzyynnCqMQVZMrhIr4ns1aeJOmEXWCt0,219
|
2
2
|
saq/__main__.py,sha256=N4RNqnCcj7eZbM3OyYaC03_6Cot-y-SxW5Hwx6fuzKU,2440
|
3
3
|
saq/errors.py,sha256=XPJw6J3caSAho4ZybuodIbeuGjboVabLuf3NFOEE-4Q,112
|
4
4
|
saq/job.py,sha256=X49OuSqZeN-RVmh4AonZRrwk2wU8MeukLSxrvjGLm7E,11552
|
@@ -8,9 +8,9 @@ saq/types.py,sha256=GhIq2BIE_Z9hA-qS-NQXh_iPICNI0NZxOzjW0vcMgFU,3196
|
|
8
8
|
saq/utils.py,sha256=NdOycT-03zxjhKM8A1i0vzKnkv1UQxvy_Zt4GnO0Zd8,1721
|
9
9
|
saq/worker.py,sha256=W9rqK_u0bbvUbdb879pvf1f-suNnesKk1TjYqHQREc8,16817
|
10
10
|
saq/queue/__init__.py,sha256=5LgBHGylCVvrLDcjMCcI2dRRgh0BPdz2TKOdc8NMs2E,87
|
11
|
-
saq/queue/base.py,sha256=
|
11
|
+
saq/queue/base.py,sha256=wej8WBWK-S9GXYEHXTfl7Wwwm-DB3o1RB-bHMvNLfdI,15682
|
12
12
|
saq/queue/http.py,sha256=V9S26gJbUt5AUIR2ETasSQy4Q_K30eGtguBYHpfcLGU,7739
|
13
|
-
saq/queue/postgres.py,sha256=
|
13
|
+
saq/queue/postgres.py,sha256=7FSljVrqISV8w82cv0yWvyejMpucbucsjpu8Ntoqee4,35648
|
14
14
|
saq/queue/postgres_migrations.py,sha256=gI6j-0TzlFFSWxji3Dy9aJ-llboJBm92J4tB_YZ7qI8,2080
|
15
15
|
saq/queue/redis.py,sha256=sa_wzUUlfPw-RZ-v_cnDEJWEFyUi3sy_3YTqG4UklOA,17754
|
16
16
|
saq/web/__init__.py,sha256=NG9LfjgJQxNft0_iZuZ3LnX1I58SfxRwKpycjazBoGE,23
|
@@ -20,9 +20,9 @@ saq/web/starlette.py,sha256=i38xuNcnQvWBY3jyHHu9Uo9ILSBzOwmk5Bq06c3CQzM,4432
|
|
20
20
|
saq/web/static/app.js,sha256=i6PaRvBvt96LOINBdEuKkDvVeM-GA8lJiFg4jtQ3viY,7094
|
21
21
|
saq/web/static/pico.min.css.gz,sha256=qCxIv3wWFMQ7MkvGSHQLwxio3121VvvieOkSjw6fv6o,9263
|
22
22
|
saq/web/static/snabbdom.js.gz,sha256=zSO3Z761TB7bYNQFFEtypD0vCuqWesqPJeE5CuV4xRg,7603
|
23
|
-
saq-0.24.
|
24
|
-
saq-0.24.
|
25
|
-
saq-0.24.
|
26
|
-
saq-0.24.
|
27
|
-
saq-0.24.
|
28
|
-
saq-0.24.
|
23
|
+
saq-0.24.10.dist-info/LICENSE,sha256=p208OXrLf_dMcvuRHpcinfsJdihCqKWbqtFXpw4kyW0,1065
|
24
|
+
saq-0.24.10.dist-info/METADATA,sha256=iPnYOcZctuzl-5KOEWq7UoOBSexbYKFTtBvEM_KUr40,7782
|
25
|
+
saq-0.24.10.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
26
|
+
saq-0.24.10.dist-info/entry_points.txt,sha256=HkKOud1K15_DV7AEltn8G5Ua10VqIgHaZ4BQit4fdOk,42
|
27
|
+
saq-0.24.10.dist-info/top_level.txt,sha256=FMrrc5EiGr4sQkEDtUMHIpomnWHL9i6xT7B6lvEh8xM,4
|
28
|
+
saq-0.24.10.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|