SemSorter commited on
Commit
e085e6c
·
1 Parent(s): 0612f0f

Disable eager simulation pre-warming on server boot to prevent combined memory spikes

Browse files
Files changed (1) hide show
  1. SemSorter/server/app.py +18 -5
SemSorter/server/app.py CHANGED
@@ -140,14 +140,11 @@ async def _simulation_tick_loop() -> None:
140
 
141
  @app.on_event("startup")
142
  async def startup():
143
- global _main_loop, _sim_tick_task, _frame_ready_event
144
  _main_loop = asyncio.get_running_loop()
145
  _frame_ready_event = asyncio.Event()
146
  bridge.set_frame_ready_event(_main_loop, _frame_ready_event)
147
- logger.info("Pre-warming MuJoCo simulation…")
148
- await bridge.run_in_sim_thread(bridge.get_simulation)
149
- _sim_tick_task = asyncio.create_task(_simulation_tick_loop())
150
- logger.info("Simulation ready")
151
 
152
 
153
  @app.on_event("shutdown")
@@ -229,9 +226,17 @@ async def api_tts(text: str):
229
 
230
  @app.websocket("/ws/chat")
231
  async def ws_chat(ws: WebSocket):
 
232
  await ws.accept()
233
  _chat_clients.add(ws)
234
  logger.info("Chat client connected (%d total)", len(_chat_clients))
 
 
 
 
 
 
 
235
  try:
236
  await ws.send_text(json.dumps({
237
  "type": "welcome",
@@ -313,9 +318,17 @@ async def ws_chat(ws: WebSocket):
313
  # ── WebSocket: live video stream ──────────────────────────────────────────────
314
  @app.websocket("/ws/video")
315
  async def ws_video(ws: WebSocket):
 
316
  await ws.accept()
317
  _video_clients.add(ws)
318
  logger.info("Video client connected")
 
 
 
 
 
 
 
319
  try:
320
  while True:
321
  # Wait for new frame (event-driven; sends exactly when sim produces one)
 
140
 
141
  @app.on_event("startup")
142
  async def startup():
143
+ global _main_loop, _frame_ready_event
144
  _main_loop = asyncio.get_running_loop()
145
  _frame_ready_event = asyncio.Event()
146
  bridge.set_frame_ready_event(_main_loop, _frame_ready_event)
147
+ logger.info("Server ready (Simulation will load lazily on first connect)")
 
 
 
148
 
149
 
150
  @app.on_event("shutdown")
 
226
 
227
  @app.websocket("/ws/chat")
228
  async def ws_chat(ws: WebSocket):
229
+ global _sim_tick_task
230
  await ws.accept()
231
  _chat_clients.add(ws)
232
  logger.info("Chat client connected (%d total)", len(_chat_clients))
233
+
234
+ # Lazily start simulation if this is the first client
235
+ if _sim_tick_task is None:
236
+ logger.info("First client connected; starting MuJoCo simulation...")
237
+ await bridge.run_in_sim_thread(bridge.get_simulation)
238
+ _sim_tick_task = asyncio.create_task(_simulation_tick_loop())
239
+
240
  try:
241
  await ws.send_text(json.dumps({
242
  "type": "welcome",
 
318
  # ── WebSocket: live video stream ──────────────────────────────────────────────
319
  @app.websocket("/ws/video")
320
  async def ws_video(ws: WebSocket):
321
+ global _sim_tick_task
322
  await ws.accept()
323
  _video_clients.add(ws)
324
  logger.info("Video client connected")
325
+
326
+ # Lazily start simulation if this is the first client
327
+ if _sim_tick_task is None:
328
+ logger.info("First client connected; starting MuJoCo simulation...")
329
+ await bridge.run_in_sim_thread(bridge.get_simulation)
330
+ _sim_tick_task = asyncio.create_task(_simulation_tick_loop())
331
+
332
  try:
333
  while True:
334
  # Wait for new frame (event-driven; sends exactly when sim produces one)