Skip to content

Commit 45dacc4

Browse files
committed
fix(data): harden conveyor dedup locks and memory limits
1 parent ae0a192 commit 45dacc4

4 files changed

Lines changed: 100 additions & 32 deletions

File tree

scripts/streaming_conveyor.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ def run_code_half(
121121
dedup_db: Path | None,
122122
dedup_near: bool,
123123
global_symbol_index: Path | None = None,
124+
memory_limit_gb: float = 10.0,
124125
) -> dict:
125126
"""index+route+pack the repo's source via the EXISTING code stage, zstd-max.
126127
@@ -132,7 +133,7 @@ def run_code_half(
132133
"""
133134
info = sr.process_one_repo(
134135
repo, repo_dir, lengths_code, work_root, dedup_db, dedup_near,
135-
global_symbol_index,
136+
global_symbol_index, memory_limit_gb,
136137
)
137138
# zstd-max the per-length code parquet files this repo just wrote.
138139
for L in info.get("lengths", {}):
@@ -163,6 +164,7 @@ def run_commits_half(
163164
dedup_near: bool,
164165
pr_store: Path | None,
165166
repo_list: Path | None,
167+
memory_limit_gb: float = 10.0,
166168
) -> tuple[int, int]:
167169
"""Extract commit records once, fan ranges to the pool. Returns (done, failed).
168170
@@ -204,6 +206,7 @@ def run_commits_half(
204206
process_range, repo, repo_dir, records_jsonl,
205207
start, end, lengths_sorted, repo_work,
206208
dedup_db, dedup_near, pr_store, repo_list,
209+
memory_limit_gb,
207210
)
208211
futures[fut] = (start, end)
209212

@@ -259,6 +262,7 @@ def process_one_repo(
259262
pr_store: Path | None,
260263
repo_list: Path | None,
261264
global_symbol_index: Path | None = None,
265+
memory_limit_gb: float = 10.0,
262266
) -> dict:
263267
"""Run BOTH halves for one already-extracted repo subtree, then delete it.
264268
@@ -281,7 +285,7 @@ def process_one_repo(
281285
try:
282286
cinfo = run_code_half(
283287
repo, repo_dir, lengths_code, work_root, dedup_db, dedup_near,
284-
global_symbol_index,
288+
global_symbol_index, memory_limit_gb,
285289
)
286290
with manifest_lock:
287291
manifest.mark_done(ck, cinfo)
@@ -303,7 +307,7 @@ def process_one_repo(
303307
done, failed = run_commits_half(
304308
repo, repo_dir, repo_work, lengths_commits, range_size,
305309
pool, manifest, manifest_lock, resume, cumulative,
306-
dedup_db, dedup_near, pr_store, repo_list,
310+
dedup_db, dedup_near, pr_store, repo_list, memory_limit_gb,
307311
)
308312
result["commits_done"] = done
309313
result["commits_failed"] = failed
@@ -370,6 +374,9 @@ def parse_args(argv: list[str]) -> argparse.Namespace:
370374
"When set, the CODE half threads it into index_project so "
371375
"unresolved base-lib callees are pulled as bounded depth-1 "
372376
"deps tagged crosslib:<repo>. DEFAULT off (unchanged).")
377+
p.add_argument("--memory-limit-gb", type=float, default=10.0,
378+
help="Per-stage fail-loud RSS limit passed to index/materialize/"
379+
"commit processors (default 10.0).")
373380
return p.parse_args(argv)
374381

375382

@@ -469,7 +476,7 @@ def should_process(repo: str) -> bool:
469476
repo, repo_dir, lengths_code, lengths_commits, args.range_size,
470477
work_root, pool, manifest, manifest_lock, resume, cumulative,
471478
args.keep_temp, dedup_db, dedup_near, pr_store, repo_list,
472-
global_symbol_index,
479+
global_symbol_index, args.memory_limit_gb,
473480
)
474481
processed_repos += 1
475482
if isinstance(res.get("code"), dict):

