Spaces:
Sleeping
Sleeping
google-labs-jules[bot]
commited on
Commit
·
59e0951
1
Parent(s):
256d59e
Fix infinite spinner by ensuring terminal job state in worker
Browse filesWraps `generate_only` in a `try...except...finally` block to catch unexpected errors and guarantee that the job status is updated to "error" or "completed". This prevents the "Zombie Job" scenario where the frontend polls indefinitely.
- Moved initial setup logic inside the `try` block.
- Added a `finally` block to enforce terminal state check on the status file.
- Log exceptions for better debugging.
agent.py
CHANGED
|
@@ -99,12 +99,12 @@ def analyze_only(path_a, path_c, job_id=None):
|
|
| 99 |
return {"detail": str(e), "status": "error"}
|
| 100 |
|
| 101 |
def generate_only(prompt, path_a, path_c, job_id, style, audio, neg, guidance, motion):
|
| 102 |
-
update_job_status(job_id, "generating", 50, "Production started (Veo 3.1)...")
|
| 103 |
-
full_prompt = f"{style} style. {prompt} Soundtrack: {audio}"
|
| 104 |
-
if neg:
|
| 105 |
-
full_prompt += f" --no {neg}"
|
| 106 |
-
|
| 107 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
if Settings.GCP_PROJECT_ID:
|
| 109 |
client = genai.Client(vertexai=True, project=Settings.GCP_PROJECT_ID, location=Settings.GCP_LOCATION)
|
| 110 |
op = client.models.generate_videos(
|
|
@@ -135,7 +135,25 @@ def generate_only(prompt, path_a, path_c, job_id, style, audio, neg, guidance, m
|
|
| 135 |
logger.error(f"Stitch error: {e}")
|
| 136 |
update_job_status(job_id, "completed", 100, "Stitch failed, showing bridge.", video_url=bridge_path)
|
| 137 |
return
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
except Exception as e:
|
|
|
|
| 139 |
update_job_status(job_id, "error", 0, f"Error: {e}")
|
| 140 |
-
|
| 141 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
return {"detail": str(e), "status": "error"}
|
| 100 |
|
| 101 |
def generate_only(prompt, path_a, path_c, job_id, style, audio, neg, guidance, motion):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 102 |
try:
|
| 103 |
+
update_job_status(job_id, "generating", 50, "Production started (Veo 3.1)...")
|
| 104 |
+
full_prompt = f"{style} style. {prompt} Soundtrack: {audio}"
|
| 105 |
+
if neg:
|
| 106 |
+
full_prompt += f" --no {neg}"
|
| 107 |
+
|
| 108 |
if Settings.GCP_PROJECT_ID:
|
| 109 |
client = genai.Client(vertexai=True, project=Settings.GCP_PROJECT_ID, location=Settings.GCP_LOCATION)
|
| 110 |
op = client.models.generate_videos(
|
|
|
|
| 135 |
logger.error(f"Stitch error: {e}")
|
| 136 |
update_job_status(job_id, "completed", 100, "Stitch failed, showing bridge.", video_url=bridge_path)
|
| 137 |
return
|
| 138 |
+
|
| 139 |
+
# If we reach here, something failed or didn't generate video
|
| 140 |
+
update_job_status(job_id, "error", 0, "Generation failed.")
|
| 141 |
+
|
| 142 |
except Exception as e:
|
| 143 |
+
logger.error(f"Worker crashed: {e}")
|
| 144 |
update_job_status(job_id, "error", 0, f"Error: {e}")
|
| 145 |
+
|
| 146 |
+
finally:
|
| 147 |
+
# Enforce Terminal State
|
| 148 |
+
try:
|
| 149 |
+
status_file = f"outputs/{job_id}.json"
|
| 150 |
+
if os.path.exists(status_file):
|
| 151 |
+
with open(status_file, "r") as f:
|
| 152 |
+
data = json.load(f)
|
| 153 |
+
|
| 154 |
+
status = data.get("status")
|
| 155 |
+
if status not in ["completed", "error"]:
|
| 156 |
+
logger.warning(f"Job {job_id} left in non-terminal state ({status}). Forcing error.")
|
| 157 |
+
update_job_status(job_id, "error", 0, "Job terminated unexpectedly.")
|
| 158 |
+
except Exception as e:
|
| 159 |
+
logger.error(f"Final safety net failed: {e}")
|