Skip to content

GML-2163-UI-GAP: surface rebuild stage in UI during long ECC phases - add progres…#47

Open
prinskumar-tigergraph wants to merge 2 commits into
release_2.0.1from
GML-2163-UI-GAP
Open

GML-2163-UI-GAP: surface rebuild stage in UI during long ECC phases - add progres…#47
prinskumar-tigergraph wants to merge 2 commits into
release_2.0.1from
GML-2163-UI-GAP

Conversation

@prinskumar-tigergraph

@prinskumar-tigergraph prinskumar-tigergraph commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

User description

…s callbacks to embed, extract, summarize_communities; cache last ECC status to fix unknown time on timeout


PR Type

Bug fix, Enhancement


Description

  • Surface long-running rebuild progress

  • Preserve ECC status during timeouts

  • Propagate progress callbacks across phases


Diagram Walkthrough

flowchart LR
  ecc["ECC rebuild phases"]
  callbacks["Progress callbacks"]
  ui["UI rebuild status"]
  cache["Last status cache"]
  timeout["Timeout fallback"]

  ecc -- "emits updates" --> callbacks
  callbacks -- "updates stage text" --> ui
  ui -- "stores running status" --> cache
  timeout -- "uses cached stage" --> ui
Loading

File Walkthrough

Relevant files
Enhancement
graph_rag.py
Add rebuild progress callbacks to GraphRAG phases               

ecc/app/graphrag/graph_rag.py

  • Adds optional progress callbacks to embed.
  • Adds optional progress callbacks to extract.
  • Adds optional progress callbacks to summarize_communities.
  • Passes progress callbacks through rebuild task creation.
+22/-5   
Bug fix
ui.py
Cache ECC rebuild status for timeout fallback                       

graphrag/app/routers/ui.py

  • Adds _last_ecc_status_cache per graph.
  • Caches successful running ECC status responses.
  • Clears cached status on completion or timeout.
  • Returns cached stage data when status polling times out.
+16/-2   

…s callbacks to embed, extract, summarize_communities; cache last ECC status to fix unknown time on timeout
@tg-pr-agent

tg-pr-agent Bot commented Jul 13, 2026

Copy link
Copy Markdown

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Status Loss

The timeout fallback expands the cached ECC response but then unconditionally overwrites status with unknown, which may defeat the goal of preserving the last known status/stage during timeouts. Consider preserving cached status when present and only defaulting to unknown when no cached value exists.

cached = _last_ecc_status_cache.get(graphname, {})
return {
    **cached,
    "graphname": graphname,
    "is_running": True,
    "status": "unknown",
    "error": "ECC is busy processing, status check timed out. Rebuild likely still in progress."
Cache Scope

_last_ecc_status_cache is an in-memory module-level cache populated only by the background monitor. In multi-worker deployments, restarts, or requests routed to a different process, timeout fallback may still return no prior started_at or stage. Validate whether this is sufficient for the UI or whether shared/persistent status storage is needed.

# Cache the last successful ECC status response per graph so the UI
# still sees started_at and stage when ECC is too busy to respond.
_last_ecc_status_cache: dict = {}
Callback Errors

Progress callback exceptions are silently swallowed, which can hide UI update failures and make rebuild progress appear stalled without diagnostics. Consider at least logging callback failures at debug or warning level.

if progress is not None:
    try:
        progress(f"Embedding documents ({n_embed} embedded so far)")
    except Exception:
        pass

Comment on lines +369 to +373
if progress is not None:
try:
progress(f"Embedding documents ({n_embed} embedded so far)")
except Exception:
pass

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: If progress is an async callback, calling it without awaiting will silently skip the UI update and emit an un-awaited coroutine warning. Capture the return value and await it when it is a coroutine; apply the same pattern to the new progress(...) calls in extract and summarize_communities. [possible issue, importance: 6]

Suggested change
if progress is not None:
try:
progress(f"Embedding documents ({n_embed} embedded so far)")
except Exception:
pass
if progress is not None:
try:
result = progress(f"Embedding documents ({n_embed} embedded so far)")
if asyncio.iscoroutine(result):
await result
except Exception:
pass

Comment on lines 2305 to 2306
except Exception as e:
LogWriter.error(f"Error during ECC rebuild monitoring for {graphname}: {e}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: _last_ecc_status_cache is only cleared on normal completion and timeout, so an unexpected monitor failure can leave stale running status for the graph. Clear the cache in finally before releasing the rebuild lock so later timeout fallbacks do not report an old rebuild as active. [possible issue, importance: 7]

New proposed code:
 except Exception as e:
     LogWriter.error(f"Error during ECC rebuild monitoring for {graphname}: {e}")
     import traceback
     LogWriter.error(traceback.format_exc())
 finally:
+    _last_ecc_status_cache.pop(graphname, None)
     # Release lock only after ALL stages complete (or timeout/error)
     release_rebuild_lock(graphname)
     LogWriter.info(f"Released global rebuild lock for {graphname}")

Comment thread graphrag/app/routers/ui.py Outdated
Comment on lines 2359 to 2364
cached = _last_ecc_status_cache.get(graphname, {})
return {
**cached,
"graphname": graphname,
"is_running": True,
"status": "unknown",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: This always overwrites the cached status with "unknown", which can hide the last known rebuild phase from the UI during ECC timeouts. Preserve the cached status when available and only fall back to "unknown" when the cache has no status. [general, importance: 7]

New proposed code:
 cached = _last_ecc_status_cache.get(graphname, {})
 return {
     **cached,
     "graphname": graphname,
     "is_running": True,
-    "status": "unknown",
+    "status": cached.get("status", "unknown"),
     "error": "ECC is busy processing, status check timed out. Rebuild likely still in progress."
 }

@prinskumar-tigergraph prinskumar-tigergraph changed the title fix: surface rebuild stage in UI during long ECC phases - add progres… GML-2163-UI-GAP: surface rebuild stage in UI during long ECC phases - add progres… Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants