feat: back off pending payment polling
This commit is contained in:
parent
f4b96107fa
commit
e9d3c48aec
2 changed files with 16 additions and 8 deletions
11
tasks.py
11
tasks.py
|
|
@ -34,7 +34,9 @@ from .paranoia import (
|
|||
)
|
||||
from .permission import nwc_permissions
|
||||
|
||||
PAYMENT_STATUS_POLL_INTERVAL_SECONDS = 1.0
|
||||
PAYMENT_STATUS_POLL_INITIAL_INTERVAL_SECONDS = 1.0
|
||||
PAYMENT_STATUS_POLL_MAX_INTERVAL_SECONDS = 60.0
|
||||
PAYMENT_STATUS_POLL_BACKOFF_MULTIPLIER = 2.0
|
||||
|
||||
|
||||
async def _check(nwc: NWCKey | None, method: str) -> dict | None:
|
||||
|
|
@ -112,6 +114,7 @@ async def _process_invoice(
|
|||
True # currently required by nip 47 specs, might change in future
|
||||
)
|
||||
payment_status: PaymentStatus | None = None
|
||||
poll_interval = PAYMENT_STATUS_POLL_INITIAL_INTERVAL_SECONDS
|
||||
while wait_for_preimage:
|
||||
payment_status = await check_transaction_status(wallet_id, payment_hash)
|
||||
if payment_status.success:
|
||||
|
|
@ -124,7 +127,11 @@ async def _process_invoice(
|
|||
},
|
||||
"in_budget": in_budget,
|
||||
}
|
||||
await asyncio.sleep(PAYMENT_STATUS_POLL_INTERVAL_SECONDS)
|
||||
await asyncio.sleep(poll_interval)
|
||||
poll_interval = min(
|
||||
poll_interval * PAYMENT_STATUS_POLL_BACKOFF_MULTIPLIER,
|
||||
PAYMENT_STATUS_POLL_MAX_INTERVAL_SECONDS,
|
||||
)
|
||||
if not payment_status:
|
||||
raise Exception("Payment status not found")
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -32,29 +32,30 @@ async def test_process_invoice_returns_payment_failed_on_failed_status(monkeypat
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_process_invoice_polls_pending_payment_at_sustainable_interval(
|
||||
async def test_process_invoice_backs_off_pending_payment_polling_to_configured_max(
|
||||
monkeypatch,
|
||||
):
|
||||
async def fake_tracked_spend_nwc(*args, **kwargs):
|
||||
return True, "a" * 64
|
||||
|
||||
pending = SimpleNamespace(success=False, failed=False)
|
||||
statuses = iter(
|
||||
[
|
||||
SimpleNamespace(success=False, failed=False),
|
||||
[pending] * 8
|
||||
+ [
|
||||
SimpleNamespace(
|
||||
success=True,
|
||||
failed=False,
|
||||
preimage="b" * 64,
|
||||
fee_msat=10,
|
||||
paid=True,
|
||||
),
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
async def fake_check_transaction_status(wallet_id: str, payment_hash: str):
|
||||
return next(statuses)
|
||||
|
||||
sleep_calls = []
|
||||
sleep_calls: list[float] = []
|
||||
|
||||
async def fake_sleep(delay: float):
|
||||
sleep_calls.append(delay)
|
||||
|
|
@ -73,7 +74,7 @@ async def test_process_invoice_polls_pending_payment_at_sustainable_interval(
|
|||
description="test",
|
||||
)
|
||||
|
||||
assert sleep_calls == [tasks.PAYMENT_STATUS_POLL_INTERVAL_SECONDS]
|
||||
assert sleep_calls == [1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 60.0, 60.0]
|
||||
assert result["preimage"] == "b" * 64
|
||||
assert result["fee_msats"] == 10
|
||||
assert result["paid"] is True
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue