Skip to content

Fix Custom Format score syncer not being scheduled accordingly#584

Merged
Flaminel merged 2 commits into
mainfrom
fix_cf_score_sync_trigger
Apr 25, 2026
Merged

Fix Custom Format score syncer not being scheduled accordingly#584
Flaminel merged 2 commits into
mainfrom
fix_cf_score_sync_trigger

Conversation

@Flaminel

@Flaminel Flaminel commented Apr 25, 2026

Copy link
Copy Markdown
Contributor

Summary by Sourcery

Align CustomFormatScoreSyncer scheduling with seeker configuration so it only runs when custom format scores are in use and proactive search is enabled.

Bug Fixes:

  • Ensure CustomFormatScoreSyncer is started or stopped based on both custom format score usage and proactive search state, preventing it from running under incorrect conditions.

Enhancements:

  • Simplify CustomFormatScoreSyncer trigger logic by centralizing its start/stop conditions and removing one-off trigger behavior tied to seeker search toggles.
  • Derive CustomFormatScoreSyncer registration conditions at startup from seeker configuration and instance usage instead of querying within the registration method.

@Flaminel

Copy link
Copy Markdown
Contributor Author

@greptileai review

@Flaminel

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Apr 25, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@greptile-apps

greptile-apps Bot commented Apr 25, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes the CustomFormatScoreSyncer scheduling by adding ProactiveSearchEnabled as a required condition (alongside anyUseCustomFormatScore) for both initial startup registration and dynamic start/stop logic in the controller. It also removes the separate one-shot trigger block for search re-enable events, which is no longer needed under the unified syncerShouldBeRunning / syncerWasRunning comparison.

Confidence Score: 5/5

Safe to merge — changes are logically correct and the only finding is a minor style inconsistency.

Both the startup registration path and the dynamic toggle path now consistently gate on ProactiveSearchEnabled && anyUseCustomFormatScore. All edge cases (either flag toggling independently or simultaneously) are handled correctly. The sole P2 comment is a cosmetic AsNoTracking() omission that doesn't affect correctness.

No files require special attention.

Important Files Changed

Filename Overview
code/backend/Cleanuparr.Api/Features/Seeker/Controllers/SeekerConfigController.cs Reworks syncer start/stop logic to gate on both ProactiveSearchEnabled AND anyUseCustomFormatScore; removes the now-redundant one-shot trigger block for search re-enable events. Logic is correct; minor style note on missing AsNoTracking().
code/backend/Cleanuparr.Api/Jobs/BackgroundJobManager.cs Moves anyUseCustomFormatScore DB query up to InitializeJobsFromConfiguration and passes it as a parameter; adds AsNoTracking() to that query; conditions initial trigger registration on ProactiveSearchEnabled && anyUseCustomFormatScore. Changes are correct and consistent with the controller logic.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[UpdateSeekerConfig called] --> B[Capture previous state\npreviousProactiveSearchEnabled\npreviousAnyUseCustomFormatScore]
    B --> C[Apply request & save changes]
    C --> D[Re-query anyUseCustomFormatScore from DB]
    D --> E{Compute states}
    E --> F[syncerShouldBeRunning =\nanyUseCustomFormatScore &&\nconfig.ProactiveSearchEnabled]
    E --> G[syncerWasRunning =\npreviousAnyUseCustomFormatScore &&\npreviousProactiveSearchEnabled]
    F --> H{syncerShouldBeRunning\n!= syncerWasRunning?}
    G --> H
    H -- Yes + should run --> I[StartJob + TriggerJobOnce\nCustomFormatScoreSyncer]
    H -- Yes + should stop --> J[StopJob\nCustomFormatScoreSyncer]
    H -- No change --> K[No action]

    subgraph Startup [BackgroundJobManager.StartAsync]
        L[Query seekerConfig &\nanyUseCustomFormatScore] --> M{ProactiveSearchEnabled\n&& anyUseCustomFormatScore?}
        M -- Yes --> N[AddTriggersForJob\nCustomFormatScoreSyncer]
        M -- No --> O[Register job without trigger]
    end
