Files
replypier/backend/app/core/system_maintenance.py
T
WangShen007 f3ad539998 feat(updates): check Gitea automatically and deploy on owner confirmation
Add owner-only update controls, a read-only SSH checker and independent systemd deployment services. Build before maintenance; back up code and database; restore on failed deployment. Preserve runtime configuration and gate business writes during the switch.
2026-10-24 07:26:41 +00:00

31 lines
1.3 KiB
Python

"""Gate business traffic during deployment and database recovery, including sockets."""
import asyncio
from pathlib import Path
from starlette.types import ASGIApp, Receive, Scope, Send
from starlette.responses import JSONResponse
MAINTENANCE_FILE = Path('/var/lib/replypier-updater/maintenance')
class SystemMaintenanceMiddleware:
def __init__(self, app: ASGIApp) -> None:
self.app = app
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
path = scope.get('path', '')
exempt = path == '/health' or (path == '/api/v1/system-updates' and scope.get('method') == 'GET')
if scope['type'] in {'http', 'websocket'} and MAINTENANCE_FILE.exists() and not exempt:
if scope['type'] == 'websocket':
await send({'type': 'websocket.close', 'code': 1013})
else:
response = JSONResponse({'detail': '系统更新中,接待将在更新完成后恢复。'},
status_code=503, headers={'Retry-After': '5'})
await response(scope, receive, send)
return
await self.app(scope, receive, send)
async def wait_for_deployment() -> None:
while MAINTENANCE_FILE.exists():
await asyncio.sleep(1)