Giter Club home page Giter Club logo

cronscheduler.aspnetcore's Introduction

CronScheduler.AspNetCore

Build status NuGet MyGet

The goal of this library was to design a simple Cron Scheduling engine that is based on build-in Asp.Net Core IHostedService interface. It is much lighter than Quartz schedular and operates inside of any .NET Core GenericHost thus makes it simpler to setup and configure. In addition IStartupJob was added to support async initialization before the IWebHost is ready to start. Sample project includes support for making sure that Database is created before the application starts.

.NET CLI

    dotnet add package CronScheduler.AspNetCore --version 1.1.2

Uses Crontab format for Jobs/Tasks schedules

This library supports up to 5 seconds job intervals in the Crontab format thank to HangfireIO/Cronos library.

You can use https://crontab-generator.org/ to generated needed job/task schedule.

Cron expression is a mask to define fixed times, dates and intervals. The mask consists of second (optional), minute, hour, day-of-month, month and day-of-week fields. All of the fields allow you to specify multiple values, and any given date/time will satisfy the specified Cron expression, if all the fields contain a matching value.

                                       Allowed values    Allowed special characters   Comment

┌───────────── second (optional)       0-59              * , - /                      
│ ┌───────────── minute                0-59              * , - /                      
│ │ ┌───────────── hour                0-23              * , - /                      
│ │ │ ┌───────────── day of month      1-31              * , - / L W ?                
│ │ │ │ ┌───────────── month           1-12 or JAN-DEC   * , - /                      
│ │ │ │ │ ┌───────────── day of week   0-6  or SUN-SAT   * , - / # L ?                Both 0 and 7 means SUN
│ │ │ │ │ │
* * * * * *

Examples

CronSchedulerWorker

This example demonstrates how to use CronScheduler with new Microsoft .NET Core Workers Template CronSchedulerWorker

CronSchedulerApp

The sample website provides with use-case scenario for this library.

Singleton dependencies for ScheduledJob

    public class TorahQuoteJob : ScheduledJob
    {
        private readonly TorahQuoteJobOptions _options;
        private readonly TorahVerses _torahVerses;
        private readonly TorahService _service;

        /// <summary>
        /// Initializes a new instance of the <see cref="TorahQuoteJob"/> class.
        /// </summary>
        /// <param name="options"></param>
        /// <param name="service"></param>
        /// <param name="torahVerses"></param>
        public TorahQuoteJob(
            IOptionsMonitor<TorahQuoteJobOptions> options,
            TorahService service,
            TorahVerses torahVerses) : base(options.CurrentValue)
        {
            _options = options.CurrentValue;
            _service = service ?? throw new ArgumentNullException(nameof(service));
            _torahVerses = torahVerses ?? throw new ArgumentNullException(nameof(torahVerses));
        }

        public override async Task ExecuteAsync(CancellationToken cancellationToken)
        {
            var index = new Random().Next(_options.Verses.Length);
            var exp = _options.Verses[index];

            _torahVerses.Current = await _service.GetVersesAsync(exp, cancellationToken);
        }
    }

Then register this service within the Startup.cs

    services.AddScheduler(builder =>
    {
        builder.Services.AddSingleton<TorahVerses>();

        // Build a policy that will handle exceptions, 408s, and 500s from the remote server
        builder.Services.AddHttpClient<TorahService>()
            .AddTransientHttpErrorPolicy(p => p.RetryAsync());
        builder.AddJob<TorahQuoteJob, TorahQuoteJobOptions>();

        builder.UnobservedTaskExceptionHandler = UnobservedHandler;
    });

Scoped or Transient Dependencies for ScheduledJob

    public class UserJob : ScheduledJob
    {
        private readonly UserJobOptions _options;
        private readonly IServiceProvider _provider;

        public UserJob(
            IServiceProvider provider,
            IOptionsMonitor<UserJobOptions> options) : base(options.CurrentValue)
        {
            _options = options.CurrentValue;
            _provider = provider ?? throw new ArgumentNullException(nameof(provider));
        }

        public override async Task ExecuteAsync(CancellationToken cancellationToken)
        {
            using (var scope = _provider.CreateScope())
            {
                var userService = scope.ServiceProvider.GetRequiredService<UserService>();

                var users = userService.GetUsers();

                foreach (var user in users)
                {
                    await userService.AddClaimAsync(user, new Claim(_options.ClaimName, DateTime.UtcNow.ToString()));
                }
            }
        }
    }

Then register this service within the Startup.cs

        services.AddScheduler(builder =>
        {
            builder.Services.AddScoped<UserService>();
            builder.AddJob<UserJob, UserJobOptions>();

            builder.UnobservedTaskExceptionHandler = UnobservedHandler;
        });
  • Sample uses Microsoft.Extensions.Http.Polly extension library to make http calls every 10 seconds.

IStartupJobs to assist with async jobs initialization before the application starts

There are many case scenarios to use StartupJobs for the IWebHost interface or IGenericHost. Most common case scenario is to make sure that database is created and updated. This library makes it possible by simply doing the following:

  • In the Program.cs file add the following:
        public static async Task Main(string[] args)
        {
            var host = CreateWebHostBuilder(args).Build();

            // process any async jobs required to get the site up and running
            await host.RunStartupJobsAync();

            host.Run();
        }
  • Register the startup job in Program.cs or in Startup.cs file.
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
    return WebHost.CreateDefaultBuilder(args)
            .ConfigureServices(services =>
            {
                services.AddStartupJob<SeedDatabaseJob>();
            })
            .ConfigureLogging((context, logger) =>
            {
                logger.AddConsole();
                logger.AddDebug();
                logger.AddConfiguration(context.Configuration.GetSection("Logging"));
            })
            .UseStartup<Startup>();
}

Background Queues

In some instances of the application the need for queuing of the tasks is required. In order to enable this add the following in Startup.cs.

    services.AddBackgroundQueuedService();

Then add sample async task to be executed by the Queued Hosted Service.

    public class MyService
    {
        private readonly IBackgroundTaskQueue _taskQueue;

        public MyService(IBackgroundTaskQueue taskQueue)
        {
            _taskQueue = taskQueue;
        }

        public void RunTask()
        {
            _taskQueue.QueueBackgroundWorkItem(async (token)=>
            {
                // run some task
                await Task.Delay(TimeSpan.FromSeconds(10), token);
            }});
        }
    }

Special Thanks to

Docker build

Utilizes King David Consulting LLC DotNet Docker Image

    docker-compose -f "docker-compose.yml" -f "docker-compose.override.yml" up -d --build

Note

Workaround for Retrying 'FindPackagesByIdAsync' for source in Docker containers restore.

 dotnet restore --disable-parallel

License

MIT License Copyright (c) 2017 King David Consulting LLC

cronscheduler.aspnetcore's People

Contributors

kdcllc avatar tomkerkhove avatar

Watchers

 avatar

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.