Loading

Comments Outside Diff (1)

  1. code/backend/Cleanuparr.Api/Features/Seeker/Controllers/SeekerConfigController.cs, line 151-152 (link)

    P2 Missing AsNoTracking() on post-save query

    The anyUseCustomFormatScore query at line 151 doesn't call AsNoTracking(), unlike the equivalent query in BackgroundJobManager.cs (line 108) which was explicitly made read-only. Since this is a read-only query called immediately after SaveChangesAsync(), adding AsNoTracking() here keeps the approach consistent and avoids unnecessary change-tracking overhead.

Reviews (1): Last reviewed commit: "fixed CF score syncer not being schedule..." | Re-trigger Greptile

@coderabbitai

coderabbitai Bot commented Apr 25, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3bd56304-692b-475d-b196-712581b745e6

📥 Commits

Reviewing files that changed from the base of the PR and between 02a07d4 and 5ef4edd.

📒 Files selected for processing (2)
  • code/backend/Cleanuparr.Api/Features/Seeker/Controllers/SeekerConfigController.cs
  • code/backend/Cleanuparr.Api/Jobs/BackgroundJobManager.cs

📝 Walkthrough

Walkthrough

The changes consolidate the CustomFormatScoreSyncer management logic by introducing a unified state transition based on two combined conditions: anyUseCustomFormatScore and ProactiveSearchEnabled. The controller and background job manager are updated to compute and pass this boolean upfront rather than repeatedly querying the database.

Changes

Cohort / File(s) Summary
CustomFormatScoreSyncer State Management
code/backend/Cleanuparr.Api/Features/Seeker/Controllers/SeekerConfigController.cs
Simplified state transitions: syncer now starts (with immediate trigger) only when both anyUseCustomFormatScore and ProactiveSearchEnabled are true, and stops otherwise. Removed prior separate triggering on search/proactive search re-enablement. Updated logging to reflect consolidated condition handling.
Job Registration & Initialization
code/backend/Cleanuparr.Api/Jobs/BackgroundJobManager.cs
Updated RegisterCustomFormatScoreSyncJob method signature to accept seekerConfig and anyUseCustomFormatScore boolean parameter. InitializeJobsFromConfiguration now computes the boolean upfront from enabled seeker instances and passes it to avoid database queries. Trigger registration now conditional on both ProactiveSearchEnabled and anyUseCustomFormatScore.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 The syncer's state now unified and clean,
One condition rules them all, serene,
No more scattered triggers to manage,
Proactive search and custom format dance—
Simpler logic, cleaner stance! ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive No description was provided by the author, making it impossible to assess relevance to the changeset. Add a pull request description explaining the scheduling issue being fixed and the approach taken in the changes.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: fixing the Custom Format score syncer scheduling logic across the controller and background job manager.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix_cf_score_sync_trigger

Comment @coderabbitai help to get the list of available commands and usage tips.

@Flaminel

Copy link
Copy Markdown
Contributor Author

@sourcery-ai review

@sourcery-ai

sourcery-ai Bot commented Apr 25, 2026

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Aligns the CustomFormatScoreSyncer job scheduling with both instance-level UseCustomFormatScore and global ProactiveSearchEnabled flags, and centralizes its registration logic to use configuration-derived state instead of re-querying.

Sequence diagram for CustomFormatScoreSyncer scheduling on seeker config update

