Skip to content

Instantly share code, notes, and snippets.

@nbevans
Created November 21, 2014 10:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nbevans/e7d6356624ea0d85aff8 to your computer and use it in GitHub Desktop.
Save nbevans/e7d6356624ea0d85aff8 to your computer and use it in GitHub Desktop.
Simple F# wrapper around the "triggers" functionality of Quartz.NET
/// 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