simplify custom poll accounts control (#138)

Этот коммит содержится в:
Vlad Pronsky 2024-04-18 05:12:10 +03:00
родитель 4b70261cfa
Коммит b9e95d4ed0

Просмотреть файл

@ -238,24 +238,16 @@ class AccountsPool:
""" """
await execute(self._db_file, qs, {"username": username}) await execute(self._db_file, qs, {"username": username})
async def get_for_queue(self, queue: str): async def _get_and_lock(self, queue: str, condition: str):
q1 = f""" # if space in condition, it's a subquery, otherwise it's username
SELECT username FROM accounts condition = f"({condition})" if " " in condition else f"'{condition}'"
WHERE active = true AND (
locks IS NULL
OR json_extract(locks, '$.{queue}') IS NULL
OR json_extract(locks, '$.{queue}') < datetime('now')
)
ORDER BY {self._order_by}
LIMIT 1
"""
if int(sqlite3.sqlite_version_info[1]) >= 35: if int(sqlite3.sqlite_version_info[1]) >= 35:
qs = f""" qs = f"""
UPDATE accounts SET UPDATE accounts SET
locks = json_set(locks, '$.{queue}', datetime('now', '+15 minutes')), locks = json_set(locks, '$.{queue}', datetime('now', '+15 minutes')),
last_used = datetime({utc.ts()}, 'unixepoch') last_used = datetime({utc.ts()}, 'unixepoch')
WHERE username = ({q1}) WHERE username = {condition}
RETURNING * RETURNING *
""" """
rs = await fetchone(self._db_file, qs) rs = await fetchone(self._db_file, qs)
@ -266,7 +258,7 @@ class AccountsPool:
locks = json_set(locks, '$.{queue}', datetime('now', '+15 minutes')), locks = json_set(locks, '$.{queue}', datetime('now', '+15 minutes')),
last_used = datetime({utc.ts()}, 'unixepoch'), last_used = datetime({utc.ts()}, 'unixepoch'),
_tx = '{tx}' _tx = '{tx}'
WHERE username = ({q1}) WHERE username = {condition}
""" """
await execute(self._db_file, qs) await execute(self._db_file, qs)
@ -275,6 +267,20 @@ class AccountsPool:
return Account.from_rs(rs) if rs else None return Account.from_rs(rs) if rs else None
async def get_for_queue(self, queue: str):
q = f"""
SELECT username FROM accounts
WHERE active = true AND (
locks IS NULL
OR json_extract(locks, '$.{queue}') IS NULL
OR json_extract(locks, '$.{queue}') < datetime('now')
)
ORDER BY {self._order_by}
LIMIT 1
"""
return await self._get_and_lock(queue, q)
async def get_for_queue_or_wait(self, queue: str) -> Account | None: async def get_for_queue_or_wait(self, queue: str) -> Account | None:
msg_shown = False msg_shown = False
while True: while True: