Repository navigation
feat(worker): Crawl each storage config as a work item, with scope routing (#281) - #293
Merged
Merged
Conversation
- WorkItems.StorageConfigId, nullable, cascading on config delete, set from the payload's optional IWorkPayload.StorageConfigId. - The claim takes the Worker's served user: a per-user Worker claims unscoped items and items of its user's configs, an all-user Worker claims everything. The executor reads WorkerState.ResolvedUserId at each claim, after WorkerInitializer has resolved it. Contract tests on real PostgreSQL: per-user and all-user claims, a config delete removing its items and fencing the running one, and the scope stored on enqueue. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A periodic kind can now have a varying set of schedules, such as one crawl per served storage config. WorkScheduler asks each IWorkScheduleSource for its schedules at every tick, inside the tick's scope; a fixed WorkSchedule<TPayload> is its own only source, so the token cleanup and retention schedules behave as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- WorkKind.Crawl with CrawlPayload(StorageConfigId): dedup key crawl:<config id>, scoped to its config. - CrawlSchedules: one schedule per active config the Worker serves (its user's configs, or all of them for an all-user Worker), due every Worker:CrawlIntervalHours. The served user is read at each tick. The first crawl after a start comes from due-ness. - CrawlHandler runs today's crawl through FileIngestionPipeline, unchanged in concurrency, exclusions and failure handling. A missing or inactive config is skipped; a missing root fails only that config's item (#282); a shutdown propagates and the item is released. - The pipeline counts items found, processed and failed (a Live Photo pair is one item) under one lock and reports them as progress, with no total until the walk ends. The result is the final counts. - The crawl BackgroundService and its timer are gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d log (#281) Deleting a storage config mid-crawl deletes its running item, so the heartbeat is fenced without any other worker involved. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflict: #36 (#291) added a duplicate report after the crawl loop had crawled every config; this branch removes that loop. Resolved as agreed with the maintainer: each config's Crawl item runs the report for its own config. Within-config copies come from this Worker's tally for that config; pairs are those between it and the same user's other active configs, so a pair across two configs is reported by each of their crawls. The counts go into the crawl's result, and a failed report is logged without failing the crawl. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…281) - The queried config ids are a Union, so their order is pinned by a test instead of being an equivalent Append/Prepend mutant. - A crawl with pairs but no copies within the config is summarised. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Closes #281. Part of #276.
What changes
Crawling is now visible, controllable work: each storage config's crawl is a
Crawlwork item, and the Worker's own crawl timer is gone.Scope routing
WorkItems.StorageConfigId(nullable, cascading on config delete) is set from a new optionalIWorkPayload.StorageConfigId.WORKER__USER) claims unscoped items and items of its user's configs. An all-user Worker claims everything.WorkerState.ResolvedUserId, read at each claim and each scheduler tick and never cached at construction, because hosted services are built beforeWorkerInitializerresolves it.Scheduling
WorkSchedulernow asks eachIWorkScheduleSourcefor its schedules at every tick.WorkSchedule<TPayload>is its own only source, so token cleanup and retention behave as before.CrawlSchedulesreturns onecrawl:<config id>schedule per active config the Worker serves, dueWorker:CrawlIntervalHours(4 h) after the last crawl of that config finished.The crawl
CrawlHandlerruns today's crawl of the config throughFileIngestionPipeline, with unchanged per-file concurrency, exclusions and failure handling.Merge with #36 (decided with the maintainer)
#36 (#291) reported duplicate content once, after the crawl loop had crawled every config. That loop no longer exists, so each
Crawlitem now reports for its own config:The counts go into the crawl's result (
Duplicates), and a failed report is logged without failing the crawl. A pair across two configs is reported by each of their crawls.Deliberately not here
Verification
dotnet test -p:TestSuite=Allafter merging master: 1,475 unit and 35 integration tests, all passing.CrawlSchedulespicks the per-user or all-user configs, with the user resolved after construction;scripts/mutation-changed.shrun over every production file changed before the merge reached 100.00%. The first CI sweep after the merge scored 99.86%, with two survivors in the reworkedSharedContentReporter. Both are killed inca0bb0b: the config ids are aUnion, whose order a test pins, and a crawl with only cross-config pairs is now checked to be summarised.mutation-guard.sh,derive-db-docs.sh --checkanddotnet format --verify-no-changespass.🤖 Generated with Claude Code