Skip to content

fix(worker): One storage config with a missing root no longer stops the Worker (#282) - #284

Merged
bitbiter-dev merged 2 commits into
masterfrom
fix/282-crawl-config-failure
Oct 18, 2026
Merged

bitbiter-dev merged 2 commits into
masterfrom
fix/282-crawl-config-failure

Conversation

@bitbiter-dev

Copy link
Copy Markdown
Owner

Closes #282.

Summary

One storage config whose root is missing or unreadable no longer stops the whole Worker. A failed crawl is logged with the config's root path and user, and the loop moves on to the next config.

 Worker.CrawlAllAsync
   for each active config
     CrawlAsync(config)
-      ingestionPipeline.RunAsync(config)        # root missing → throws → BackgroundService faults → StopHost
+      try ingestionPipeline.RunAsync(config)
+      catch when not a shutdown (IngestionShutdown.IsInProgress)
+        Log.CrawlFailed(rootPath, userId, ex)   # Error; next config runs
  • A shutdown in the middle of a crawl still propagates and is not logged as a failure.
  • FileIngestionPipeline still throws for a missing root. Only the per-config loop catches it.
  • CLAUDE.md now says a missing root fails that config's crawl, not the process.
  • The IngestionShutdown comment names its third caller.

Loading the config list itself (the database being unreachable, for example) can still stop the host. That is outside #282 and is noted on #281, which replaces this loop with the work queue.

Evidence

  • Before: CrawlAllAsync_ConfigCrawlFails_LogsItsRootAndCrawlsTheNextConfigAsync failed, because the exception escaped and the second config was never crawled.
    After: it passes, together with:
    • ExecuteAsync_CrawlFails_KeepsRunningAndCrawlsAgainAfterTheIntervalAsync: crawl fails → timer re-armed → crawl again after 3 h, and the Worker is still running;
    • CrawlAllAsync_ShutdownDuringACrawl_StopsWithoutLoggingAFailureAsync: throws OperationCanceledException, no next config, no error log;
    • CrawlAllAsync_CancellationWithoutShutdown_IsLoggedAsACrawlFailureAsync.
  • All test projects pass, and dotnet format --verify-no-changes is clean.
  • scripts/mutation-changed.sh: 100.00% (5 killed, 0 survived).

Merge Danger

Door: two-way

Blast Radius: Worker crawl loop

A crawl error that used to crash the Worker is now logged at Error level and retried on the next interval. An operator who relied on the container restarting to notice a missing mount now has to watch the Worker logs for the error.

🤖 Generated with Claude Code

bitbiter-dev and others added 2 commits October 18, 2026 21:18
…he Worker (#282)

Worker.CrawlAllAsync now logs a failed crawl of one storage config, naming
its root and user, and moves on to the next config. Before, the exception
faulted the crawl BackgroundService, the default StopHost shut down the
whole Worker, and restart: unless-stopped turned that into a crash loop
that also blocked every other user's crawl in all-user mode.

A shutdown mid-crawl still propagates (IngestionShutdown.IsInProgress)
and is not logged as a failure. FileIngestionPipeline still throws for a
missing root; only the per-config loop catches it. The work queue (#281)
replaces this loop later.

Closes #282.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The crawl failure message no longer claims a next config exists, the
IngestionShutdown comment names its third caller, and the cancellation
test checks the logged exception's type.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bitbiter-dev
bitbiter-dev merged commit 66a5b2d into master Oct 18, 2026
11 checks passed
@bitbiter-dev
bitbiter-dev deleted the fix/282-crawl-config-failure branch October 18, 2026 08:43
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.

fix(worker): One storage config with a missing root stops the whole Worker

1 participant