fix sqlite database locked issues by using an async lock on the database and requiring explicit transaction control (or each command will be its own transaction).

This commit is contained in:
fiatjaf
2021-03-26 19:10:30 -03:00
parent 9cc7052920
commit 85011d23c3
10 changed files with 276 additions and 276 deletions
+2 -3
View File
@@ -1,6 +1,6 @@
import json
import math
from quart import g, jsonify, request
from quart import jsonify, request
from http import HTTPStatus
import traceback
@@ -29,7 +29,6 @@ from .helpers import (
# Handles signed URL from Bleskomat ATMs and "action" callback of auto-generated LNURLs.
@bleskomat_ext.route("/u", methods=["GET"])
async def api_bleskomat_lnurl():
try:
query = request.args.to_dict()
@@ -125,7 +124,7 @@ async def api_bleskomat_lnurl():
except LnurlHttpError as e:
return jsonify({"status": "ERROR", "reason": str(e)}), e.http_status
except Exception as e:
except Exception:
traceback.print_exc()
return (
jsonify({"status": "ERROR", "reason": "Unexpected error"}),
+8 -17
View File
@@ -61,7 +61,7 @@ class BleskomatLnurl(NamedTuple):
raise LnurlValidationError("Multiple payment requests not supported")
try:
invoice = bolt11.decode(pr)
except ValueError as e:
except ValueError:
raise LnurlValidationError(
'Invalid parameter ("pr"): Lightning payment request expected'
)
@@ -79,14 +79,11 @@ class BleskomatLnurl(NamedTuple):
async def execute_action(self, query: Dict[str, str]):
self.validate_action(query)
used = False
if self.initial_uses > 0:
await db.commit()
await db.begin()
used = await self.use()
if not used:
await db.rollback()
raise LnurlValidationError("Maximum number of uses already reached")
try:
async with db.connect() as conn:
if self.initial_uses > 0:
used = await self.use(conn)
if not used:
raise LnurlValidationError("Maximum number of uses already reached")
tag = self.tag
if tag == "withdrawRequest":
payment_hash = await pay_invoice(
@@ -95,16 +92,10 @@ class BleskomatLnurl(NamedTuple):
)
if not payment_hash:
raise LnurlValidationError("Failed to pay invoice")
except Exception as e:
if used:
await db.rollback()
raise e
if used:
await db.commit()
async def use(self) -> bool:
async def use(self, conn) -> bool:
now = int(time.time())
result = await db.execute(
result = await conn.execute(
"""
UPDATE bleskomat_lnurls
SET remaining_uses = remaining_uses - 1, updated_time = ?
+1 -2
View File
@@ -70,11 +70,10 @@ async def api_bleskomat_retrieve(bleskomat_id):
}
)
async def api_bleskomat_create_or_update(bleskomat_id=None):
try:
fiat_currency = g.data["fiat_currency"]
exchange_rate_provider = g.data["exchange_rate_provider"]
rate = await fetch_fiat_exchange_rate(
await fetch_fiat_exchange_rate(
currency=fiat_currency, provider=exchange_rate_provider
)
except Exception as e: