Skip to content

perf(importer): improve import pipeline throughput with 6 targeted optimizations - #345

Merged
javi11 merged 1 commit into
mainfrom
feat/import-speed-improvements
Feb 26, 2026
Merged

perf(importer): improve import pipeline throughput with 6 targeted optimizations#345
javi11 merged 1 commit into
mainfrom
feat/import-speed-improvements

Conversation

@javi11

@javi11 javi11 commented Feb 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Parallel multifile validation: replaced sequential file loop with a bounded goroutine pool (sourcegraph/conc, maxConcurrentFileValidations=4) — near-linear speedup on multi-file NZBs (expected 2-4x for typical 100-file archives)
  • Single-pass segment validation: exported SelectSegmentsForValidation + ValidateSegmentList from internal/usenet/validation.go; validation/segments.go now shares a single iteration for size accumulation and availability checking, eliminating the redundant first pass
  • Category-path memoization: sync.Map cache on Service avoids repeated string operations in calculateProcessVirtualDir on every import; invalidateCategoryCache() available for future config-change hooks
  • Lazy progress tracker allocation: broadcaster.HasSubscribers() guards CreateTracker calls in the RAR/7zip processors; Tracker.Update has a nil-receiver guard so passing a nil *Tracker is safe
  • Serialized queue claims: single sync.Mutex in queue.Manager.processNextItem serialises DB claim transactions, eliminating SQLite lock-contention retries and their exponential backoff delays
  • Scanner depth limit: DirectoryScanner defaults to maxScanDepth=10 (configurable via SetMaxScanDepth) to prevent runaway traversal of deep or cyclically-linked directory trees

Test plan

  • make — full build (Go backend + frontend, all checks)
  • go test ./internal/importer/... — no regressions in importer package
  • go test ./internal/usenet/... — segment validation tests pass with refactored helpers
  • go test ./internal/progress/... — nil-safe tracker and HasSubscribers tests pass
  • Manual: import a 100+ file NZB and compare wall time vs main branch
  • Manual: start 4 workers, add 10 items, confirm no "retrying claim" log lines
  • Manual: scan a deeply nested directory (>10 levels) and verify it stops at depth 10

🤖 Generated with Claude Code

…timizations

- Parallel file validation in multifile processor using bounded goroutine pool
  (sourcegraph/conc, maxConcurrentFileValidations=4) for near-linear speedup on
  multi-file NZBs
- Merge segment validation passes: export SelectSegmentsForValidation +
  ValidateSegmentList so validation/segments.go can skip the redundant size-
  accumulation loop and share a single iteration with availability checking
- Cache virtual directory category-path resolution with sync.Map to eliminate
  repeated string allocations on every import (invalidateCategoryCache provided
  for future config-change hooks)
- Lazy progress tracker creation: guard CreateTracker calls behind
  broadcaster.HasSubscribers() to avoid allocations when no SSE client is
  connected; nil-safe Tracker.Update prevents panics when tracker is nil
- Serialize queue claim transactions with a sync.Mutex so workers never contend
  on SQLite, eliminating exponential-backoff retries under high concurrency
- Limit directory scanner depth to defaultMaxScanDepth=10 (configurable via
  SetMaxScanDepth) to prevent runaway traversal of deep or symlinked trees

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@javi11
javi11 merged commit 99161b2 into main Feb 26, 2026
1 check passed
@javi11
javi11 deleted the feat/import-speed-improvements branch February 26, 2026 14:08
yoshitaka420 pushed a commit to yoshitaka420/altmount that referenced this pull request Jun 1, 2026
…timizations (kipsilabs#345)

- Parallel file validation in multifile processor using bounded goroutine pool
  (sourcegraph/conc, maxConcurrentFileValidations=4) for near-linear speedup on
  multi-file NZBs
- Merge segment validation passes: export SelectSegmentsForValidation +
  ValidateSegmentList so validation/segments.go can skip the redundant size-
  accumulation loop and share a single iteration with availability checking
- Cache virtual directory category-path resolution with sync.Map to eliminate
  repeated string allocations on every import (invalidateCategoryCache provided
  for future config-change hooks)
- Lazy progress tracker creation: guard CreateTracker calls behind
  broadcaster.HasSubscribers() to avoid allocations when no SSE client is
  connected; nil-safe Tracker.Update prevents panics when tracker is nil
- Serialize queue claim transactions with a sync.Mutex so workers never contend
  on SQLite, eliminating exponential-backoff retries under high concurrency
- Limit directory scanner depth to defaultMaxScanDepth=10 (configurable via
  SetMaxScanDepth) to prevent runaway traversal of deep or symlinked trees

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

1 participant