Abstract submit and poll operations#19688
Conversation
…sks to use this service This service will manage operations that require status to be synced between servers (load balanced setup).
This is both async and returns an attempt, which will fail if a rebuild operation is already running.
…on-background operations. Storing an expiration date allows setting different expiration times depending on the type of operation, and whether it is running in the background or not.
… expiration and deletion in `LongRunningOperationRepository.CleanOperations`.
…rm on why a result could not be retrieved
…ons-in-a-LB-friendly-way # Conflicts: # src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs
…round and stale operations
…ons-in-a-LB-friendly-way
There was a problem hiding this comment.
Pull Request Overview
This PR abstracts long-running operations into a unified service, replacing direct background-queue usage in key services, and adds infrastructure to persist, track, and clean up those operations.
- Introduce
LongRunningOperationServiceand its repository for enqueueing, tracking status, and storing results - Refactor
ContentPublishingServiceandDatabaseCacheRebuilderto use the new service - Add cleanup job, migrations, DI registrations, and comprehensive unit/integration tests
Reviewed Changes
Copilot reviewed 36 out of 36 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/Umbraco.Core/Services/LongRunningOperationService.cs | Core service to enqueue, run, and track long-running operations |
| src/Umbraco.Infrastructure/Persistence/Repositories/Implement/LongRunningOperationRepository.cs | Repository persisting operation metadata, status, and results |
| src/Umbraco.Core/Services/ContentPublishingService.cs | Refactored branch publish to use LongRunningOperationService |
| src/Umbraco.PublishedCache.HybridCache/DatabaseCacheRebuilder.cs | Refactored rebuild logic to use LongRunningOperationService |
| src/Umbraco.Infrastructure/BackgroundJobs/Jobs/LongRunningOperationsCleanupJob.cs | Recurring job deleting stale operations after one day |
| src/Umbraco.Core/DependencyInjection/UmbracoBuilderExtensions.cs | Register the cleanup job in recurring background jobs |
| src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Repositories.cs | Register new ILongRunningOperationRepository |
| src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs | Register ILongRunningOperationService |
| tests/Umbraco.Tests.UnitTests/Umbraco.Core/Services/LongRunningOperationServiceTests.cs | Unit tests for LongRunningOperationService |
| tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/LongRunningOperationRepositoryTests.cs | Integration tests for repository behavior |
Comments suppressed due to low confidence (2)
src/Umbraco.Core/Services/ILongRunningOperationService.cs:20
- The default value for
allowConcurrentExecutionisfalsehere but istruein the implementation; aligning these defaults will prevent surprising behavior when callers omit this argument.
Task<Attempt<Guid, LongRunningOperationEnqueueStatus>> Run(
src/Umbraco.Web.Common/DependencyInjection/UmbracoBuilderExtensions.cs:193
- [nitpick] There's an extra space before this line relative to others in the block; aligning indentation improves readability and consistency.
builder.Services.AddRecurringBackgroundJob<LongRunningOperationsCleanupJob>();
AndyButland
left a comment
There was a problem hiding this comment.
Looks great so far @lauraneto, really impressive. I've tested out the happy paths and they all work as expected. I know you are still working on a few things but will share the points I've found in the code review now.
src/Umbraco.Core/Persistence/Repositories/ILongRunningOperationRepository.cs
Show resolved
Hide resolved
src/Umbraco.Infrastructure/BackgroundJobs/Jobs/LongRunningOperationsCleanupJob.cs
Show resolved
Hide resolved
src/Umbraco.Infrastructure/BackgroundJobs/Jobs/LongRunningOperationsCleanupJob.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: Andy Butland <abutland73@gmail.com>
e2a2bb6 to
f3c41e4
Compare
…ons-in-a-LB-friendly-way
AndyButland
left a comment
There was a problem hiding this comment.
All looks good to me now, and have re-tested to verify the two long running operations continue to work as expected. Approving and let's merge this in.
Description
This pull request introduces a new
LongRunningOperationServiceservice that allows you to run/queue and track long running operations. Also added a repository to keep track of the status, and a few unit and integration tests.Adjusted the
ContentPublishingService.PublishBranchAsync()andDatabaseCacheRebuilder.Rebuild()to use the new service instead of usingIBackgroundTaskQueuedirectly.Added a new background job
LongRunningOperationsCleanupJobthat deletes them after some time (now hardcoded to 1 day).Considerations:
Run()parameterstypeandallowConcurrentExecution.Methods:
Run()- runs or schedules a task/operation.type- type of operation, mostly relevant whenallowMultipleRunsOfTypeis false, but also used to make sure that when an operation is queried the type matches.operation- the task to run (Taskwhen no result,Task<T>when a result is returned, which we need to store).runInBackground- whether to queue the operation in the background, or run it and wait for the result before returning.allowConcurrentExecution- whether you should be able to run or queue an operation when another of the same type is already running, example: database cache rebuild.GetStatus()- gets the status of an operation by id.GetByType()- gets a list of operations by type. Accepts a list of status to use as filter. Defaults to Enqueued or Running.GetResult()- Get the result of an operation.TODOs
Check how to handle- will be done in a separate PRIndexingRebuilderService.TryRebuild