fix: reliable cloud sync and connection pooling for Render live dashboard

This commit is contained in:
2026-09-17 16:41:52 +05:30
parent 68bda2519f
commit 37445d2ae9
8 changed files with 286 additions and 48 deletions
+83
View File
@@ -79,3 +79,86 @@ async def retry_failed_transmissions():
logger.error(f"Error in retry background task: {e}")
await asyncio.sleep(settings.retry_interval_seconds)
async def sync_cloud_state():
"""
Periodically syncs all assigned patients and their latest non-null vitals to Render Cloud.
Ensures that whenever Render restarts or deploys with an empty DB, the cloud dashboard
is immediately populated with the same data as localhost.
"""
import os
if os.getenv("RENDER") is not None or os.getenv("PORT") == "10000" or "render.local" in os.getenv("HOSTNAME", ""):
return # Do not run sync loop if we are running inside Render
from models import Patient
from api_client import sync_patient_assignment_to_cloud, forward_vitals_to_api
from datetime import datetime, timezone
from sqlalchemy import or_
logger.info("Starting background task for periodic cloud state sync to Render...")
await asyncio.sleep(5)
while True:
try:
db = SessionLocal()
try:
patients = db.query(Patient).filter(
Patient.patient_id != "UNKNOWN",
Patient.mrn != "UNKNOWN"
).all()
for p in patients:
if not p.device_id:
continue
# 1. Sync patient demographics assignment to Render
p_data = {
"mrn": p.mrn or p.patient_id,
"name": p.name,
"gender": p.gender,
"dob": p.dob,
"bed_id": p.bed_id,
"patient_type": getattr(p, "patient_type", None)
}
await sync_patient_assignment_to_cloud(p_data, p.device_id)
# 2. Backfill and forward latest complete non-null vitals to Render
patient_filters = or_(
VitalReading.patient_id == p.mrn,
VitalReading.patient_id == p.patient_id,
VitalReading.device_id == p.device_id
)
recent_r = db.query(VitalReading).filter(patient_filters).order_by(VitalReading.timestamp.desc()).first()
if recent_r:
spo2_r = db.query(VitalReading.spo2).filter(patient_filters, VitalReading.spo2 != None).order_by(VitalReading.timestamp.desc()).first()
hr_r = db.query(VitalReading.heart_rate).filter(patient_filters, VitalReading.heart_rate != None).order_by(VitalReading.timestamp.desc()).first()
bp_r = db.query(VitalReading.systolic_bp, VitalReading.diastolic_bp, VitalReading.map_bp).filter(patient_filters, VitalReading.systolic_bp != None).order_by(VitalReading.timestamp.desc()).first()
temp_r = db.query(VitalReading.temperature).filter(patient_filters, VitalReading.temperature != None).order_by(VitalReading.timestamp.desc()).first()
rr_r = db.query(VitalReading.respiratory_rate).filter(patient_filters, VitalReading.respiratory_rate != None).order_by(VitalReading.timestamp.desc()).first()
merged = NormalizedVitals(
device_id=p.device_id,
patient_id=p.mrn or p.patient_id,
patient_name=p.name,
patient_gender=p.gender,
patient_dob=p.dob,
bed_id=p.bed_id,
patient_type=getattr(p, "patient_type", None),
timestamp=recent_r.timestamp or datetime.now(timezone.utc),
heart_rate=hr_r[0] if hr_r else None,
spo2=spo2_r[0] if spo2_r else None,
systolic_bp=bp_r[0] if bp_r else None,
diastolic_bp=bp_r[1] if bp_r else None,
map_bp=bp_r[2] if bp_r else None,
temperature=temp_r[0] if temp_r else None,
respiratory_rate=rr_r[0] if rr_r else None
)
await forward_vitals_to_api(merged)
finally:
db.close()
except Exception as e:
logger.error(f"Error in sync_cloud_state background task: {e}")
await asyncio.sleep(15)