jamesmh / coravel

Near-zero config .NET library that makes advanced application features like Task Scheduling, Caching, Queuing, Event Broadcasting, and more a breeze!
https://docs.coravel.net/Installation/
MIT License
3.9k stars 257 forks source link

Run task always at start. #181

Closed m4rcelpl closed 3 years ago

m4rcelpl commented 4 years ago

Hi!

There is lack of option to run task immediately after program starts. I miss this function in my current project and this is very useful while debugging.

scheduler
.Schedule<SomeTask>()
.RunAtStart(configuration.GetValue<bool>("RunAtStart")) 👈
.Daily().PreventOverlapping("065C935A-E049-45CB-95E4-58CB65562B0C")
tolbxela commented 4 years ago

Yes, while testing and debugging I also need something like RunOnce() to fire it quick at start. Now I am helping myself with starting a razor page with this.Queue.QueueInvocable<SomeInvocable>()

BertrandJU commented 4 years ago

@tolbxela @m4rcelpl using a BackgroundService :

using Coravel.Queuing.Interfaces;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MyApp.Services.Jobs
{
    public class StartBackgroundJobsService : BackgroundService
    {
        private readonly IQueue _queue;
        public StartBackgroundJobsService(IQueue queue)
        {
            this._queue = queue ?? throw new ArgumentNullException(nameof(queue));
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            this._queue.QueueInvocable<SomeInvocable>();
        }
    }
}

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHostedService<StartBackgroundJobsService>();
    }
}
tolbxela commented 4 years ago

Good, but too much code for .RunOnce() and the BackgroundService works only starting from ASP.NET Core v.2.1

jamesmh commented 4 years ago

The background service also wouldn't support the "Prevent Overlapping" locking logic too.

pavlekukric commented 3 years ago

Any updates on this? Need for something like StartBackgroundJobsService is an overkill for such a simple thing as RunAtStart()

jamesmh commented 3 years ago

No timeline, but I'll be looking at this next.

jamesmh commented 3 years ago

This is available in 4.0.5 as RunOnceAtStart()

tolbxela commented 3 years ago

👍

jamesmh commented 3 years ago

So 4.0.5 has a bug. See #257.

The issue is my fault and has to do with HostedServices running before the .NET configuration is completed (so hosted service gets it's own lifecycle that may or may not have access to all available services when it starts up - so the "first" run at startup actually runs before the Configuration in .NET is completed 🥴).

Anyways, that's fixed - but will have to release this as a new major version since I needed to upgrade some of the nuget packages it uses in order to hook into the .NET lifecycle tools.

What I'm coming across now is another question I didn't think of: If a task is scheduled, let's say, every hour but only to run on weekends, should the task run at start if it's a weekday?

I can see arguments for both sides of this argument lol.

  1. "RunOnceAtStart" means what it means - run at start no matter what
  2. Well, it doesn't make sense to run the task on a day that it is never supposed to run on.

The easier implementation is no.1 (which is what I currently have working) - curious if those who asked for this have any thoughts or expected behaviors based on this question?

tolbxela commented 3 years ago
  1. "RunOnceAtStart" means what it means - run at start no matter what 👍
carlosrfernandez commented 3 years ago

As @tolbxela I would also go for the most practical and straightforward solution.

RunOnceAtStart just means that...

This is really the most useful tool while developing.

It is also useful for testing after something is deployed. If it only follows the schedule, it might be that it will execute during the weekend at some specific time.

I'd rather it run immediately always.

I think that you could just leave a comment on the method description stating this behavior.

tolbxela commented 3 years ago

Keep it simple!

jamesmh commented 3 years ago

So 4.1.0 should have the fix now 🙂