-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Load Balancing: Implement distributed background jobs #20397
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Implements distributed (cluster-wide, single-run) background jobs with database-backed coordination so that specific recurring jobs execute only once across all servers in a load-balanced Umbraco environment.
- Introduces IDistributedBackgroundJob and a coordinating DistributedBackgroundJobHostedService with locking and persistence.
- Adds repository/service layer, schema (table + lock), migration, install seed data, and configuration settings (DistributedJobSettings).
- Converts selected former per-server IRecurringBackgroundJob implementations to distributed jobs and registers them accordingly.
Reviewed Changes
Copilot reviewed 32 out of 32 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/Umbraco.JsonSchema/UmbracoCmsSchema.cs | Adds DistributedJobSettings to schema definition. |
| Umbraco.Web.Common/DependencyInjection/UmbracoBuilderExtensions.cs | Replaces previous recurring job registrations with distributed job registrations and hosted service. |
| DistributedJobService.cs | Service implementing coordination logic for claiming and finishing jobs. |
| IDistributedJobService.cs | Interface for distributed job coordination. |
| DistributedJobRepository.cs | Data access for distributed job records (selection, update, finish). |
| IDistributedJobRepository.cs | Repository contract for distributed jobs. |
| DistributedJobDto.cs | NPoco DTO mapping for distributed job table. |
| DistributedBackgroundJobModel.cs | Domain model for distributed jobs. |
| AddDistributedJobs.cs | Migration creating table, lock entry, and seeding jobs on upgrade. |
| UmbracoPlan.cs | Adds migration step for distributed jobs. |
| DatabaseSchemaCreator.cs | Includes DistributedJobDto in install schema creation. |
| DatabaseDataCreator.cs | Seeds initial distributed job data and lock on fresh install. |
| UmbracoBuilder.Services.cs | Registers DistributedJobService. |
| UmbracoBuilder.Repositories.cs | Registers DistributedJobRepository. |
| WebhookLoggingCleanup.cs | Converted to distributed job pattern. |
| WebhookFiring.cs | Converted to distributed job pattern. |
| TemporaryFileCleanupJob.cs | Converted to distributed job pattern. |
| ScheduledPublishingJob.cs | Converted to distributed job pattern. |
| OpenIddictCleanupJob.cs | Converted to distributed job pattern. |
| LongRunningOperationsCleanupJob.cs | Converted to distributed job pattern. |
| LogScrubberJob.cs | Converted to distributed job pattern. |
| HealthCheckNotifierJob.cs | Converted to distributed job pattern, removes dynamic delay logic. |
| ContentVersionCleanupJob.cs | Converted to distributed job pattern. |
| CacheInstructionsPruningJob.cs | Converted to distributed job pattern. |
| IDistributedBackgroundJob.cs | Defines distributed job contract. |
| DistributedBackgroundJobHostedService.cs | Timer-driven executor for distributed jobs. |
| Constants-Locks.cs | Adds DistributedJobs lock constant. |
| Constants-DatabaseSchema.cs | Adds DistributedJob table constant. |
| UmbracoBuilder.Configuration.cs | Registers DistributedJobSettings options. |
| Constants-Configuration.cs | Adds configuration key for distributed jobs. |
| DistributedJobSettings.cs | Adds configurable polling period and startup delay. |
| UmbracoBuilderAuthExtensions.cs | Registers OpenIddictCleanupJob as distributed job. |
src/Umbraco.Infrastructure/Services/Implement/DistributedJobService.cs
Outdated
Show resolved
Hide resolved
src/Umbraco.Infrastructure/Persistence/Repositories/Implement/DistributedJobRepository.cs
Show resolved
Hide resolved
src/Umbraco.Infrastructure/BackgroundJobs/DistributedBackgroundJobHostedService.cs
Outdated
Show resolved
Hide resolved
src/Umbraco.Infrastructure/BackgroundJobs/DistributedBackgroundJobHostedService.cs
Outdated
Show resolved
Hide resolved
src/Umbraco.Infrastructure/BackgroundJobs/DistributedBackgroundJobHostedService.cs
Outdated
Show resolved
Hide resolved
src/Umbraco.Infrastructure/BackgroundJobs/DistributedBackgroundJobHostedService.cs
Outdated
Show resolved
Hide resolved
src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs
Outdated
Show resolved
Hide resolved
src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs
Outdated
Show resolved
Hide resolved
src/Umbraco.Infrastructure/BackgroundJobs/DistributedBackgroundJobHostedService.cs
Show resolved
Hide resolved
…rvice.cs Co-authored-by: Copilot <[email protected]>
…dJobHostedService.cs Co-authored-by: Copilot <[email protected]>
…tor.cs Co-authored-by: Copilot <[email protected]>
…tor.cs Co-authored-by: Copilot <[email protected]>
…dJobHostedService.cs Co-authored-by: Copilot <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks really cool. I have two concerns
One about responsibilities, I've written more about that in the Repository file :D
The other thing that comes to mind is that I see you add the jobs in the database in the data creator, which begs the question, if I, as an implementor, want to add my own job, do I also manually need to create a migration which adds this row the the table? I would ideally like to avoid people having to do this, so can we instead do this automatically on boot? I mention this in the UpdateAllChangedAsync as well
src/Umbraco.Infrastructure/Persistence/Repositories/Implement/DistributedJobRepository.cs
Show resolved
Hide resolved
src/Umbraco.Infrastructure/Persistence/Repositories/Implement/DistributedJobRepository.cs
Outdated
Show resolved
Hide resolved
src/Umbraco.Infrastructure/Persistence/Repositories/Implement/DistributedJobRepository.cs
Outdated
Show resolved
Hide resolved
src/Umbraco.Infrastructure/Persistence/Repositories/Implement/DistributedJobRepository.cs
Outdated
Show resolved
Hide resolved
src/Umbraco.Infrastructure/Services/Implement/DistributedJobService.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: Mole <[email protected]>
nikolajlauridsen
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good now, only have one minor naming nitpick
Notes
Introduces distributed background job support for load-balanced Umbraco environments by implementing database-backed job coordination to ensure certain jobs run only once across all servers.
Problem
Umbraco's RecurringBackgroundJobs currently lack the ability to distinguish between:
In load-balanced scenarios, this causes distributed jobs to execute redundantly on all servers, leading to unnecessary processing and potential conflicts.
Solution
This PR introduces a new IDistributedBackgroundJob abstraction with database-backed coordination:
IDistributedBackgroundJobInterfaceDistributedBackgroundJobsHostedServiceDistributedJobSettingsIDistributedJobServiceTesting
Single server testing
Load-Balanced testing: