saq 0.24.6__py3-none-any.whl → 0.24.9__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/postgres.py +59 -39
- {saq-0.24.6.dist-info → saq-0.24.9.dist-info}/METADATA +1 -1
- {saq-0.24.6.dist-info → saq-0.24.9.dist-info}/RECORD +8 -8
- {saq-0.24.6.dist-info → saq-0.24.9.dist-info}/LICENSE +0 -0
- {saq-0.24.6.dist-info → saq-0.24.9.dist-info}/WHEEL +0 -0
- {saq-0.24.6.dist-info → saq-0.24.9.dist-info}/entry_points.txt +0 -0
- {saq-0.24.6.dist-info → saq-0.24.9.dist-info}/top_level.txt +0 -0
saq/__init__.py
CHANGED
saq/queue/postgres.py
CHANGED
@@ -138,7 +138,6 @@ class PostgresQueue(Queue):
|
|
138
138
|
self._waiting = 0 # Internal counter of worker tasks waiting for dequeue
|
139
139
|
self._dequeue_conn: AsyncConnection | None = None
|
140
140
|
self._connection_lock = asyncio.Lock()
|
141
|
-
self._releasing: list[str] = []
|
142
141
|
self._has_sweep_lock = False
|
143
142
|
self._channel = CHANNEL.format(self.name)
|
144
143
|
self._listener = ListenMultiplexer(self.pool, self._channel)
|
@@ -480,30 +479,34 @@ class PostgresQueue(Queue):
|
|
480
479
|
|
481
480
|
job.status = status or job.status
|
482
481
|
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
482
|
+
try:
|
483
|
+
await conn.execute(
|
484
|
+
SQL(
|
485
|
+
dedent(
|
486
|
+
"""
|
487
|
+
UPDATE {jobs_table} SET
|
488
|
+
job = %(job)s
|
489
|
+
,status = %(status)s
|
490
|
+
,scheduled = %(scheduled)s
|
491
|
+
{expire_at}
|
492
|
+
WHERE key = %(key)s
|
493
|
+
"""
|
494
|
+
)
|
495
|
+
).format(
|
496
|
+
jobs_table=self.jobs_table,
|
497
|
+
expire_at=SQL(",expire_at = %(expire_at)s" if expire_at != -1 else ""),
|
498
|
+
),
|
499
|
+
{
|
500
|
+
"job": self.serialize(job),
|
501
|
+
"status": job.status,
|
502
|
+
"key": job.key,
|
503
|
+
"scheduled": job.scheduled,
|
504
|
+
"expire_at": expire_at,
|
505
|
+
},
|
506
|
+
)
|
507
|
+
finally:
|
508
|
+
if job.status != Status.ACTIVE:
|
509
|
+
await self._release_job(job.key)
|
507
510
|
|
508
511
|
async def job(self, job_key: str) -> Job | None:
|
509
512
|
async with self.pool.connection() as conn, conn.cursor() as cursor:
|
@@ -643,7 +646,7 @@ class PostgresQueue(Queue):
|
|
643
646
|
dedent(
|
644
647
|
"""
|
645
648
|
WITH locked_job AS (
|
646
|
-
SELECT key
|
649
|
+
SELECT key
|
647
650
|
FROM {jobs_table}
|
648
651
|
WHERE status = 'queued'
|
649
652
|
AND queue = %(queue)s
|
@@ -663,13 +666,11 @@ class PostgresQueue(Queue):
|
|
663
666
|
UPDATE {jobs_table} SET status = 'active'
|
664
667
|
FROM locked_job
|
665
668
|
WHERE {jobs_table}.key = locked_job.key
|
666
|
-
|
667
|
-
RETURNING job
|
669
|
+
RETURNING job, {jobs_table}.key
|
668
670
|
"""
|
669
671
|
)
|
670
672
|
).format(
|
671
673
|
jobs_table=self.jobs_table,
|
672
|
-
job_lock_keyspace=self.job_lock_keyspace,
|
673
674
|
),
|
674
675
|
{
|
675
676
|
"queue": self.name,
|
@@ -681,8 +682,31 @@ class PostgresQueue(Queue):
|
|
681
682
|
)
|
682
683
|
results = await cursor.fetchall()
|
683
684
|
|
684
|
-
|
685
|
-
|
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 results]},
|
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
|
+
)
|
707
|
+
|
708
|
+
for job, _ in results:
|
709
|
+
self._job_queue.put_nowait(self.deserialize(job))
|
686
710
|
|
687
711
|
if results:
|
688
712
|
await self._notify(DEQUEUE)
|
@@ -839,7 +863,7 @@ class PostgresQueue(Queue):
|
|
839
863
|
).format(jobs_table=self.jobs_table),
|
840
864
|
{"key": key},
|
841
865
|
)
|
842
|
-
|
866
|
+
await self._release_job(key)
|
843
867
|
|
844
868
|
async def _notify(self, key: str, connection: AsyncConnection | None = None) -> None:
|
845
869
|
async with self.nullcontext(connection) if connection else self.pool.connection() as conn:
|
@@ -871,26 +895,22 @@ class PostgresQueue(Queue):
|
|
871
895
|
yield enter_result
|
872
896
|
|
873
897
|
async def _release_job(self, key: str) -> None:
|
874
|
-
self.
|
875
|
-
if self._connection_lock.locked():
|
876
|
-
return
|
877
|
-
async with self._get_dequeue_conn() as conn:
|
898
|
+
async with self._get_dequeue_conn() as conn, conn:
|
878
899
|
await conn.execute(
|
879
900
|
SQL(
|
880
901
|
dedent(
|
881
902
|
"""
|
882
903
|
SELECT pg_advisory_unlock({job_lock_keyspace}, lock_key)
|
883
904
|
FROM {jobs_table}
|
884
|
-
WHERE key =
|
905
|
+
WHERE key = %(key)s
|
885
906
|
"""
|
886
907
|
)
|
887
908
|
).format(
|
888
909
|
jobs_table=self.jobs_table,
|
889
910
|
job_lock_keyspace=self.job_lock_keyspace,
|
890
911
|
),
|
891
|
-
{"
|
912
|
+
{"key": key},
|
892
913
|
)
|
893
|
-
self._releasing.clear()
|
894
914
|
|
895
915
|
@cached_property
|
896
916
|
def _job_queue(self) -> asyncio.Queue:
|
@@ -1,4 +1,4 @@
|
|
1
|
-
saq/__init__.py,sha256=
|
1
|
+
saq/__init__.py,sha256=G_2GAPgXY3_BEk5HNQpH8pQf3RqSY6Mjx8ZIOSSTRtc,218
|
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
|
@@ -10,7 +10,7 @@ saq/worker.py,sha256=W9rqK_u0bbvUbdb879pvf1f-suNnesKk1TjYqHQREc8,16817
|
|
10
10
|
saq/queue/__init__.py,sha256=5LgBHGylCVvrLDcjMCcI2dRRgh0BPdz2TKOdc8NMs2E,87
|
11
11
|
saq/queue/base.py,sha256=vRSr4ExGETlkjc9bLrtqfi_A7Zsr_IQzCMyN_b70-UM,15572
|
12
12
|
saq/queue/http.py,sha256=V9S26gJbUt5AUIR2ETasSQy4Q_K30eGtguBYHpfcLGU,7739
|
13
|
-
saq/queue/postgres.py,sha256=
|
13
|
+
saq/queue/postgres.py,sha256=R3nQBNWk4rZyAm52lUQyqxl0g37OnGUlL_Ixo9UgV9o,35580
|
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.9.dist-info/LICENSE,sha256=p208OXrLf_dMcvuRHpcinfsJdihCqKWbqtFXpw4kyW0,1065
|
24
|
+
saq-0.24.9.dist-info/METADATA,sha256=zPpbi2NsgYJVaZJk2TIJm9TVB9M3IZJoinrnV-uekOQ,7781
|
25
|
+
saq-0.24.9.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
26
|
+
saq-0.24.9.dist-info/entry_points.txt,sha256=HkKOud1K15_DV7AEltn8G5Ua10VqIgHaZ4BQit4fdOk,42
|
27
|
+
saq-0.24.9.dist-info/top_level.txt,sha256=FMrrc5EiGr4sQkEDtUMHIpomnWHL9i6xT7B6lvEh8xM,4
|
28
|
+
saq-0.24.9.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|