sequenceDiagram
    actor AdminUser
    participant SeekerConfigController
    participant JobManagementService
    participant Logger

    AdminUser->>SeekerConfigController: UpdateSeekerConfig(newConfig)
    activate SeekerConfigController
    SeekerConfigController->>SeekerConfigController: Load previousAnyUseCustomFormatScore
    SeekerConfigController->>SeekerConfigController: Load previousProactiveSearchEnabled
    SeekerConfigController->>SeekerConfigController: Compute anyUseCustomFormatScore

    SeekerConfigController->>SeekerConfigController: syncerShouldBeRunning = anyUseCustomFormatScore && newConfig.ProactiveSearchEnabled
    SeekerConfigController->>SeekerConfigController: syncerWasRunning = previousAnyUseCustomFormatScore && previousProactiveSearchEnabled

    alt syncerShouldBeRunning != syncerWasRunning
        alt syncerShouldBeRunning
            SeekerConfigController->>Logger: LogInformation(CustomFormatScoreSyncer conditions met, starting job)
            SeekerConfigController->>JobManagementService: StartJob(CustomFormatScoreSyncer, null, CustomFormatScoreSyncerCron)
            SeekerConfigController->>JobManagementService: TriggerJobOnce(CustomFormatScoreSyncer)
        else syncerShouldBeRunning is false
            SeekerConfigController->>Logger: LogInformation(CustomFormatScoreSyncer conditions no longer met, stopping job)
            SeekerConfigController->>JobManagementService: StopJob(CustomFormatScoreSyncer)
        end
    else no change in scheduling conditions
        SeekerConfigController->>SeekerConfigController: Do not modify CustomFormatScoreSyncer scheduling
    end

    SeekerConfigController-->>AdminUser: Ok(seeker configuration updated)
    deactivate SeekerConfigController
Loading

Updated class diagram for BackgroundJobManager and SeekerConfigController scheduling logic

classDiagram
    class SeekerConfigController {
        - ILogger logger
        - IJobManagementService jobManagementService
        + Task UpdateSeekerConfig(UpdateSeekerConfigRequest config)
    }

    class BackgroundJobManager {
        - IJobManagementService jobManagementService
        - DataContext dataContext
        + Task InitializeJobsFromConfiguration(CancellationToken cancellationToken)
        + Task RegisterQueueCleanerJob(QueueCleanerConfig config, CancellationToken cancellationToken)
        + Task RegisterArrConfigJob(ArrConfig config, CancellationToken cancellationToken)
        + Task RegisterDownloadCleanerJob(DownloadCleanerConfig config, CancellationToken cancellationToken)
        + Task RegisterBlacklistSyncJob(BlacklistSyncConfig config, CancellationToken cancellationToken)
        + Task RegisterSeekerJob(SeekerConfig config, CancellationToken cancellationToken)
        + Task RegisterCustomFormatScoreSyncJob(SeekerConfig seekerConfig, bool anyUseCustomFormatScore, CancellationToken cancellationToken)
        + Task AddJobWithoutTrigger~CustomFormatScoreSyncer~(CancellationToken cancellationToken)
        + Task AddTriggersForJob~CustomFormatScoreSyncer~(string cronExpression, CancellationToken cancellationToken)
    }

    class SeekerConfig {
        + bool ProactiveSearchEnabled
        + bool SearchEnabled
    }

    class SeekerInstanceConfig {
        + bool Enabled
        + bool UseCustomFormatScore
    }

    class ArrInstance {
        + bool Enabled
    }

    class IJobManagementService {
        + Task StartJob(JobType jobType, object state, string cronExpression)
        + Task StopJob(JobType jobType)
        + Task TriggerJobOnce(JobType jobType)
    }

    class DataContext {
        + DbSet~SeekerConfig~ SeekerConfigs
        + DbSet~SeekerInstanceConfig~ SeekerInstanceConfigs
    }

    class Logger {
        + void LogInformation(string message)
    }

    SeekerConfigController --> IJobManagementService : uses
    SeekerConfigController --> Logger : logs to
    BackgroundJobManager --> IJobManagementService : manages jobs via
    BackgroundJobManager --> DataContext : reads configuration from
    SeekerInstanceConfig --> ArrInstance : has ArrInstance
    DataContext --> SeekerConfig : stores
    DataContext --> SeekerInstanceConfig : stores
    BackgroundJobManager --> SeekerConfig : reads
    SeekerConfigController --> SeekerConfig : evaluates flags
Loading

Flow diagram for CustomFormatScoreSyncer registration in BackgroundJobManager

