Browse Source

Defer dynamic handler registration and fix outcomes

Move DynamicBackgroundWorkerHandlerRegistry.Register calls to after scheduling to avoid registering handlers when scheduling fails. Adjust Quartz behaviour to return actual outcomes: only unregister when DeleteJob reports deletion and return whether RescheduleJob succeeded. Convert TickerQ RemoveAsync to a non-async Task<bool> (using Task.FromResult) and move its registration similarly. Update test to poll with a timeout (instead of a fixed 500ms delay) to wait for background worker execution.
pull/25066/head
SALİH ÖZKARA 3 weeks ago
parent
commit
b9a265a831
  1. 4
      framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/HangfireBackgroundWorkerManager.cs
  2. 17
      framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerManager.cs
  3. 10
      framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/AbpTickerQBackgroundWorkerManager.cs
  4. 4
      framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/BackgroundWorkerManager.cs
  5. 8
      framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/DynamicBackgroundWorkerManager_Tests.cs

4
framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/HangfireBackgroundWorkerManager.cs

@ -165,8 +165,6 @@ public class HangfireBackgroundWorkerManager : BackgroundWorkerManager, ISinglet
Check.NotNull(schedule, nameof(schedule));
Check.NotNull(handler, nameof(handler));
DynamicBackgroundWorkerHandlerRegistry.Register(workerName, handler);
var cronExpression = schedule.CronExpression;
if (cronExpression.IsNullOrWhiteSpace())
{
@ -204,6 +202,8 @@ public class HangfireBackgroundWorkerManager : BackgroundWorkerManager, ISinglet
});
}
DynamicBackgroundWorkerHandlerRegistry.Register(workerName, handler);
return Task.CompletedTask;
}

17
framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerManager.cs

@ -130,8 +130,6 @@ public class QuartzBackgroundWorkerManager : BackgroundWorkerManager, ISingleton
Check.NotNull(schedule, nameof(schedule));
Check.NotNull(handler, nameof(handler));
DynamicBackgroundWorkerHandlerRegistry.Register(workerName, handler);
if (schedule.Period == null && schedule.CronExpression.IsNullOrWhiteSpace())
{
throw new AbpException($"Both 'Period' and 'CronExpression' are not set for dynamic worker {workerName}. You must set at least one of them.");
@ -170,6 +168,8 @@ public class QuartzBackgroundWorkerManager : BackgroundWorkerManager, ISingleton
{
await Scheduler.ScheduleJob(jobDetail, trigger, cancellationToken);
}
DynamicBackgroundWorkerHandlerRegistry.Register(workerName, handler);
}
public override async Task<bool> RemoveAsync(string workerName, CancellationToken cancellationToken = default)
@ -182,10 +182,13 @@ public class QuartzBackgroundWorkerManager : BackgroundWorkerManager, ISingleton
}
var jobKey = new JobKey($"DynamicWorker:{workerName}");
await Scheduler.DeleteJob(jobKey, cancellationToken);
DynamicBackgroundWorkerHandlerRegistry.Unregister(workerName);
var deleted = await Scheduler.DeleteJob(jobKey, cancellationToken);
if (deleted)
{
DynamicBackgroundWorkerHandlerRegistry.Unregister(workerName);
}
return true;
return deleted;
}
public override async Task<bool> UpdateScheduleAsync(string workerName, DynamicBackgroundWorkerSchedule schedule, CancellationToken cancellationToken = default)
@ -218,8 +221,8 @@ public class QuartzBackgroundWorkerManager : BackgroundWorkerManager, ISingleton
builder.WithInterval(TimeSpan.FromMilliseconds(schedule.Period!.Value)).RepeatForever());
}
await Scheduler.RescheduleJob(triggerKey, triggerBuilder.Build(), cancellationToken);
var result = await Scheduler.RescheduleJob(triggerKey, triggerBuilder.Build(), cancellationToken);
return true;
return result != null;
}
}

10
framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/AbpTickerQBackgroundWorkerManager.cs

@ -105,8 +105,6 @@ public class AbpTickerQBackgroundWorkerManager : BackgroundWorkerManager, ISingl
Check.NotNull(schedule, nameof(schedule));
Check.NotNull(handler, nameof(handler));
DynamicBackgroundWorkerHandlerRegistry.Register(workerName, handler);
var cronExpression = schedule.CronExpression ?? GetCron(schedule.Period ?? DynamicBackgroundWorkerSchedule.DefaultPeriod);
var functionName = $"DynamicWorker:{workerName}";
@ -137,15 +135,17 @@ public class AbpTickerQBackgroundWorkerManager : BackgroundWorkerManager, ISingl
Function = functionName,
Expression = cronExpression
});
DynamicBackgroundWorkerHandlerRegistry.Register(workerName, handler);
}
public override async Task<bool> RemoveAsync(string workerName, CancellationToken cancellationToken = default)
public override Task<bool> RemoveAsync(string workerName, CancellationToken cancellationToken = default)
{
Check.NotNullOrWhiteSpace(workerName, nameof(workerName));
if (!DynamicBackgroundWorkerHandlerRegistry.IsRegistered(workerName))
{
return false;
return Task.FromResult(false);
}
var functionName = $"DynamicWorker:{workerName}";
@ -153,7 +153,7 @@ public class AbpTickerQBackgroundWorkerManager : BackgroundWorkerManager, ISingl
AbpTickerQBackgroundWorkersProvider.BackgroundWorkers.Remove(functionName);
DynamicBackgroundWorkerHandlerRegistry.Unregister(workerName);
return true;
return Task.FromResult(true);
}
public override async Task<bool> UpdateScheduleAsync(string workerName, DynamicBackgroundWorkerSchedule schedule, CancellationToken cancellationToken = default)

4
framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/BackgroundWorkerManager.cs

@ -71,13 +71,13 @@ public class BackgroundWorkerManager : IBackgroundWorkerManager, ISingletonDepen
Check.NotNull(schedule, nameof(schedule));
Check.NotNull(handler, nameof(handler));
DynamicBackgroundWorkerHandlerRegistry.Register(workerName, handler);
if (schedule.Period == null && !string.IsNullOrWhiteSpace(schedule.CronExpression))
{
throw new AbpException("Default background worker manager does not support cron expression without period.");
}
DynamicBackgroundWorkerHandlerRegistry.Register(workerName, handler);
var timer = ServiceProvider.GetRequiredService<AbpAsyncTimer>();
var serviceScopeFactory = ServiceProvider.GetRequiredService<IServiceScopeFactory>();
var worker = new InMemoryDynamicBackgroundWorker(

8
framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/DynamicBackgroundWorkerManager_Tests.cs

@ -121,7 +121,13 @@ public class DynamicBackgroundWorkerManager_Tests : BackgroundJobsTestBase
result.ShouldBeTrue();
_handlerRegistry.IsRegistered(workerName).ShouldBeTrue();
await Task.Delay(500);
var timeout = TimeSpan.FromSeconds(5);
var startTime = DateTime.UtcNow;
while (executionCount == 0 && DateTime.UtcNow - startTime < timeout)
{
await Task.Delay(50);
}
executionCount.ShouldBeGreaterThan(0);
}

Loading…
Cancel
Save