From ce9e47a132222b3c57f55a7ae0273aecc56969c7 Mon Sep 17 00:00:00 2001 From: ahmetfarukulu Date: Tue, 31 Dec 2024 11:22:05 +0300 Subject: [PATCH] docs: add background workers documentation for layered solution and update navigation links --- .../background-workers.md | 63 +++++++++++++++++++ .../layered-web-application/multi-tenancy.md | 4 +- .../background-workers.md | 2 +- 3 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 docs/en/solution-templates/layered-web-application/background-workers.md diff --git a/docs/en/solution-templates/layered-web-application/background-workers.md b/docs/en/solution-templates/layered-web-application/background-workers.md new file mode 100644 index 0000000000..61f766abd5 --- /dev/null +++ b/docs/en/solution-templates/layered-web-application/background-workers.md @@ -0,0 +1,63 @@ +# Layered Solution: Background Workers + +```json +//[doc-nav] +{ + "Previous": { + "Name": "Background Jobs", + "Path": "solution-templates/layered-web-application/background-jobs" + }, + "Next": { + "Name": "Multi-Tenancy", + "Path": "solution-templates/layered-web-application/multi-tenancy" + } +} +``` + +Background workers are long-running processes that operate in the background of your application. They are ideal for non-time-sensitive tasks, such as processing data, sending notifications, or monitoring system health. Typically, background workers start when the application launches and run continuously until the application stops. For more information, refer to the [Background Workers](../../framework/infrastructure/background-workers/index.md) document. + +Basically, you can create scheduled workers to run at specific time intervals based on your requirements. For example, you might create a worker to check the status of inactive users and change their status to passive if they haven't logged in to the application in the last 30 days. + +```csharp +public class PassiveUserCheckerWorker : AsyncPeriodicBackgroundWorkerBase +{ + public PassiveUserCheckerWorker( + AbpAsyncTimer timer, + IServiceScopeFactory serviceScopeFactory) : base( + timer, + serviceScopeFactory) + { + Timer.Period = 600000; //10 minutes + } + + protected async override Task DoWorkAsync( + PeriodicBackgroundWorkerContext workerContext) + { + Logger.LogInformation("Starting: Setting status of inactive users..."); + + // Resolve dependencies + var userRepository = workerContext + .ServiceProvider + .GetRequiredService(); + + // Do the work + await userRepository.UpdateInactiveUserStatusesAsync(); + + Logger.LogInformation("Completed: Setting status of inactive users..."); + } +} +``` + +After creating a worker, we should also register it in the application. We might add it in the *Domain* or *Application* layer. You can register your worker in the `OnApplicationInitializationAsync` method of your module class. + +```csharp +public class BookstoreApplicationModule : AbpModule +{ + public override async Task OnApplicationInitializationAsync(ApplicationInitializationContext context) + { + await context.AddBackgroundWorkerAsync(); + } +} +``` + +> When scaling out your application in a distributed system, it's crucial to consider that the same background workers might run on multiple instances of the same service. This requires careful management of potential side effects. For example, if you're processing messages from a queue, you need to ensure that each message is processed only once. To prevent multiple instances from handling the same message, you can use [distributed locking](../../framework/infrastructure/distributed-locking.md). diff --git a/docs/en/solution-templates/layered-web-application/multi-tenancy.md b/docs/en/solution-templates/layered-web-application/multi-tenancy.md index 53727f1c85..4011535d4d 100644 --- a/docs/en/solution-templates/layered-web-application/multi-tenancy.md +++ b/docs/en/solution-templates/layered-web-application/multi-tenancy.md @@ -4,8 +4,8 @@ //[doc-nav] { "Previous": { - "Name": "Swagger integration", - "Path": "solution-templates/layered-web-application/swagger-integration" + "Name": "Background Workers", + "Path": "solution-templates/layered-web-application/background-workers" }, "Next": { "Name": "BLOB storing", diff --git a/docs/en/solution-templates/single-layer-web-application/background-workers.md b/docs/en/solution-templates/single-layer-web-application/background-workers.md index 6b9a3b3dc1..7075d85879 100644 --- a/docs/en/solution-templates/single-layer-web-application/background-workers.md +++ b/docs/en/solution-templates/single-layer-web-application/background-workers.md @@ -48,7 +48,7 @@ public class PassiveUserCheckerWorker : AsyncPeriodicBackgroundWorkerBase } ``` -After creating a worker, we should also register it in the related microservice or project. You can register your worker in the `OnApplicationInitializationAsync` method of your module class. +After creating a worker, we should also register it in the application. You can register your worker in the `OnApplicationInitializationAsync` method of your module class. ```csharp public class BookstoreModule : AbpModule