feat: extension lifecycle hooks (__init__.py)
- restaurant_start spawns three permanent tasks:
1. invoice listener (LNBits payment settlement)
2. NostrClient bootstrap (after 10s grace for nostrclient ext)
3. Nostr sync loop (after 15s)
- restaurant_stop cancels tasks and closes the WS.
- Module-level nostr_client = None when nostrclient unavailable;
publishing helpers no-op gracefully in that case.
This commit is contained in:
parent
5c19cf6691
commit
3b046276f6
1 changed files with 89 additions and 0 deletions
89
__init__.py
Normal file
89
__init__.py
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
import asyncio
|
||||
|
||||
from fastapi import APIRouter
|
||||
from loguru import logger
|
||||
|
||||
from .crud import db
|
||||
from .tasks import wait_for_paid_invoices
|
||||
from .views import restaurant_generic_router
|
||||
from .views_api import restaurant_api_router
|
||||
|
||||
restaurant_ext: APIRouter = APIRouter(prefix="/restaurant", tags=["Restaurant"])
|
||||
restaurant_ext.include_router(restaurant_generic_router)
|
||||
restaurant_ext.include_router(restaurant_api_router)
|
||||
|
||||
restaurant_static_files = [
|
||||
{
|
||||
"path": "/restaurant/static",
|
||||
"name": "restaurant_static",
|
||||
}
|
||||
]
|
||||
|
||||
scheduled_tasks: list[asyncio.Task] = []
|
||||
|
||||
# Module-level NostrClient — None when nostrclient extension is unavailable.
|
||||
# Populated by the lifecycle task below.
|
||||
nostr_client = None
|
||||
|
||||
|
||||
def restaurant_stop():
|
||||
for task in scheduled_tasks:
|
||||
try:
|
||||
task.cancel()
|
||||
except Exception as ex:
|
||||
logger.warning(ex)
|
||||
|
||||
global nostr_client
|
||||
if nostr_client:
|
||||
asyncio.get_event_loop().create_task(nostr_client.stop())
|
||||
|
||||
|
||||
def restaurant_start():
|
||||
from lnbits.tasks import create_permanent_unique_task
|
||||
|
||||
# Invoice listener — settles orders on payment, kicks off print jobs.
|
||||
task1 = create_permanent_unique_task("ext_restaurant", wait_for_paid_invoices)
|
||||
scheduled_tasks.append(task1)
|
||||
|
||||
async def _start_nostr_client():
|
||||
global nostr_client
|
||||
await asyncio.sleep(10) # Wait for nostrclient to be ready
|
||||
try:
|
||||
from .nostr.nostr_client import NostrClient
|
||||
|
||||
nostr_client = NostrClient()
|
||||
logger.info("[RESTAURANT] Starting NostrClient for menu + order sync")
|
||||
await nostr_client.run_forever()
|
||||
except Exception as e:
|
||||
logger.warning(f"[RESTAURANT] NostrClient failed to start: {e}")
|
||||
logger.info("[RESTAURANT] Restaurant will work without Nostr layer")
|
||||
|
||||
task2 = create_permanent_unique_task("ext_restaurant_nostr", _start_nostr_client)
|
||||
scheduled_tasks.append(task2)
|
||||
|
||||
async def _sync_nostr_events():
|
||||
global nostr_client
|
||||
await asyncio.sleep(15)
|
||||
if not nostr_client:
|
||||
logger.info("[RESTAURANT] No NostrClient, skipping Nostr sync")
|
||||
return
|
||||
try:
|
||||
from .nostr_sync import wait_for_nostr_events
|
||||
|
||||
await wait_for_nostr_events(nostr_client)
|
||||
except Exception as e:
|
||||
logger.error(f"[RESTAURANT] Nostr sync task failed: {e}")
|
||||
|
||||
task3 = create_permanent_unique_task(
|
||||
"ext_restaurant_nostr_sync", _sync_nostr_events
|
||||
)
|
||||
scheduled_tasks.append(task3)
|
||||
|
||||
|
||||
__all__ = [
|
||||
"db",
|
||||
"restaurant_ext",
|
||||
"restaurant_start",
|
||||
"restaurant_static_files",
|
||||
"restaurant_stop",
|
||||
]
|
||||
Loading…
Add table
Add a link
Reference in a new issue