scripts/streaming_reindex.py

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ def stage_index_source(
293293
dedup_db: Path | None = None,
294294
dedup_near: bool = True,
295295
global_symbol_index: Path | None = None,
296+
memory_limit_gb: float = 10.0,
296297
) -> Path:
297298
"""index_project.py --enriched -> <repo>.enriched.jsonl.
298299
@@ -313,6 +314,7 @@ def stage_index_source(
313314
"--max-tokens", str(TOKENIZE_BUDGET),
314315
"--exclude-dirs", SOURCE_EXTRA_EXCLUDE,
315316
"--tokenizer-path", TOKENIZER_PATH,
317+
"--memory-limit-gb", str(memory_limit_gb),
316318
]
317319
if dedup_db is not None:
318320
cmd += ["--dedup-db", str(dedup_db)]
@@ -336,7 +338,8 @@ def stage_index_commits(repo: str, commit_inputs: Sequence[Path], work: Path,
336338
dedup_db: Path | None = None,
337339
dedup_near: bool = True,
338340
pr_store: Path | None = None,
339-
repo_list: Path | None = None) -> Path:
341+
repo_list: Path | None = None,
342+
memory_limit_gb: float = 10.0) -> Path:
340343
"""process_commits.py -> <repo>.enriched.jsonl (commit edit-signal docs).
341344
342345
A commit is an ATOMIC change-unit: process_commits dedups whole commit DOCS
@@ -352,6 +355,7 @@ def stage_index_commits(repo: str, commit_inputs: Sequence[Path], work: Path,
352355
"--max-tokens", str(TOKENIZE_BUDGET),
353356
"--tokenizer-path", TOKENIZER_PATH,
354357
"--format", "both",
358+
"--memory-limit-gb", str(memory_limit_gb),
355359
]
356360
if dedup_db is not None:
357361
cmd += ["--dedup-db", str(dedup_db)]
@@ -371,7 +375,12 @@ def stage_index_commits(repo: str, commit_inputs: Sequence[Path], work: Path,
371375
return enriched
372376

373377

374-
def stage_materialize(repo: str, enriched: Path, work: Path) -> Path:
378+
def stage_materialize(
379+
repo: str,
380+
enriched: Path,
381+
work: Path,
382+
memory_limit_gb: float = 10.0,
383+
) -> Path:
375384
"""clang_enriched_to_parquet.py -> tokenized enriched parquet (single file)."""
376385
tok = work / f"{repo}.tok.parquet"
377386
run_checked(
@@ -385,6 +394,7 @@ def stage_materialize(repo: str, enriched: Path, work: Path) -> Path:
385394
"--materialize-tokenized-enriched",
386395
"--overflow-policy", "drop",
387396
"--size", _budget_size_label(TOKENIZE_BUDGET),
397+
"--memory-limit-gb", str(memory_limit_gb),
388398
],
389399
log_path=work / f"{repo}.materialize.log",
390400
)
@@ -469,6 +479,7 @@ def process_one_repo(
469479
dedup_db: Path | None = None,
470480
dedup_near: bool = True,
471481
global_symbol_index: Path | None = None,
482+
memory_limit_gb: float = 10.0,
472483
) -> dict:
473484
"""Index a repo, then ROUTE each code doc to exactly ONE length bucket.
474485
@@ -483,9 +494,11 @@ def process_one_repo(
483494
work = work_root / repo
484495
work.mkdir(parents=True, exist_ok=True)
485496
lengths_sorted = sorted(int(x) for x in target_lengths)
486-
enriched = stage_index_source(repo, repo_dir, work, dedup_db, dedup_near,
487-
global_symbol_index)
488-
tok = stage_materialize(repo, enriched, work)
497+
enriched = stage_index_source(
498+
repo, repo_dir, work, dedup_db, dedup_near,
499+
global_symbol_index, memory_limit_gb,
500+
)
501+
tok = stage_materialize(repo, enriched, work, memory_limit_gb)
489502

490503
_bucket_for, route_by_fit = _route_by_fit_impl()
491504
route_dir = work / "routed"
@@ -509,13 +522,15 @@ def process_one_commit_source(
509522
repo_dir: Path | None,
510523
dedup_db: Path | None = None,
511524
dedup_near: bool = True,
525+
memory_limit_gb: float = 10.0,
512526
) -> dict:
513527
work = work_root / key
514528
work.mkdir(parents=True, exist_ok=True)
515529
lengths_sorted = sorted(int(x) for x in target_lengths)
516530
enriched = stage_index_commits(key, commit_inputs, work, repo_root, repo_dir,
517-
dedup_db, dedup_near)
518-
tok = stage_materialize(key, enriched, work)
531+
dedup_db, dedup_near,
532+
memory_limit_gb=memory_limit_gb)
533+
tok = stage_materialize(key, enriched, work, memory_limit_gb)
519534

520535
_bucket_for, route_by_fit = _route_by_fit_impl()
521536
route_dir = work / "routed"
@@ -571,6 +586,9 @@ def parse_args(argv: list[str]) -> argparse.Namespace:
571586
"When set, the CODE stage threads it into index_project so "
572587
"unresolved base-lib callees are pulled in as bounded "
573588
"depth-1 deps tagged crosslib:<repo>. DEFAULT off.")
589+
p.add_argument("--memory-limit-gb", type=float, default=10.0,
590+
help="Per-stage fail-loud RSS limit passed to index/materialize/"
591+
"commit processors (default 10.0).")
574592
return p.parse_args(argv)
575593

576594

@@ -650,7 +668,7 @@ def main(argv: list[str]) -> int:
650668
key, files, target_lengths, work_root,
651669
Path(args.commit_repo_root) if args.commit_repo_root else None,
652670
Path(args.commit_repo_dir) if args.commit_repo_dir else None,
653-
dedup_db, dedup_near,
671+
dedup_db, dedup_near, args.memory_limit_gb,
654672
)
655673
manifest.mark_done(manifest_key, info)
656674
run_report[manifest_key] = info
@@ -681,7 +699,9 @@ def should_process(repo: str) -> bool:
681699
for repo, repo_dir in gen:
682700
try:
683701
info = process_one_repo(repo, repo_dir, target_lengths, work_root,
684-
dedup_db, dedup_near, global_symbol_index)
702+
dedup_db, dedup_near,
703+
global_symbol_index,
704+
args.memory_limit_gb)
685705
manifest.mark_done(repo, info)
686706
run_report[repo] = info
687707
processed += 1

scripts/streaming_reindex_commits.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@ def process_range(
363363
dedup_near: bool = True,
364364
pr_store: Path | None = None,
365365
repo_list: Path | None = None,
366+
memory_limit_gb: float = 10.0,
366367
) -> dict:
367368
"""Full per-range pipeline. RAISES RepoFailure on any failure (no fallback)."""
368369
rkey = range_key(repo, start_idx)
@@ -375,8 +376,9 @@ def process_range(
375376
# process_commits needs the source tree for include resolution.
376377
enriched = stage_index_commits(rkey, [slice_jsonl], rwork, repo_dir, None,
377378
dedup_db, dedup_near,
378-
pr_store=pr_store, repo_list=repo_list)
379-
tok = stage_materialize(rkey, enriched, rwork)
379+
pr_store=pr_store, repo_list=repo_list,
380+
memory_limit_gb=memory_limit_gb)
381+
tok = stage_materialize(rkey, enriched, rwork, memory_limit_gb)
380382

381383
route_dir = rwork / "routed"
382384
routed = route_by_fit(tok, lengths_sorted, route_dir)
@@ -419,6 +421,7 @@ def process_one_repo(
419421
dedup_near: bool = True,
420422
pr_store: Path | None = None,
421423
repo_list: Path | None = None,
424+
memory_limit_gb: float = 10.0,
422425
) -> int:
423426
"""Extract one repo, fan its ranges to the pool, wait for completion.
424427
@@ -461,7 +464,7 @@ def process_one_repo(
461464
fut = pool.submit(
462465
process_range, repo, repo_dir, records_jsonl,
463466
start, end, lengths_sorted, repo_work,
464-
dedup_db, dedup_near, pr_store, repo_list,
467+
dedup_db, dedup_near, pr_store, repo_list, memory_limit_gb,
465468
)
466469
futures[fut] = (start, end)
467470

@@ -537,6 +540,9 @@ def parse_args(argv: list[str]) -> argparse.Namespace:
537540
p.add_argument("--repo-list", default=None,
538541
help="Path to outputs/pr_ingest/repo_list.json (bare-name -> "
539542
"owner/repo map) for resolving the PR-store key.")
543+
p.add_argument("--memory-limit-gb", type=float, default=10.0,
544+
help="Per-stage fail-loud RSS limit passed to process_commits/"
545+
"materializer (default 10.0).")
540546
return p.parse_args(argv)
541547

542548

@@ -636,6 +642,7 @@ def should_process(repo: str) -> bool:
636642
work_root, pool, manifest, manifest_lock, resume,
637643
args.token_budget, cumulative, args.keep_temp,
638644
dedup_db, dedup_near, pr_store, repo_list,
645+
args.memory_limit_gb,
639646
)
640647
ranges_done += done
641648
processed_repos += 1

0 commit comments

Comments
 (0)