Repository navigation
Conversation
|
@Extrodox is attempting to deploy a commit to the shashankss1205's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Overlaps merged #1071 watcher sync and conflicts with current watcher.py. |
# Conflicts: # src/codegraphcontext/core/watcher.py
main added _update_lock/_timers_lock after this branch was cut (CodeGraphContext#1424, serialising concurrent watcher updates). Tests that build the handler via __new__ must set them, as the neighbouring tests in this file already do.
|
Rebased onto current
Why I have not merged itThe parallel parsing hits an open segfault bug — #1370. That issue reports non-deterministic Your # utils/tree_sitter_manager.py:322
def execute_query(language, query_string, node):
query = Query(language, query_string) # per call, no lock
cursor = QueryCursor(query)
res = cursor.captures(node)
So merging this would move a known crash from What would unblock itEither is fine, and either would be a genuinely valuable PR on its own:
The rest of the PR is good — reusing the already-parsed changed file is a clear win regardless, and if you wanted to split that out as its own PR it would merge immediately. Keeping this open as a draft. |
|
#1370 is now fixed — #1593 merged, adding a process-wide lock around tree-sitter query construction and execution. That was the blocker on this PR. Measured cost of the lock is ~1% (3.48s vs 3.45s median over 120 parses on 8 threads), because only the query step is serialised — One caveat I want to be straight about: I could not reproduce the segfault locally, so #1593 is a guard against the reported crash rather than one I demonstrated. It is not proof your parallelism is now safe — it removes the specific unsynchronised path the report pointed at. Your branch is already rebased onto |
|
This is still marked as a draft, so I've left it alone — flagging that it's now conflict-free against |
Shashankss1205
left a comment
There was a problem hiding this comment.
Verified and merging. This one aged well — it still applies cleanly to main four months later, and the full unit + integration suite is green on it: 1598 passed, 8 skipped (1596 on main plus your two new tests, no regressions).
Three things I checked specifically:
- Reusing
changed_file_datais valid.update_file_in_graphreturnsfile_data,None, or{"deleted": True, ...}, and your guard covers all three. Skipping the redundant re-parse of the file thatupdate_file_in_graphjust parsed is free — that's one whole file's parse removed from every single watcher event, before any parallelism. - Thread safety of
parse_fileis already an established assumption. The main indexing pipeline calls it concurrently viaasyncio.to_threadunder a semaphore (pipeline.py), so aThreadPoolExecutorin the watcher isn't introducing a new requirement — it's matching what indexing already does. - Nondeterministic completion order is pre-existing.
as_completedmeanssubset_file_datafills in arbitrary order, but the main pipeline already collects concurrently-parsed results the same way, andlink_function_callsconsumes the list as a set of facts rather than a sequence.
I also like that failures are contained: parse_affected_file catches per-file, logs, and returns None, so one unparseable neighbour can't take down the whole incremental update.
One follow-up I'll file rather than block on: _incremental_parse_workers() re-implements worker-count resolution that pipeline.py already has as get_parallel_workers() — and lands on different numbers. Yours defaults to 4 and caps at 32; the pipeline's defaults to 10 and doesn't cap. So with PARALLEL_WORKERS unset, indexing uses 10 workers and the watcher uses 4, which will confuse whoever tunes that setting next. Not worth holding a good perf fix for, but the two should converge on one helper.
Thanks for the patience on the review latency — four months is longer than this should have sat.
|
Heads-up: this is still marked as a draft, so I can't merge it — GitHub blocks the merge regardless of approval. I've approved it and verified it independently (details in the review above): it applies cleanly to current Mark it ready for review and I'll merge it immediately. If the draft status was deliberate and there's something you still wanted to change, tell me what and I'll wait — but from here it looks finished. @Extrodox — flagging you directly since this has been sitting for four months and a draft PR doesn't surface in the normal review queue. That's partly on me for not spotting it sooner. |
Shashankss1205
left a comment
There was a problem hiding this comment.
Parallel watcher parsing integrates with #1741 locally; 85 tests pass, one skip. Resolve shared worker method/test conflict as in included supplement, but await contributor ready status and CI.
Summary
update_file_in_graph()instead of parsing the same file again during incremental relinking.ThreadPoolExecutordriven byPARALLEL_WORKERS.Why
Incremental indexing was effectively serial for affected-file parsing, and the changed file could be parsed twice in one update pass. This makes large affected sets slower than necessary even when parsing work is CPU-bound and independent per file.
Validation
PYTHONPATH=src /tmp/cgc-pr-venv/bin/python -m pytest tests/unit/tools/test_graph_builder_perf_fixes.py::TestWatcherIncrementalHandleModification::test_incremental_parse_workers_uses_parallel_workers_config tests/unit/tools/test_graph_builder_perf_fixes.py::TestWatcherIncrementalHandleModification::test_handle_modification_reuses_changed_file_parse_result -qPYTHONPATH=src /tmp/cgc-pr-venv/bin/python -m compileall -q src/codegraphcontext/core/watcher.pyNote: the default Homebrew Python in this shell is externally managed and lacked project dependencies, so validation used a temporary venv under
/tmp/cgc-pr-venv.