Merge pull request 'fix(provision): publish default stall in background to avoid blocking signup (#7)' (#8) from fix-7-publish-stall-async into main
Some checks failed
ci.yml / Merge pull request 'fix(provision): publish default stall in background to avoid blocking signup (#7)' (#8) from fix-7-publish-stall-async into main (push) Failing after 0s
Some checks failed
ci.yml / Merge pull request 'fix(provision): publish default stall in background to avoid blocking signup (#7)' (#8) from fix-7-publish-stall-async into main (push) Failing after 0s
Reviewed-on: #8
This commit is contained in:
commit
adda751eb0
1 changed files with 44 additions and 5 deletions
49
services.py
49
services.py
|
|
@ -288,18 +288,57 @@ async def provision_merchant(
|
|||
# Publish the kind 30017 stall event so customers' clients can resolve
|
||||
# the stall name when they fetch products. Non-fatal on failure: a
|
||||
# later product publish (or webapp self-heal) will retry.
|
||||
#
|
||||
# Fire-and-forget: `nostr_client.publish_nostr_event` has no per-relay
|
||||
# deadline and will block indefinitely if every configured relay is
|
||||
# unreachable (cf. aiolabs/nostrmarket#7). When `provision_merchant`
|
||||
# is called from the eager signup hook (lnbits/core/services/users.py
|
||||
# ::_create_default_merchant, aiolabs/lnbits#46), inline-awaiting that
|
||||
# publish hangs the uvicorn worker on `POST /auth/register` forever.
|
||||
# The DB rows we just wrote are sufficient to serve the wallet UI;
|
||||
# the stall event_id gets backfilled when the publish completes (or
|
||||
# stays NULL until a later resubscribe-driven republish lands it).
|
||||
asyncio.create_task(
|
||||
_publish_default_stall_background(merchant.id, merchant, default_stall)
|
||||
)
|
||||
|
||||
return merchant
|
||||
|
||||
|
||||
# Generous bound: signing through the bunker can take 1–2 s on a cold
|
||||
# session, plus the relay publish itself. 30 s is well over both, and
|
||||
# the cap matters only when the relay set is unreachable.
|
||||
STALL_PUBLISH_TIMEOUT_S = 30.0
|
||||
|
||||
|
||||
async def _publish_default_stall_background(
|
||||
merchant_id: str, merchant: Merchant, default_stall: Stall
|
||||
) -> None:
|
||||
"""Background helper for `provision_merchant`'s default-stall publish.
|
||||
|
||||
Bounded by `STALL_PUBLISH_TIMEOUT_S` so even a permanently-unreachable
|
||||
relay set doesn't pin an asyncio task forever. Errors and timeouts are
|
||||
logged at warning — never raised, since the caller scheduled-and-forgot.
|
||||
"""
|
||||
try:
|
||||
stall_event = await sign_and_send_to_nostr(merchant, default_stall)
|
||||
stall_event = await asyncio.wait_for(
|
||||
sign_and_send_to_nostr(merchant, default_stall),
|
||||
timeout=STALL_PUBLISH_TIMEOUT_S,
|
||||
)
|
||||
default_stall.event_id = stall_event.id
|
||||
await update_stall(merchant.id, default_stall)
|
||||
await update_stall(merchant_id, default_stall)
|
||||
except asyncio.TimeoutError:
|
||||
logger.warning(
|
||||
f"[NOSTRMARKET] Default stall publish for merchant "
|
||||
f"{merchant_id} timed out after {STALL_PUBLISH_TIMEOUT_S}s; "
|
||||
f"event_id stays NULL until a later republish lands it"
|
||||
)
|
||||
except Exception as ex:
|
||||
logger.warning(
|
||||
f"[NOSTRMARKET] Failed to publish default stall for "
|
||||
f"merchant {merchant.id}: {ex}"
|
||||
f"merchant {merchant_id}: {ex}"
|
||||
)
|
||||
|
||||
return merchant
|
||||
|
||||
|
||||
async def handle_order_paid(order_id: str, merchant_pubkey: str):
|
||||
try:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue