Can you create a schedule jobs solution? #395
Replies: 7 comments
-
Yes it is possible. I used background tasks, which executes commands from Application layer. |
Beta Was this translation helpful? Give feedback.
-
I used Hangfire with Mediatr. it worked great. |
Beta Was this translation helpful? Give feedback.
-
Mind sharing an example? |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
@neman any help ? |
Beta Was this translation helpful? Give feedback.
-
I never implement background job using clean architecture. But I ever implement background job using hangfire. Basically, we just register our action and let hangfire does the job. I'm thinking to create job executor abstraction in application layer, f.e public delegate Task JobAction();
public interface IJobAgent
{
void Queue(JobAction action, JobConfigs configs);
}
public abstract record JobConfigs
{
public static OneTimeJobConfigs OneTime => new();
public static OneTimeJobConfigs Delayed(TimeSpan delay) => new(delay);
public static RecurringJobConfigs Scheduled(string schedule) => new(schedule);
}
public record OneTimeJobConfigs(TimeSpan? Delay = null) : JobConfigs;
public record RecurringJobConfigs(string Schedule) : JobConfigs; And then in infra layer, we can use hangfire like this: public class HangfireJobAgent : IJobAgent
{
public void Queue(JobAction action, JobConfigs configs)
{
switch (configs)
{
case RecurringJobConfigs recurringJob:
RecurringJob.AddOrUpdate(() => action(), recurringJob.CronSchedule);
break;
case OneTimeJobConfigs { Delay: not null } oneTimeJob:
BackgroundJob.Schedule(() => action(), oneTimeJob.Delay.Value);
break;
case OneTimeJobConfigs:
BackgroundJob.Enqueue(() => action());
break;
}
}
}
public static class DependencyInjection
{
public static IServiceCollection AddAgentJob(this IServiceCollection services) => services
// Add Hangfire services.
.AddHangfire(configuration => configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
// choose your job storage options
.UseSQLiteStorage("yourConnectionString"))
// Add the processing server as IHostedService
.AddHangfireServer();
} After that, we can use in request handler as follows: public record MyRequest : IRequest;
public class MyRequestHandler : IRequestHandler<MyRequest>
{
private readonly IJobAgent _jobAgent;
public MyRequestHandler(IJobAgent jobAgent)
{
_jobAgent = jobAgent;
}
public Task<Unit> Handle(MyRequest request, CancellationToken cancellationToken)
{
// register task next hour
_jobAgent.Queue(() => Task.CompletedTask, JobConfigs.Delayed(TimeSpan.FromHours(1)));
return Task.FromResult(Unit.Value);
}
} Note that, I never tried this, please test before using. This's just my idea. |
Beta Was this translation helpful? Give feedback.
-
@fakhrulhilal thx for the example. Had to make following changes to make it work. Method call expressions are not supported with Hangfire
Minor changes to make it work:
Start a job from e.g. a query like so:
|
Beta Was this translation helpful? Give feedback.
-
I need create a schedule jobs. This is possible using the same structure?
Maybe use job worker or any other idea as quartz etc..
Anybody have any idea?
Beta Was this translation helpful? Give feedback.
All reactions