Skip to content

Commit b6b0e52

Browse files
lolimmlostclaude
andcommitted
fix: Show waiting message during startup instead of hanging spinners
Partials now return "Waiting for first cycle to complete…" instantly during startup instead of calling arr APIs that may hang. SSE cycle_end already triggers auto-refresh so no manual page reload is needed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 5268179 commit b6b0e52

2 files changed

Lines changed: 25 additions & 1 deletion

File tree

src/web/app.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from src.web.config_manager import ConfigManager
1111
from src.web.database import ActivityRecorder, Database
12-
from src.web.events import EventBus
12+
from src.web.events import EventBus, EventType
1313
from src.web.routes import api_router, page_router
1414

1515

@@ -28,6 +28,7 @@ def create_app(settings, event_bus: EventBus, trigger_event: asyncio.Event = Non
2828
app.state.templates = templates
2929
app.state.start_time = time.time()
3030
app.state.trigger_event = trigger_event
31+
app.state.first_cycle_done = False
3132

3233
# Register routes
3334
app.include_router(api_router)
@@ -58,6 +59,21 @@ async def start_web_server(settings, event_bus: EventBus, trigger_event: asyncio
5859
await recorder.start()
5960
app.state.recorder = recorder
6061

62+
# Track when the first main-loop cycle finishes so partials can show
63+
# a "waiting" message instead of hanging on arr API calls during startup.
64+
async def _mark_first_cycle_done():
65+
queue = event_bus.subscribe()
66+
try:
67+
while True:
68+
event = await queue.get()
69+
if event.event_type == EventType.CYCLE_END:
70+
app.state.first_cycle_done = True
71+
break
72+
finally:
73+
event_bus.unsubscribe(queue)
74+
75+
asyncio.create_task(_mark_first_cycle_done())
76+
6177
# Schedule daily cleanup of old activity log entries
6278
async def _periodic_cleanup():
6379
while True:

src/web/routes.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,10 @@ async def page_settings(request: Request):
456456
@page_router.get("/partials/queue-table", response_class=HTMLResponse)
457457
async def partial_queue_table(request: Request):
458458
templates = request.app.state.templates
459+
if not getattr(request.app.state, "first_cycle_done", True):
460+
return HTMLResponse(
461+
'<p><em>Waiting for first cycle to complete\u2026</em></p>'
462+
)
459463
items = await _fetch_queue(request)
460464
return templates.TemplateResponse("partials/queue_table.html", {
461465
"request": request,
@@ -468,6 +472,10 @@ async def partial_queue_table(request: Request):
468472
async def partial_activity_feed(request: Request):
469473
templates = request.app.state.templates
470474
db = request.app.state.database
475+
if not getattr(request.app.state, "first_cycle_done", True):
476+
return HTMLResponse(
477+
'<p><em>Waiting for first cycle to complete\u2026</em></p>'
478+
)
471479
cursor = await db.db.execute(
472480
"SELECT * FROM activity_log ORDER BY timestamp DESC LIMIT 20"
473481
)

0 commit comments

Comments
 (0)