Poll ETTN statuses in batches and commit per receipt
The cron poll committed only at the end; with ~100 created receipts and a 1s pause between Checkbox requests it hit arq's 300s timeout every run, so all status updates were rolled back and fiscalized receipts stayed "created". Now each run polls at most 30 least-recently-checked receipts and commits after each one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -68,6 +68,11 @@ _CHECKBOX_TO_STATUS = {
|
||||
# или Checkbox был недоступен) и повторить его из cron'а.
|
||||
_PENDING_RETRY_AFTER = timedelta(minutes=1)
|
||||
|
||||
# Сколько `created`-чеков опрашивать за один прогон cron'а (раз в минуту):
|
||||
# при паузе ~1 с между запросами к Checkbox прогон укладывается в минуту и
|
||||
# не наслаивается на следующий.
|
||||
_ETTN_POLL_BATCH = 30
|
||||
|
||||
# Статус заказа в CRM, когда Checkbox принял ЕТТН-чек: заказ можно собирать.
|
||||
CRM_STATUS_AFTER_RECEIPT = "PACKED"
|
||||
# Чеки, при которых заказу нужен этот статус в CRM (Checkbox чек принял).
|
||||
@@ -495,9 +500,20 @@ async def cancel_receipt(
|
||||
|
||||
|
||||
async def sync_ettn_statuses(session: AsyncSession, client: CheckboxClient) -> None:
|
||||
"""Опрашивает Checkbox по чекам, ожидающим оплаты посылки (`created`)."""
|
||||
"""Опрашивает Checkbox по чекам, ожидающим оплаты посылки (`created`).
|
||||
|
||||
За прогон — не больше `_ETTN_POLL_BATCH` давно не проверенных чеков, с
|
||||
коммитом после каждого: запросы к Checkbox идут с паузой, и опрос всех
|
||||
чеков разом не укладывался в таймаут cron-задачи, а откат по таймауту
|
||||
терял весь прогон — статусы не обновлялись вовсе.
|
||||
"""
|
||||
receipts = list(
|
||||
await session.scalars(select(Receipt).where(Receipt.status == ReceiptStatus.CREATED))
|
||||
await session.scalars(
|
||||
select(Receipt)
|
||||
.where(Receipt.status == ReceiptStatus.CREATED)
|
||||
.order_by(Receipt.last_checked_at.asc().nulls_first())
|
||||
.limit(_ETTN_POLL_BATCH)
|
||||
)
|
||||
)
|
||||
registers: dict[uuid.UUID, CheckboxCredentials] = {}
|
||||
for receipt in receipts:
|
||||
@@ -521,8 +537,7 @@ async def sync_ettn_statuses(session: AsyncSession, client: CheckboxClient) -> N
|
||||
_apply_ettn(receipt, ettn)
|
||||
if receipt.status in CLOSED_STATUSES:
|
||||
await _release_order(session, receipt.order_id)
|
||||
|
||||
await session.commit()
|
||||
await session.commit()
|
||||
|
||||
|
||||
async def sync_crm_statuses(session: AsyncSession, crm: CrmClient) -> None:
|
||||
|
||||
Reference in New Issue
Block a user