GithubHelp home page GithubHelp logo

xiangyan99 / fluentscheduler Goto Github PK

View Code? Open in Web Editor NEW

This project forked from fluentscheduler/fluentscheduler

0.0 2.0 0.0 1.49 MB

Automated job scheduler with fluent interface.

License: Other

C# 100.00%

fluentscheduler's Introduction

logo

FluentScheduler

Automated job scheduler with fluent interface.

Usage

The job configuration is handled in a Registry class. A job is either an Action or a class that inherits IJob:

using FluentScheduler;

public class MyRegistry : Registry
{
    public MyRegistry()
    {
        // Schedule an IJob to run at an interval
        Schedule<MyJob>().ToRunNow().AndEvery(2).Seconds();

        // Schedule an IJob to run once, delayed by a specific time interval
        Schedule<MyJob>().ToRunOnceIn(5).Seconds();

        // Schedule a simple job to run at a specific time
        Schedule(() => Console.WriteLine("It's 9:15 PM now.")).ToRunEvery(1).Days().At(21, 15);

        // Schedule a more complex action to run immediately and on an monthly interval
        Schedule<MyComplexJob>().ToRunNow().AndEvery(1).Months().OnTheFirst(DayOfWeek.Monday).At(3, 0);

        // Schedule a job using a factory method and pass parameters to the constructor.
        Schedule(() => new MyComplexJob("Foo", DateTime.Now)).ToRunNow().AndEvery(2).Seconds();
                
        // Schedule multiple jobs to be run in a single schedule
        Schedule<MyJob>().AndThen<MyOtherJob>().ToRunNow().AndEvery(5).Minutes();
    }
} 

You can also use the Registry class directly (instead of inheriting it):

var registry = new Registry();
registry.Schedule<MyJob>().ToRunNow().AndEvery(2).Seconds();
registry.Schedule<MyJob>().ToRunOnceIn(5).Seconds();
registry.Schedule(() => Console.WriteLine("It's 9:15 PM now.")).ToRunEvery(1).Days().At(21, 15);
registry.Schedule<MyComplexJob>().ToRunNow().AndEvery(1).Months().OnTheFirst(DayOfWeek.Monday).At(3, 0);
registry.Schedule<MyJob>().AndThen<MyOtherJob>().ToRunNow().AndEvery(5).Minutes();

To check all possible options of scheduling you can use IntelliSense on the go or check this daunting call graph (click to enlarge):

call graph

With the registry ready you then need to initialize the JobManager. This is usually done as soon as your application is loaded (in the Application_Start method of a web application for example):

protected void Application_Start()
{
    JobManager.Initialize(new MyRegistry()); 
} 

It's also possible to schedule jobs after initialization:

JobManager.AddJob(() => Console.WriteLine("Late job!"), (s) => s.ToRunEvery(5).Seconds());

Using it with ASP.NET

When using it with ASP.NET consider implementing IRegisteredObject in your job and registering it itself on HostingEnvironmentย (here's a great explanation on it), like:

public class SampleJob : IJob, IRegisteredObject
{
    private readonly object _lock = new object();

    private bool _shuttingDown;

    public SampleJob()
    {
        // Register this job with the hosting environment.
        // Allows for a more graceful stop of the job, in the case of IIS shutting down.
        HostingEnvironment.RegisterObject(this);
    }

    public void Execute()
    {
        lock (_lock)
        {
            if (_shuttingDown)
                return;

            // Do work, son!
        }
    }

    public void Stop(bool immediate)
    {
        // Locking here will wait for the lock in Execute to be released until this code can continue.
        lock (_lock)
        {
            _shuttingDown = true;
        }

        HostingEnvironment.UnregisterObject(this);
    }
}

Using it with .NET Core

FluentScheduler supports .NET Core, just add the dependency to project.json and run dotnet restore.

  "dependencies": {
    "FluentScheduler": "<desired version>"
  }

Stopping the Scheduler

If you just want to stop the scheduler, call JobManager.Stop(). If you want to both stop the scheduler and wait the currently running jobs to finish, call JobManager.StopAndBlock().

Dependency Injection

FluentScheduler makes it easy to use your IoC tool of choice to create job instances. Simply implement IJobFactory.

An example using StructureMap:

using FluentScheduler;
using StructureMap;

public class StructureMapJobFactory : IJobFactory
{
    public IJob GetJobInstance<T>() where T : IJob
    {
        return ObjectFactory.Container.GetInstance<T>();
    }
}

public class MyRegistry : Registry
{
    public MyRegistry()
    {
        // Schedule an IJob to run at an interval
        Schedule<MyJob>().ToRunNow().AndEvery(2).Seconds();
    }
} 

Register the new job factory with the JobManager:

protected void Application_Start()
{
    JobManager.JobFactory = new StructureMapJobFactory();
    JobManager.Initialize(new MyRegistry()); 
}

Unexpected exceptions

To observe unhandled exceptions from your scheduled jobs, you will need to hook the JobException event on JobManager. That event will give you access to the underlying System.Threading.Tasks.Task and thrown exception details.

JobManager.JobException += (info) => Log.Fatal("An error just happened with a scheduled job: " + info.Exception);

Not milliseconds

The aim of the library is ease of use and flexibility, and not millisecond precision.

While we make best efforts to ensure the library efficiency, we don't test it for milliseconds. Guaranteeing such precision can be tricky considering the time the library spends 'with itself'. That's why the least interval you can set is one second.

Daylight Saving Time

Unfortunately, not unlike many schedulers, there is no Daylight Saving Time support yet.

If you are worried about your jobs not running or running twice due to that, the suggestion is to avoid troublesome time ranges or just call JobManager.UseUtcTime() before using the library.

Weekly jobs

Let's suppose it's 10:00 of a Monday morning and you want to start a job that runs every Monday at 14:00. Should the first run of your job be today or only on the next week Monday?

If you want the former (not waiting for a whole week):

// Every "zero" weeks
Schedule<MyJob>().ToRunEvery(0).Weeks().On(DayOfWeek.Monday).At(14, 0);

Or if you want the latter (making sure that at least one week has passed):

// Every "one" weeks
Schedule<MyJob>().ToRunEvery(1).Weeks().On(DayOfWeek.Monday).At(14, 0);

Concurrent jobs

By default, the library allows a schedule to run in parallel with a previously triggered execution of the same schedule.

If you don't want such behaviour you can set a specific schedule as non-reentrant:

public class MyRegistry : Registry
{
    Schedule<MyJob>().NonReentrant().ToRunEvery(2).Seconds();
}

Or you can set it on all schedules:

public class MyRegistry : Registry
{
    NonReentrantAsDefault();
    Schedule<MyJob>().ToRunEvery(2).Seconds();
}

Contributing

Feel free to open an issue or submit a pull request. To make sure your pull request doesn't go in vain (gets declined), open an issue first discussing it (before actually implementing it).

When sending a patch remember to Run All Tests (Ctrl + R, A) and Run Code Analysis on Solution (Alt + F11) if possible. And, of course, be consistent with the existing code.

You can also help others in need for support, there's a "help wanted" label to sign those issues.
Right now most of them are about problems on different environments (other than vanilla .NET in Windows):

fluentscheduler's People

Contributors

dnauck avatar eokadas avatar hakanl avatar jgeurts avatar mdissel avatar mjamro avatar tallesl avatar thanood avatar urbanbjorkman avatar vkaldi avatar youcandanch avatar

Watchers

 avatar  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.