Base solution for your next web application
Starts in:
01 DAYS
01 HRS
01 MIN
01 SEC
Open Closed

Help in understanding time when background job runs! #8573


User avatar
0
ajayak created

Hi,

Background job has Timer.Period property which controls when to run the job. But also I have hangfire connected which has its own way of running jobs via CRON expression.

Here is an example:

// At 1:50 of every 7th day
RecurringJob.AddOrUpdate<ShipmentAddressLocationCoordinatesWorker>(job => job.Start(), "50 1 * * 0", TimeZoneInfo.Utc);

inside the ShipmentAddressLocationCoordinatesWorker constuctor:

Timer.Period = 1000 * 60 * 60 * 24 * 7; // 7 Days

The problem is, I have no idea when the job's DoWork function will be executed! I checked the logs and saw that this job never executed. Can someone help me on understanding how to correctly use Timer.Period property? :)


9 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team

    hi

    I think you are talking about Background Worker.

    It has nothing to do with hangfire.

    see https://aspnetboilerplate.com/Pages/Documents/Background-Jobs-And-Workers#background-workers

  • User Avatar
    0
    ajayak created

    Hi @maliming,

    I'm little confused here. Aren't the background jobs handled by hangfire when abp hangfire package is added?

  • User Avatar
    0
    maliming created
    Support Team

    hangfire works for background jobs, but the Timer.Period you mentioned belongs to the background worker. It has nothing to do with hangfire.

  • User Avatar
    0
    ajayak created

    In the example I posted above, can you provide information on when the DoWork function will be executed in ShipmentAddressLocationCoordinatesWorker? :)

    At 1:50 of every 7th day ?

  • User Avatar
    0
    maliming created
    Support Team

    You are calling hangfire's api. RecurringJob has nothing to do with Abp.

  • User Avatar
    0
    BobIngham created

    @ajayak When you use Hangfire it's initialised in your Startup and instantiated in your WebCoreModule, which you probably already know:

    if (WebConsts.HangfireDashboardEnabled)
    {
        //Hangfire(Enable to use Hangfire instead of default job manager)
        services.AddHangfire(config =>
        {
            config.UseSqlServerStorage(_appConfiguration.GetConnectionString("Default"));
            HangfireService.InitializeJobs();
        });
    }
    

    Your HangfireService class triggers jobs using standard CRON scheduling:

    public class HangfireService
    {
        public static void InitializeJobs()
        {
            RecurringJob.AddOrUpdate<UpdateFromDataProvider>(job => job.Execute(0), "30 * * * *");
            return;
        }
    }
    

    Zero's background jobs work a little differently. They are instantiated into your WebHostModule:

    if (IocManager.Resolve<IMultiTenancyConfig>().IsEnabled)
    {
        var workManager = IocManager.Resolve<IBackgroundWorkerManager>();
        workManager.Add(IocManager.Resolve<SubscriptionExpirationCheckWorker>());
        workManager.Add(IocManager.Resolve<SubscriptionExpireEmailNotifierWorker>());
    }
    

    And the timing is declared at the top of the Worker class:

    namespace Nuagecare.MultiTenancy
    {
        public class SubscriptionExpirationCheckWorker : PeriodicBackgroundWorkerBase, ISingletonDependency
        {
            private const int CheckPeriodAsMilliseconds = 1 * 60 * 60 * 1000; //1 hour
    

    Hope that helps. Zero's background workers and Hangfire workers can work, it's not one or the other, it can be both.

  • User Avatar
    0
    ajayak created

    Hi @bobingham,

    Here is my code for job:

    public class ShipmentAddressLocationCoordinatesWorker : PeriodicBackgroundWorkerBase, ISingletonDependency
    {
        public ShipmentAddressLocationCoordinatesWorker(AbpTimer timer) : base(timer)
        {
            Timer.Period = 1000 * 60 * 60 * 24 * 7; // 7 Days
        }
    
        [UnitOfWork]
        protected override void DoWork()
        {
            // My Code
        }
    }
    

    and I initialize this with Hangfire as:

    // At 1:50 of every 7th day
     RecurringJob.AddOrUpdate<ShipmentAddressLocationCoordinatesWorker>(job => job.Start(), "50 1 * * 0", TimeZoneInfo.Utc);
    

    This is also added in ApplicationModule's PostInitialize function

    workManager.Add(IocManager.Resolve<ShipmentAddressLocationCoordinatesWorker>());
    

    Am I doing something wrong here? Having 2 expressions for timer is really confusing. Can it be simplified?

  • User Avatar
    0
    BobIngham created

    Hi @ajayak, If you're happy working with Hangfire then stick with Hangfire only. Invoke Hangfire in your WebCoreModule as above. Place your job in the HangfireService:

    public class HangfireService
    {
        public static void InitializeJobs()
        {
            RecurringJob.AddOrUpdate<ShipmentAddressLocationCoordinatesWorker>(job => job.Execute(0), "50 1 * * 0");
            return;
        }
    }
    

    Then your worker looks something like below. You are trying to run an abp background worker by firing it from Hangfire.

    namespace Nuagecare.Web.Hangfire.Workers
    {
        public class UpdateFromDataProvider : BackgroundJob<int>, ITransientDependency
        {
            public IAbpSession _abpSession;
            private readonly IRepository<Tenant> _tenantRepository;
            private readonly DataProviderAPIProvider _dataProviderAPIProvider;
    
    
            public UpdateFromDataProvider(
                IAbpSession abpSession,
                IRepository<Tenant> tenantRepository,
                DataProviderAPIProvider dataProviderAPIProvider)
            {
                _abpSession = abpSession;
                _tenantRepository = tenantRepository;
                _dataProviderAPIProvider = dataProviderAPIProvider;
            }
    
            [DisableConcurrentExecution(timeoutInSeconds: 10 * 60)]
            [AutomaticRetry(Attempts = 0)]
            public override void Execute(int number)
            {
                var env = AppDomain.CurrentDomain.GetData("HostingEnvironment") as IHostingEnvironment;
                ... code removed for brevity
    

    Hopefully that shuold be a little clearer. Here's how it looks in VS. Probably the guys at Zero will tell me I have everything wrong!!!! This has been up and working in an Azure production site for over a year and never fails.

  • User Avatar
    0
    ajayak created

    Thanks :)