Daemon cron using F#
As continuation for my previous post I want to create a daemon which runs jobs using created cron code.
module Daemon =
[<Literal>]
let INTERVAL = 30000
let internalRun interval (now: unit->DateTime) (jobs: seq<Job>) =
// to dispose System.Threading.Timer properly
let createDisposable f =
{
new IDisposable with
member x.Dispose() = f()
}
// event fot Timer
let timerElapsed obj =
let checkJob = () |> now |> Schedule.isTime
jobs
|> Seq.map (fun x ->
let schedule = Schedule.generate x.cron
(schedule, x.action)
)
|> Seq.filter (fun (x, y) -> checkJob x)
|> Seq.map (fun (x, y) -> y)
|> Async.Parallel
|> Async.RunSynchronously
|> ignore
// timer
let localTimer = new Timer(timerElapsed, null, Timeout.Infinite, interval)
// start timer
localTimer.Change(0, interval) |> ignore
// return timer as IDisposable
createDisposable (fun() -> localTimer.Dispose())
// get DateTime
let now = fun () -> DateTime.UtcNow
// public method to call
let run jobs = internalRun INTERVAL now jobs
How to use the daemon above:
type Job = { action: Async<unit>; cron: string }
let act id =
async {
printfn "Execution %A" id
}
let jobs = [|1; 2|] |> Array.map (fun id ->
{
action = act id;
cron = "* * * * *"
})
let daemon = run jobs
Unfortunately I don’t see the good way to wtite unit test for this code as there is hardcoded dependency to System.Threading.Timer.
Feel free to comment if you see the solution. Thanks in advance.