flowchart TD
    A[InitializeJobsFromConfiguration] --> B[Load SeekerConfig from DataContext]
    B --> C[Query anyUseCustomFormatScore from SeekerInstanceConfigs]
    C --> D[RegisterQueueCleanerJob]
    D --> E[RegisterArrConfigJob]
    E --> F[RegisterDownloadCleanerJob]
    F --> G[RegisterBlacklistSyncJob]
    G --> H[RegisterSeekerJob]
    H --> I[RegisterCustomFormatScoreSyncJob seekerConfig and anyUseCustomFormatScore]

    subgraph RegisterCustomFormatScoreSyncJob
        I --> J[AddJobWithoutTrigger CustomFormatScoreSyncer]
        J --> K{seekerConfig.ProactiveSearchEnabled && anyUseCustomFormatScore}
        K -- true --> L[AddTriggersForJob CustomFormatScoreSyncer with CustomFormatScoreSyncerCron]
        K -- false --> M[Do not add triggers]
    end
Loading

File-Level Changes

Change Details Files
Update Seeker configuration controller to start/stop the CustomFormatScoreSyncer job based on combined UseCustomFormatScore and ProactiveSearchEnabled conditions.
  • Compute syncerShouldBeRunning from anyUseCustomFormatScore and config.ProactiveSearchEnabled and syncerWasRunning from previousAnyUseCustomFormatScore and previousProactiveSearchEnabled.
  • Change the condition to start/stop the CustomFormatScoreSyncer job to compare syncerShouldBeRunning vs syncerWasRunning.
  • Update log messages to reference generic "conditions met" / "conditions no longer met" instead of only UseCustomFormatScore.
  • Remove logic that triggered CustomFormatScoreSyncer once when search or proactive search was re-enabled with custom format scores active.
code/backend/Cleanuparr.Api/Features/Seeker/Controllers/SeekerConfigController.cs
Adjust background job initialization to decide CustomFormatScoreSyncer triggers using seeker configuration and precomputed instance state.
  • Precompute anyUseCustomFormatScore in InitializeJobsFromConfiguration by querying SeekerInstanceConfigs with enabled instances that use custom format scores.
  • Change RegisterCustomFormatScoreSyncJob signature to take SeekerConfig and anyUseCustomFormatScore instead of DataContext.
  • Within RegisterCustomFormatScoreSyncJob, remove the internal query for anyUseCustomFormatScore and rely on the passed-in flag.
  • Gate adding triggers for CustomFormatScoreSyncer on both seekerConfig.ProactiveSearchEnabled and anyUseCustomFormatScore.
code/backend/Cleanuparr.Api/Jobs/BackgroundJobManager.cs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • The condition for when the CustomFormatScoreSyncer should run (anyUseCustomFormatScore && ProactiveSearchEnabled) is now duplicated between the controller and BackgroundJobManager; consider extracting this into a shared helper/service method to keep the behavior consistent over time.
  • In InitializeJobsFromConfiguration, you now perform two separate queries for SeekerConfig and anyUseCustomFormatScore; consider combining these (e.g., via a projection or navigation property) to avoid an extra DB round-trip on startup.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The condition for when the CustomFormatScoreSyncer should run (`anyUseCustomFormatScore && ProactiveSearchEnabled`) is now duplicated between the controller and `BackgroundJobManager`; consider extracting this into a shared helper/service method to keep the behavior consistent over time.
- In `InitializeJobsFromConfiguration`, you now perform two separate queries for `SeekerConfig` and `anyUseCustomFormatScore`; consider combining these (e.g., via a projection or navigation property) to avoid an extra DB round-trip on startup.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@codecov

codecov Bot commented Apr 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 54.54545% with 5 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ackend/Cleanuparr.Api/Jobs/BackgroundJobManager.cs 0.00% 5 Missing ⚠️

📢 Thoughts on this report? Let us know!

@Flaminel Flaminel merged commit 5d400ad into main Apr 25, 2026
13 checks passed
@Flaminel Flaminel deleted the fix_cf_score_sync_trigger branch April 25, 2026 20:57
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