[perf] send payment notifications in background (#3588)

This commit is contained in:
Vlad Stan 2025-11-26 19:53:10 +02:00 committed by GitHub
parent 730ab59578
commit 5f1cfc0e37
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 16 additions and 8 deletions

View file

@ -1,6 +1,7 @@
import asyncio import asyncio
import json import json
import smtplib import smtplib
from asyncio.tasks import create_task
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText from email.mime.text import MIMEText
from http import HTTPStatus from http import HTTPStatus
@ -286,6 +287,13 @@ async def send_payment_notification(wallet: Wallet, payment: Payment):
logger.error(f"Error dispatching webhook: {e!s}") logger.error(f"Error dispatching webhook: {e!s}")
def send_payment_notification_in_background(wallet: Wallet, payment: Payment):
try:
create_task(send_payment_notification(wallet, payment))
except Exception as e:
logger.warning(f"Error sending payment notification: {e}")
async def send_ws_payment_notification(wallet: Wallet, payment: Payment): async def send_ws_payment_notification(wallet: Wallet, payment: Payment):
# TODO: websocket message should be a clean payment model # TODO: websocket message should be a clean payment model
# await websocket_manager.send(wallet.inkey, payment.json()) # await websocket_manager.send(wallet.inkey, payment.json())

View file

@ -47,7 +47,7 @@ from ..models import (
PaymentState, PaymentState,
Wallet, Wallet,
) )
from .notifications import send_payment_notification from .notifications import send_payment_notification_in_background
payment_lock = asyncio.Lock() payment_lock = asyncio.Lock()
wallets_payments_lock: dict[str, asyncio.Lock] = {} wallets_payments_lock: dict[str, asyncio.Lock] = {}
@ -741,7 +741,7 @@ async def _pay_internal_invoice(
await update_payment(internal_payment, conn=conn) await update_payment(internal_payment, conn=conn)
logger.success(f"internal payment successful {internal_payment.checking_id}") logger.success(f"internal payment successful {internal_payment.checking_id}")
await send_payment_notification(wallet, payment) send_payment_notification_in_background(wallet, payment)
# notify receiver asynchronously # notify receiver asynchronously
from lnbits.tasks import internal_invoice_queue from lnbits.tasks import internal_invoice_queue
@ -814,7 +814,7 @@ async def _pay_external_invoice(
payment = await update_payment_success_status( payment = await update_payment_success_status(
payment, payment_response, conn=conn payment, payment_response, conn=conn
) )
await send_payment_notification(wallet, payment) send_payment_notification_in_background(wallet, payment)
logger.success(f"payment successful {payment_response.checking_id}") logger.success(f"payment successful {payment_response.checking_id}")
payment.checking_id = payment_response.checking_id payment.checking_id = payment_response.checking_id

View file

@ -298,7 +298,7 @@ async def test_retry_failed_invoice(
assert external_invoice.payment_request assert external_invoice.payment_request
ws_notification = mocker.patch( ws_notification = mocker.patch(
"lnbits.core.services.payments.send_payment_notification", "lnbits.core.services.payments.send_payment_notification_in_background",
AsyncMock(return_value=None), AsyncMock(return_value=None),
) )
@ -378,7 +378,7 @@ async def test_pay_external_invoice_pending(
AsyncMock(return_value=payment_reponse_pending), AsyncMock(return_value=payment_reponse_pending),
) )
ws_notification = mocker.patch( ws_notification = mocker.patch(
"lnbits.core.services.payments.send_payment_notification", "lnbits.core.services.payments.send_payment_notification_in_background",
AsyncMock(return_value=None), AsyncMock(return_value=None),
) )
wallet = await get_wallet(from_wallet.id) wallet = await get_wallet(from_wallet.id)
@ -428,7 +428,7 @@ async def test_retry_pay_external_invoice_pending(
AsyncMock(return_value=payment_reponse_pending), AsyncMock(return_value=payment_reponse_pending),
) )
ws_notification = mocker.patch( ws_notification = mocker.patch(
"lnbits.core.services.payments.send_payment_notification", "lnbits.core.services.payments.send_payment_notification_in_background",
AsyncMock(return_value=None), AsyncMock(return_value=None),
) )
wallet = await get_wallet(from_wallet.id) wallet = await get_wallet(from_wallet.id)
@ -474,7 +474,7 @@ async def test_pay_external_invoice_success(
AsyncMock(return_value=payment_reponse_pending), AsyncMock(return_value=payment_reponse_pending),
) )
ws_notification = mocker.patch( ws_notification = mocker.patch(
"lnbits.core.services.payments.send_payment_notification", "lnbits.core.services.payments.send_payment_notification_in_background",
AsyncMock(return_value=None), AsyncMock(return_value=None),
) )
wallet = await get_wallet(from_wallet.id) wallet = await get_wallet(from_wallet.id)
@ -520,7 +520,7 @@ async def test_retry_pay_success(
AsyncMock(return_value=payment_reponse_pending), AsyncMock(return_value=payment_reponse_pending),
) )
ws_notification = mocker.patch( ws_notification = mocker.patch(
"lnbits.core.services.payments.send_payment_notification", "lnbits.core.services.payments.send_payment_notification_in_background",
AsyncMock(return_value=None), AsyncMock(return_value=None),
) )
wallet = await get_wallet(from_wallet.id) wallet = await get_wallet(from_wallet.id)