Created
November 21, 2014 10:21
-
-
Save nbevans/e7d6356624ea0d85aff8 to your computer and use it in GitHub Desktop.
Simple F# wrapper around the "triggers" functionality of Quartz.NET
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Provides a simple scheduler service for time and calendar oriented events. | |
module Singapore.Scheduler | |
open System | |
open Quartz | |
open Quartz.Impl | |
let private schedulerFactory = StdSchedulerFactory() | |
let private scheduler = schedulerFactory.GetScheduler() | |
/// Initializes the scheduler agent. | |
let initialize () = | |
scheduler.Start() | |
{ new IDisposable with member __.Dispose() = scheduler.Shutdown(true) } | |
/// Specifies the type of repetition to occur. | |
type Repetitions = | |
/// Repeat the trigger forever, endlessly. | |
| RepeatForever | |
/// Repeat the trigger up to a limited number of times. | |
| RepeatCount of Value : int | |
/// Identifies the unique name and group of a trigger. | |
type TriggerKey = TriggerKey of Name : string * Group : string | |
with | |
member internal x.QuartzTriggerKey = match x with TriggerKey (name, group) -> Quartz.TriggerKey(name, group) | |
member internal x.QuartzJobKey = match x with TriggerKey (name, group) -> Quartz.JobKey(name, group) | |
/// Specifies the characteristics of a trigger schedule. | |
type TriggerSpec = | |
/// A trigger schedule that will be invoked on a recurring time interval for a set number (or unlimited) number of repetitions. | |
| Interval of Interval : TimeSpan * Repetitions : Repetitions | |
/// A trigger schedule that will be invoked on a daily basis at a particular time of day, on particular days of the week. | |
| DailyAtTime of TimeOfDay : TimeSpan * DaysOfWeek : DayOfWeek list | |
/// A trigger schedule that is programmed by a succinct Crontab expression. | |
| CronExpression of Expression : string | |
/// Schedules a trigger from the provided key and specification. | |
let schedule (key:TriggerKey) spec = | |
let tb = TriggerBuilder.Create().WithIdentity(key.QuartzTriggerKey) | |
match spec with | |
| Interval (interval, repetitions) -> | |
ignore <| tb.WithSimpleSchedule(fun sb -> | |
sb.WithInterval interval |> ignore | |
match repetitions with | |
| RepeatForever -> sb.RepeatForever() |> ignore | |
| RepeatCount v -> sb.WithRepeatCount v |> ignore) | |
| DailyAtTime (timeOfDay, daysOfWeek) -> | |
ignore <| tb.WithDailyTimeIntervalSchedule(fun sb -> | |
sb.OnDaysOfTheWeek(daysOfWeek |> List.toArray) |> ignore | |
sb.StartingDailyAt(Quartz.TimeOfDay(timeOfDay.Hours, timeOfDay.Minutes, timeOfDay.Seconds)) |> ignore | |
sb.EndingDailyAfterCount(1) |> ignore) | |
| CronExpression expr -> | |
ignore <| tb.WithCronSchedule(expr) | |
let quartzTrigger = tb.Build() | |
let quartzDummyJob = JobBuilder.Create().OfType<Quartz.Job.NoOpJob>().WithIdentity(key.QuartzJobKey).Build() | |
scheduler.ScheduleJob(quartzDummyJob, quartzTrigger) |> ignore | |
{ new IDisposable with member __.Dispose() = scheduler.DeleteJob(key.QuartzJobKey) |> ignore } | |
/// Listens for a particular trigger key to be triggered and invokes a callback function. | |
let listen key triggered = | |
let listener = { | |
new ITriggerListener with | |
member __.Name = sprintf "Listener for %A" key | |
member __.TriggerFired(trigger, context) = triggered key | |
member __.TriggerMisfired(trigger) = () | |
member __.TriggerComplete(trigger, context, triggerInstructionCode) = () | |
member __.VetoJobExecution(trigger, context) = false | |
} | |
let matcher = { | |
new IMatcher<Quartz.TriggerKey> with | |
member __.IsMatch quartzTriggerKey = TriggerKey(quartzTriggerKey.Name, quartzTriggerKey.Group) = key | |
member __.GetHashCode () = 0 | |
member __.Equals _ = false | |
} | |
scheduler.ListenerManager.AddTriggerListener(listener, matcher) | |
{ new IDisposable with member __.Dispose() = scheduler.ListenerManager.RemoveTriggerListener(listener.Name) |> ignore } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment