Skip to content

Background tasks

Simon Yohannes edited this page Feb 2, 2020 · 6 revisions

puck has a tasks api which is pretty simple to use.

to define a task, you create a class that inherits from puck.core.Base.BaseTask:

public class CustomTask:BaseTask
{
    public string CustomProperty { get; set; }
    public override void Run(CancellationToken t)
    {
          //handle background task here  
    }        
}

you can define properties and a Run method to handle your background task. since it inherits from BaseTask, it will inherit the following properties:

    public string Name { get; set; }
    public bool Recurring { get; set; }
    public int IntervalSeconds { get; set; }
    public DateTime RunOn { get; set; }

you can then create an instance of your task and enter in the property values by visiting the Developer section of puck and clicking on the Tasks tab.

if your task is recurring, you can set Recurring to true, IntervalSeconds to something like 60 and RunOn to be something like the current date and time to have your task run every 60 seconds starting from now.

if your task is not Recurring, it doesn't matter what the IntervalSeconds value is, just set RunOn to be a date and time in the future when you want your one off task to run.

it's sensible to add a warning about background tasks. background tasks aren't entirely safe in asp.net environment and you have the CancellationToken passed in to your Run method to let you know if the site is shutting down. don't have tasks fired too frequently or have them run too long, it will be to the detriment of your site performance.

the Dispatcher will not allow a task instance to run again before it has completed so even if the interval is small and the task is long, you won't have the tasks pile up. the timer interval of the Dispatcher is 2 seconds so that's the minimum interval you can have for your tasks.

Load balancing considerations and using ServiceProvider to get dependencies

if you're running Puck in a load balanced environment, you may for example only want to run your task on the single instance EditServer and not on all of the front end servers. here's how you would do that:

public override async Task Run(CancellationToken t)
{
     if (ServiceProvider.GetService<IConfiguration>().GetValue<bool>("IsEditServer")) {
          //handle task here
     }
}

in the code above, the Run method uses the BaseTask property ServiceProvider (which your custom task will inherit), to get the IConfiguration dependency and checks if the current instance is the EditServer. dependency injection isn't supported in Puck's background tasks so you can use the ServiceProvider to get your dependencies.