JonathanColetti commited on
Commit
d5bd942
·
verified ·
1 Parent(s): 2ee5f0c

surface worker errors instead of blocking on the frame queue

Browse files
Files changed (1) hide show
  1. app.py +26 -11
app.py CHANGED
@@ -55,6 +55,7 @@ GITHUB = "https://github.com/JonathanColetti/LiveWan"
55
  FPS = 16
56
  BLOCK_SECONDS = 0.75 # 3 latent frames -> 12 pixel frames at 16 fps
57
  NO_STEER = "don't steer, stay on the opening prompt"
 
58
 
59
  # ---------------------------------------------------------------- bootstrap
60
 
@@ -201,19 +202,30 @@ def run(world: str, steer_to: str, steer_at: float, seconds: float, seed: int):
201
  engine.start(world=WORLDS[world], seed=int(seed))
202
  frames, pending_steer, last_push = [], steer_idx is not None, 0.0
203
 
 
 
 
 
 
204
  try:
205
  while len(frames) < total_frames:
206
- if engine.status.state == "error":
207
- raise gr.Error(f"engine error: {engine.status.error}")
208
  try:
209
- jpg = engine.frames.get(timeout=60)
210
  except queue.Empty:
211
- # The worker sets state to idle and puts the reason in `detail` when
212
- # a stream ends on its own (the 1024-latent-frame RoPE ceiling).
213
- if engine.status.state != "streaming":
 
 
 
 
214
  break
215
- raise gr.Error("the stream stalled waiting for a block")
 
 
 
216
 
 
217
  frames.append(cv2.imdecode(np.frombuffer(jpg, np.uint8),
218
  cv2.IMREAD_COLOR)[:, :, ::-1])
219
 
@@ -226,14 +238,17 @@ def run(world: str, steer_to: str, steer_at: float, seconds: float, seed: int):
226
  last_push = now
227
  yield frames[-1], hud(engine.stats(), now - t0), None
228
  finally:
 
 
 
 
229
  engine.stop()
230
 
231
  if not frames:
232
  raise gr.Error("no frames were produced")
233
- note = engine.status.detail
234
- line = hud(engine.stats(), time.perf_counter() - t0)
235
- if note:
236
- line += f"\n\n_{note}_"
237
  yield frames[-1], line, write_mp4(frames)
238
 
239
 
 
55
  FPS = 16
56
  BLOCK_SECONDS = 0.75 # 3 latent frames -> 12 pixel frames at 16 fps
57
  NO_STEER = "don't steer, stay on the opening prompt"
58
+ STALL_SECONDS = 45 # a block is ~0.3 s; this only trips when something is wrong
59
 
60
  # ---------------------------------------------------------------- bootstrap
61
 
 
202
  engine.start(world=WORLDS[world], seed=int(seed))
203
  frames, pending_steer, last_push = [], steer_idx is not None, 0.0
204
 
205
+ # The worker runs in a thread and reports failure by setting status.state rather
206
+ # than raising here, so poll it between frames: a long blocking get() would spend
207
+ # the whole GPU reservation waiting on a stream that is already dead.
208
+ ended = ""
209
+ last_frame_at = time.perf_counter()
210
  try:
211
  while len(frames) < total_frames:
 
 
212
  try:
213
+ jpg = engine.frames.get(timeout=0.5)
214
  except queue.Empty:
215
+ state = engine.status.state
216
+ if state == "error":
217
+ raise gr.Error(f"engine error: {engine.status.error}")
218
+ if state != "streaming":
219
+ # The worker ends the stream itself at the 1024-latent-frame
220
+ # RoPE ceiling and puts the reason in `detail`.
221
+ ended = engine.status.detail
222
  break
223
+ if time.perf_counter() - last_frame_at > STALL_SECONDS:
224
+ raise gr.Error(
225
+ f"no block in {STALL_SECONDS} s (state={state})")
226
+ continue
227
 
228
+ last_frame_at = time.perf_counter()
229
  frames.append(cv2.imdecode(np.frombuffer(jpg, np.uint8),
230
  cv2.IMREAD_COLOR)[:, :, ::-1])
231
 
 
238
  last_push = now
239
  yield frames[-1], hud(engine.stats(), now - t0), None
240
  finally:
241
+ stats = engine.stats()
242
+ print(f"[run] {len(frames)} frames, {stats['blocks']} blocks, "
243
+ f"state={engine.status.state!r} detail={engine.status.detail!r} "
244
+ f"error={engine.status.error!r}", flush=True)
245
  engine.stop()
246
 
247
  if not frames:
248
  raise gr.Error("no frames were produced")
249
+ line = hud(stats, time.perf_counter() - t0)
250
+ if ended:
251
+ line += f"\n\n_{ended}_"
 
252
  yield frames[-1], line, write_mp4(frames)
253
 
254