Code Monkey home page Code Monkey logo

pilgaard.backgroundjobs's Introduction

Pilgaard BackgroundJobs Banner

CI Downloads Version

A dotnet library for running background jobs in a scalable and performant manner.

Features

  • Implement background jobs through interfaces
  • Centralized host to manage and run jobs, keeping memory and thread usage low.
  • Dependency Injection support
  • Read and update job schedules at runtime through IConfiguration or IOptionsMonitor
  • Monitoring jobs using logs and metrics, both compatible with OpenTelemetry

Scheduling Methods

  • Cron expressions using ICronJob
  • Recurringly at a set interval using IRecurringJob
  • Recurringly at a set interval after an initial delay using IRecurringJobWithInitialDelay
  • Once at an absolute time using IOneTimeJob

Use Case examples

  • Sending emails
  • Processing data
  • Enforcing data retention

Getting Started

Make BackgroundJobs by implementing one of these interfaces:

public class CronJob : ICronJob
{
    public Task RunJobAsync(CancellationToken cancellationToken = default)
    {
        Console.WriteLine("Time to backup your databases!");

        return Task.CompletedTask;
    }
    public CronExpression CronExpression => CronExpression.Parse("0 3 * * *");
}
public class RecurringJob : IRecurringJob
{
    public Task RunJobAsync(CancellationToken cancellationToken = default)
    {
        Console.WriteLine("This is your hourly reminder to stay hydrated.");

        return Task.CompletedTask;
    }
    public TimeSpan Interval => TimeSpan.FromHours(1);
}
public class RecurringJobWithInitialDelay : IRecurringJobWithInitialDelay
{
    public Task RunJobAsync(CancellationToken cancellationToken = default)
    {
        Console.WriteLine("This is your hourly reminder to stay hydrated.");

        return Task.CompletedTask;
    }
    public TimeSpan Interval => TimeSpan.FromHours(1);
    public TimeSpan InitialDelay => TimeSpan.Zero;
}
public class OneTimeJob : IOneTimeJob
{
    public Task RunJobAsync(CancellationToken cancellationToken = default)
    {
        Console.WriteLine("Happy New Year!");

        return Task.CompletedTask;
    }
    public DateTime ScheduledTimeUtc => new(year: 2023, month: 12, day: 31, hour: 23, minute: 59, second: 59);
}

Registration

Call AddBackgroundJobs() on an IServiceCollection, and then add jobs:

builder.Services.AddBackgroundJobs()
    .AddJob<CronJob>()
    .AddJob<RecurringJob>()
    .AddJob<RecurringJobWithInitialDelay>()
    .AddJob<OneTimeJob>();

You can also register jobs in-line for simple use cases:

builder.Services.AddBackgroundJobs()
    .AddJob(
        name: "basic-cronjob",
        job: () => {},
        cronExpression: CronExpression.Parse("* * * * *"))
    .AddJob(
        name: "basic-recurringjob",
        job: () => {},
        interval: TimeSpan.FromSeconds(3))
    .AddJob(
        name: "basic-recurringjob-withinitialdelay",
        job: () => {},
        interval: TimeSpan.FromSeconds(3),
        initialDelay: TimeSpan.Zero)
    .AddJob(
        name: "basic-onetimejob",
        job: () => {},
        scheduledTimeUtc: DateTime.UtcNow.AddHours(1))
    .AddAsyncJob(
        name: "async-cronjob",
        job: cancellationToken => Task.CompletedTask,
        cronExpression: CronExpression.Parse("* * * * *"))
    .AddAsyncJob(
        name: "async-recurringjob",
        job: cancellationToken => Task.CompletedTask,
        interval: TimeSpan.FromSeconds(3))
    .AddAsyncJob(
        name: "async-recurringjob-withinitialdelay",
        job: cancellationToken => Task.CompletedTask,
        interval: TimeSpan.FromSeconds(3),
        initialDelay: TimeSpan.Zero)
    .AddAsyncJob(
        name: "async-onetimejob",
        job: cancellationToken => Task.CompletedTask,
        scheduledTimeUtc: DateTime.UtcNow.AddHours(1));

Samples

Sample ๐Ÿ”— Tags
BackgroundJobs.Configuration ASP.NET, Reloading, Configuration
BackgroundJobs.MinimalAPI ASP.NET, MinimalAPI
BackgroundJobs.OpenTelemetry ASP.NET, Open Telemetry, Metrics, Logs
BackgroundJobs.WorkerService Console, Worker Service

Open Telemetry Compatibility

Each project exposes histogram metrics, which allow monitoring the duration and count of jobs.

The meter names match the project names.

The Open Telemetry Sample shows how to collect CronJob metrics using the Prometheus Open Telemetry exporter.


Roadmap

  • Replace Assembly Scanning with registration similar to that of HealthChecks
  • A separate UI project to help visualize when jobs trigger
  • Utilize dotnet 8's new TimeProvider instead of DateTime.UtcNow
  • More samples
    • Using Blazor Server
    • Using a Worker Service
    • Using IConfiguration to reload job schedule
    • Using OneTimeJobs to control feature flags
    • Using RecurringJobs to manage data retention

Thanks to

  • The developers of Cronos for their excellent Cron expression library.
  • JetBrains for providing me with a free license to their products, through their Open Source Support program.

pilgaard.backgroundjobs's People

Contributors

dependabot[bot] avatar imgbotapp avatar nielspilgaard avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

vasjen

pilgaard.backgroundjobs's Issues

Plan for dotnet 8

When updating to NET8.0, I have the following updates in mind:

  • Replace usage of DateTime.UtcNow with the equivalents in the new TimeProvider.
  • Add convenience methods for adding cronjobs that run every minute, hour, day, week and month respectively
  • Target frameworks will be netstandard2.0 and net6.0 and net8.0

net8.0 will not be added as a target framework, there's no need to at this time.

RecurringJob scheduling inconsistencies

I've discovered a few major issues with the project Pilgaard.BackgroundJobs, until they are resolved I recommend using Pilgaard.CronJobs, Pilgaard.RecurringJobs or Pilgaard.ScheduledJobs instead

Bugs

  • Only 1 interface-based recurring job can be scheduled per program.
  • The logic that determines when to execute recurring jobs is incorrect, any job with an interval above 30 seconds will never run.

I plan to fix these issues when I begin to update to dotnet 8, starting ~November 2023

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.