Last active
February 16, 2016 07:47
-
-
Save mastoj/efa01160b62457ed6c24 to your computer and use it in GitHub Desktop.
An alternative background worker to: http://www.navision-blog.de/blog/2015/12/21/adding-background-tasks-to-suave-io-websites/ ?
This file contains hidden or 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
/// Discriminated union representing two messages - one for sending | |
/// numbers to the agent and one for resetting the state of the agent | |
type CounterMessage = | |
| Update of float | |
| Reset | |
// Simple agent that calculates average and can be reset | |
let counter = MailboxProcessor.Start(fun agent -> | |
let rec loop sum count = async { | |
let! msg = agent.Receive() | |
match msg with | |
| Reset -> | |
return! loop 0.0 0.0 | |
| Update f -> | |
let sum, count = sum + f, count + 1.0 | |
printfn "Average: %f" (sum / count) | |
return! loop sum count } | |
loop 0.0 0.0) | |
// Infrastructure code | |
open System | |
type Agent<'T> = MailboxProcessor<'T> | |
type TriggerEvent<'a> = | |
| SingleTask of DateTime * 'a | |
| RecurringTask of TimeSpan * 'a | |
| Stop | |
type TaskMsg = | |
| StopTask | |
let createTrigger<'a> (taskAgent : Agent<'a>) = | |
let createTask repeat time message = Agent.Start(fun agent -> | |
let rec loop () = | |
async { | |
let! msgOption = agent.TryReceive(time) | |
match msgOption with | |
| Some _ -> () | |
| None -> | |
taskAgent.Post message | |
if repeat | |
then return! loop() | |
else () | |
} | |
loop()) | |
let createSingleTask = createTask false | |
let createRecurringTask = createTask true | |
Agent.Start(fun agent -> | |
let rec loop tasks = | |
async { | |
let! msg = agent.Receive() | |
match msg with | |
| Stop -> | |
tasks | |
|> List.iter (fun (t:Agent<TaskMsg>) -> StopTask |> t.Post) | |
return! loop [] | |
| SingleTask(time, message) -> | |
let ms = (time - DateTime.Now).TotalMilliseconds |> int | |
return! loop ((createSingleTask ms message)::tasks) | |
| RecurringTask(time, message) -> | |
let ms = time.TotalMilliseconds |> int | |
return! loop ((createRecurringTask ms message)::tasks) | |
} | |
loop []) | |
let trigger = createTrigger counter | |
trigger.Post(SingleTask(DateTime.Now.AddSeconds(4.), Update 2.3)) | |
trigger.Post(SingleTask(DateTime.Now.AddSeconds(3.), Update 12.3)) | |
trigger.Post(RecurringTask(TimeSpan.FromSeconds(2.), Update 2.1)) | |
trigger.Post(SingleTask(DateTime.Now.AddSeconds(2.), Update 112.3)) | |
trigger.Post(RecurringTask(TimeSpan.FromSeconds(10.), Reset)) | |
System.Console.ReadLine() | |
System.Console.WriteLine("Stopping") | |
trigger.Post(Stop) | |
System.Console.ReadLine() | |
System.Console.WriteLine("Starting") | |
trigger.Post(RecurringTask(TimeSpan.FromSeconds(2.), Update 2.1)) | |
trigger.Post(SingleTask(DateTime.Now.AddSeconds(3.), Update 12.3)) | |
System.Console.ReadLine() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment