feat: add settings.lnbits_running (#2450)

* feat: add `settings.lnbits_runing `
This commit is contained in:
Vlad Stan 2024-04-22 12:33:53 +03:00 committed by GitHub
parent e91096c535
commit 4ac30116a9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 41 additions and 26 deletions

View File

@ -69,6 +69,8 @@ from .tasks import (
async def startup(app: FastAPI): async def startup(app: FastAPI):
settings.lnbits_running = True
# wait till migration is done # wait till migration is done
await migrate_databases() await migrate_databases()
@ -104,6 +106,9 @@ async def startup(app: FastAPI):
async def shutdown(): async def shutdown():
logger.warning("LNbits shutting down...")
settings.lnbits_running = False
# shutdown event # shutdown event
cancel_all_tasks() cancel_all_tasks()
@ -181,7 +186,7 @@ async def check_funding_source() -> None:
max_retries = settings.funding_source_max_retries max_retries = settings.funding_source_max_retries
retry_counter = 0 retry_counter = 0
while True: while settings.lnbits_running:
try: try:
logger.info(f"Connecting to backend {funding_source.__class__.__name__}...") logger.info(f"Connecting to backend {funding_source.__class__.__name__}...")
error_message, balance = await funding_source.status() error_message, balance = await funding_source.status()
@ -412,7 +417,7 @@ def initialize_server_logger():
serverlog_queue = asyncio.Queue() serverlog_queue = asyncio.Queue()
async def update_websocket_serverlog(): async def update_websocket_serverlog():
while True: while settings.lnbits_running:
msg = await serverlog_queue.get() msg = await serverlog_queue.get()
await websocket_updater(super_user_hash, msg) await websocket_updater(super_user_hash, msg)

View File

@ -26,7 +26,7 @@ async def killswitch_task():
killswitch will check lnbits-status repository for a signal from killswitch will check lnbits-status repository for a signal from
LNbits and will switch to VoidWallet if the killswitch is triggered. LNbits and will switch to VoidWallet if the killswitch is triggered.
""" """
while True: while settings.lnbits_running:
funding_source = get_funding_source() funding_source = get_funding_source()
if ( if (
settings.lnbits_killswitch settings.lnbits_killswitch
@ -56,7 +56,7 @@ async def watchdog_task():
Registers a watchdog which will check lnbits balance and nodebalance Registers a watchdog which will check lnbits balance and nodebalance
and will switch to VoidWallet if the watchdog delta is reached. and will switch to VoidWallet if the watchdog delta is reached.
""" """
while True: while settings.lnbits_running:
funding_source = get_funding_source() funding_source = get_funding_source()
if ( if (
settings.lnbits_watchdog settings.lnbits_watchdog
@ -77,7 +77,7 @@ async def wait_for_paid_invoices(invoice_paid_queue: asyncio.Queue):
""" """
This worker dispatches events to all extensions and dispatches webhooks. This worker dispatches events to all extensions and dispatches webhooks.
""" """
while True: while settings.lnbits_running:
payment = await invoice_paid_queue.get() payment = await invoice_paid_queue.get()
logger.trace("received invoice paid event") logger.trace("received invoice paid event")
# dispatch api_invoice_listeners # dispatch api_invoice_listeners

View File

@ -379,7 +379,7 @@ async def subscribe_wallet_invoices(request: Request, wallet: Wallet):
api_invoice_listeners[uid] = payment_queue api_invoice_listeners[uid] = payment_queue
try: try:
while True: while settings.lnbits_running:
if await request.is_disconnected(): if await request.is_disconnected():
await request.close() await request.close()
break break

View File

@ -4,6 +4,8 @@ from fastapi import (
WebSocketDisconnect, WebSocketDisconnect,
) )
from lnbits.settings import settings
from ..services import ( from ..services import (
websocket_manager, websocket_manager,
websocket_updater, websocket_updater,
@ -16,7 +18,7 @@ websocket_router = APIRouter(prefix="/api/v1/ws", tags=["Websocket"])
async def websocket_connect(websocket: WebSocket, item_id: str): async def websocket_connect(websocket: WebSocket, item_id: str):
await websocket_manager.connect(websocket, item_id) await websocket_manager.connect(websocket, item_id)
try: try:
while True: while settings.lnbits_running:
await websocket.receive_text() await websocket.receive_text()
except WebSocketDisconnect: except WebSocketDisconnect:
websocket_manager.disconnect(websocket) websocket_manager.disconnect(websocket)

View File

@ -423,6 +423,12 @@ class TransientSettings(InstalledExtensionsSettings):
# - are cleared on server restart # - are cleared on server restart
first_install: bool = Field(default=False) first_install: bool = Field(default=False)
# Indicates that the server should continue to run.
# When set to false it indicates that the shutdown procedure is ongoing.
# If false no new tasks, threads, etc should be started.
# Long running while loops should use this flag instead of `while True:`
lnbits_running: bool = Field(default=True)
@classmethod @classmethod
def readonly_fields(cls): def readonly_fields(cls):
return [f for f in inspect.signature(cls).parameters if not f.startswith("_")] return [f for f in inspect.signature(cls).parameters if not f.startswith("_")]

View File

@ -106,7 +106,7 @@ async def internal_invoice_listener():
Called by the app startup sequence. Called by the app startup sequence.
""" """
while True: while settings.lnbits_running:
checking_id = await internal_invoice_queue.get() checking_id = await internal_invoice_queue.get()
logger.info("> got internal payment notification", checking_id) logger.info("> got internal payment notification", checking_id)
create_task(invoice_callback_dispatcher(checking_id)) create_task(invoice_callback_dispatcher(checking_id))
@ -134,7 +134,7 @@ async def check_pending_payments():
outgoing = True outgoing = True
incoming = True incoming = True
while True: while settings.lnbits_running:
logger.info( logger.info(
f"Task: checking all pending payments (incoming={incoming}," f"Task: checking all pending payments (incoming={incoming},"
f" outgoing={outgoing}) of last 15 days" f" outgoing={outgoing}) of last 15 days"

View File

@ -6,6 +6,8 @@ from typing import Any, NamedTuple, Optional
from loguru import logger from loguru import logger
from lnbits.settings import settings
class Cached(NamedTuple): class Cached(NamedTuple):
value: Any value: Any
@ -52,7 +54,7 @@ class Cache:
return value return value
async def invalidate_forever(self): async def invalidate_forever(self):
while True: while settings.lnbits_running:
try: try:
await asyncio.sleep(self.interval) await asyncio.sleep(self.interval)
ts = time() ts = time()

View File

@ -184,6 +184,6 @@ class AlbyWallet(Wallet):
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]: async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
self.queue: asyncio.Queue = asyncio.Queue(0) self.queue: asyncio.Queue = asyncio.Queue(0)
while True: while settings.lnbits_running:
value = await self.queue.get() value = await self.queue.get()
yield value yield value

View File

@ -166,10 +166,10 @@ class ClicheWallet(Wallet):
) )
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]: async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
while True: while settings.lnbits_running:
try: try:
ws = create_connection(self.endpoint) ws = create_connection(self.endpoint)
while True: while settings.lnbits_running:
r = ws.recv() r = ws.recv()
data = json.loads(r) data = json.loads(r)
print(data) print(data)

View File

@ -232,7 +232,7 @@ class CoreLightningWallet(Wallet):
return PaymentPendingStatus() return PaymentPendingStatus()
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]: async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
while True: while settings.lnbits_running:
try: try:
paid = await run_sync( paid = await run_sync(
lambda: self.ln.waitanyinvoice(self.last_pay_index, timeout=2) lambda: self.ln.waitanyinvoice(self.last_pay_index, timeout=2)

View File

@ -256,7 +256,7 @@ class CoreLightningRestWallet(Wallet):
return PaymentPendingStatus() return PaymentPendingStatus()
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]: async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
while True: while settings.lnbits_running:
try: try:
url = f"{self.url}/v1/invoice/waitAnyInvoice/{self.last_pay_index}" url = f"{self.url}/v1/invoice/waitAnyInvoice/{self.last_pay_index}"
async with self.client.stream("GET", url, timeout=None) as r: async with self.client.stream("GET", url, timeout=None) as r:

View File

@ -215,13 +215,13 @@ class EclairWallet(Wallet):
return PaymentPendingStatus() return PaymentPendingStatus()
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]: async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
while True: while settings.lnbits_running:
try: try:
async with connect( async with connect(
self.ws_url, self.ws_url,
extra_headers=[("Authorization", self.headers["Authorization"])], extra_headers=[("Authorization", self.headers["Authorization"])],
) as ws: ) as ws:
while True: while settings.lnbits_running:
message = await ws.recv() message = await ws.recv()
message_json = json.loads(message) message_json = json.loads(message)

View File

@ -133,6 +133,6 @@ class FakeWallet(Wallet):
return PaymentPendingStatus() return PaymentPendingStatus()
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]: async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
while True: while settings.lnbits_running:
value: Bolt11 = await self.queue.get() value: Bolt11 = await self.queue.get()
yield value.payment_hash yield value.payment_hash

View File

@ -155,7 +155,7 @@ class LNbitsWallet(Wallet):
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]: async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
url = f"{self.endpoint}/api/v1/payments/sse" url = f"{self.endpoint}/api/v1/payments/sse"
while True: while settings.lnbits_running:
try: try:
async with httpx.AsyncClient( async with httpx.AsyncClient(
timeout=None, headers=self.headers timeout=None, headers=self.headers

View File

@ -268,7 +268,7 @@ class LndWallet(Wallet):
return PaymentPendingStatus() return PaymentPendingStatus()
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]: async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
while True: while settings.lnbits_running:
try: try:
request = ln.InvoiceSubscription() request = ln.InvoiceSubscription()
async for i in self.rpc.SubscribeInvoices(request): async for i in self.rpc.SubscribeInvoices(request):

View File

@ -280,7 +280,7 @@ class LndRestWallet(Wallet):
return PaymentPendingStatus() return PaymentPendingStatus()
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]: async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
while True: while settings.lnbits_running:
try: try:
url = "/v1/invoices/subscribe" url = "/v1/invoices/subscribe"
async with self.client.stream("GET", url, timeout=None) as r: async with self.client.stream("GET", url, timeout=None) as r:

View File

@ -145,6 +145,6 @@ class LNPayWallet(Wallet):
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]: async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
self.queue: asyncio.Queue = asyncio.Queue(0) self.queue: asyncio.Queue = asyncio.Queue(0)
while True: while settings.lnbits_running:
value = await self.queue.get() value = await self.queue.get()
yield value yield value

View File

@ -152,7 +152,7 @@ class LnTipsWallet(Wallet):
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]: async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
last_connected = None last_connected = None
while True: while settings.lnbits_running:
url = "/api/v1/invoicestream" url = "/api/v1/invoicestream"
try: try:
last_connected = time.time() last_connected = time.time()

View File

@ -141,6 +141,6 @@ class OpenNodeWallet(Wallet):
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]: async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
self.queue: asyncio.Queue = asyncio.Queue(0) self.queue: asyncio.Queue = asyncio.Queue(0)
while True: while settings.lnbits_running:
value = await self.queue.get() value = await self.queue.get()
yield value yield value

View File

@ -244,7 +244,7 @@ class SparkWallet(Wallet):
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]: async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
url = f"/stream?access-key={self.token}" url = f"/stream?access-key={self.token}"
while True: while settings.lnbits_running:
try: try:
async with self.client.stream("GET", url, timeout=None) as r: async with self.client.stream("GET", url, timeout=None) as r:
async for line in r.aiter_lines(): async for line in r.aiter_lines():

View File

@ -154,6 +154,6 @@ class ZBDWallet(Wallet):
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]: async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
self.queue: asyncio.Queue = asyncio.Queue(0) self.queue: asyncio.Queue = asyncio.Queue(0)
while True: while settings.lnbits_running:
value = await self.queue.get() value = await self.queue.get()
yield value yield value