-
Notifications
You must be signed in to change notification settings - Fork 0
⚡ Bolt: [성능 개선] 파일 내용을 가져오는 과정의 병렬화 (N+1 API 병목 현상 완화) #684
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
seonghobae
wants to merge
10
commits into
main
from
bolt-parallelize-changed-file-context-13880293840684726726
Closed
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
5b337d4
⚡ Bolt: [성능 개선] 변경된 파일 내용 가져오기 병렬화
seonghobae 2b61175
⚡ Bolt: [성능 개선] 파일 내용을 가져오는 과정의 병렬화 (N+1 API 병목 현상 완화)
seonghobae 1d74a1e
Merge branch 'main' into bolt-parallelize-changed-file-context-138802…
opencode-agent[bot] 735498a
⚡ Bolt: [성능 개선] 파일 내용을 가져오는 과정의 병렬화 (N+1 API 병목 현상 완화)
seonghobae 55a8441
fix(rebase): preserve current uv.lock materialization
seonghobae aae629c
Merge branch 'main' into bolt-parallelize-changed-file-context-138802…
opencode-agent[bot] 0d7381b
Merge main into bolt-parallelize-changed-file-context-138802938406847…
seonghobae d9cd03e
Merge branch 'main' into bolt-parallelize-changed-file-context-138802…
opencode-agent[bot] 7d2e861
test: verify Noema concurrency and redaction contracts
seonghobae b9f1f5f
chore(ci): retrigger current-head review after coverage repair
seonghobae File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| """Focused contracts for changed-file review context concurrency.""" | ||
|
|
||
| from collections.abc import Callable, Iterable, Iterator | ||
| from typing import Any | ||
|
|
||
| from scripts.ci import noema_review_gate as noema | ||
|
|
||
|
|
||
| class RecordingExecutor: | ||
| """Synchronous executor double that records worker and map contracts.""" | ||
|
|
||
| instances: list["RecordingExecutor"] = [] | ||
|
|
||
| def __init__(self, *, max_workers: int) -> None: | ||
| """Record the configured worker limit.""" | ||
| self.max_workers = max_workers | ||
| self.map_inputs: list[tuple[str, ...]] = [] | ||
| self.instances.append(self) | ||
|
|
||
| def __enter__(self) -> "RecordingExecutor": | ||
| """Return the executor double for context-manager use.""" | ||
| return self | ||
|
|
||
| def __exit__(self, *args: object) -> bool: | ||
| """Propagate exceptions raised by the code under test.""" | ||
| return False | ||
|
|
||
| def map( | ||
| self, | ||
| function: Callable[[str], str], | ||
| values: Iterable[str], | ||
| ) -> Iterator[str]: | ||
| """Record ordered inputs and evaluate them synchronously.""" | ||
| ordered_values = tuple(values) | ||
| self.map_inputs.append(ordered_values) | ||
| return map(function, ordered_values) | ||
|
|
||
|
|
||
| def install_recording_executor(monkeypatch: Any) -> None: | ||
| """Install a fresh recording executor double.""" | ||
| RecordingExecutor.instances.clear() | ||
| monkeypatch.setattr(noema.concurrent.futures, "ThreadPoolExecutor", RecordingExecutor) | ||
|
|
||
|
|
||
| def test_single_file_context_does_not_create_executor(monkeypatch: Any) -> None: | ||
| """Keep the one-file fast path strictly serial.""" | ||
| install_recording_executor(monkeypatch) | ||
| monkeypatch.setattr(noema, "fetch_changed_file_paths", lambda repo, number: ["src/only.py"]) | ||
| monkeypatch.setattr(noema, "fetch_head_file_content", lambda repo, path, head_sha: "only content") | ||
|
|
||
| context = noema.changed_file_context("owner/repo", 7, "head") | ||
|
|
||
| assert RecordingExecutor.instances == [] | ||
| assert context == "### src/only.py\nonly content" | ||
|
|
||
|
|
||
| def test_parallel_file_context_uses_bounded_map_and_scrubs_errors(monkeypatch: Any) -> None: | ||
| """Verify bounded parallel mapping, stable order, and error redaction.""" | ||
| install_recording_executor(monkeypatch) | ||
| paths = [f"src/file_{index}.py" for index in range(noema.MAX_CONTEXT_WORKERS + 2)] | ||
| sensitive_value = "".join(("github_", "pat_", "123456789")) | ||
| monkeypatch.setattr(noema, "fetch_changed_file_paths", lambda repo, number: paths) | ||
|
|
||
| def fake_fetch_head_file_content(repo: str, path: str, head_sha: str) -> str: | ||
| """Return deterministic content while exercising error and empty paths.""" | ||
| if path == paths[0]: | ||
| raise RuntimeError(f"API error token {sensitive_value}") | ||
| if path == paths[-1]: | ||
| return "" | ||
| return f"content for {path}" | ||
|
|
||
| monkeypatch.setattr(noema, "fetch_head_file_content", fake_fetch_head_file_content) | ||
|
|
||
| context = noema.changed_file_context("owner/repo", 7, "head") | ||
|
|
||
| assert len(RecordingExecutor.instances) == 1 | ||
| executor = RecordingExecutor.instances[0] | ||
| assert executor.max_workers == min(noema.MAX_CONTEXT_WORKERS, len(paths)) | ||
| assert executor.max_workers <= noema.MAX_CONTEXT_WORKERS | ||
| assert executor.max_workers <= len(paths) | ||
| assert executor.map_inputs == [tuple(paths)] | ||
| assert "Unavailable from head content API: API error token ***" in context | ||
| assert sensitive_value not in context | ||
| assert "No UTF-8 text content available from head content API." in context | ||
|
|
||
| section_positions = [context.index(f"### {path}") for path in paths] | ||
| assert section_positions == sorted(section_positions) | ||
|
|
||
|
|
||
| def test_parallel_file_context_worker_count_tracks_small_batches(monkeypatch: Any) -> None: | ||
| """Limit worker creation to the number of files in a small batch.""" | ||
| install_recording_executor(monkeypatch) | ||
| paths = ["src/first.py", "src/second.py"] | ||
| monkeypatch.setattr(noema, "fetch_changed_file_paths", lambda repo, number: paths) | ||
| monkeypatch.setattr(noema, "fetch_head_file_content", lambda repo, path, head_sha: path) | ||
|
|
||
| noema.changed_file_context("owner/repo", 7, "head") | ||
|
|
||
| executor = RecordingExecutor.instances[0] | ||
| assert executor.max_workers == len(paths) | ||
| assert executor.map_inputs == [tuple(paths)] |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.