Skip to content

Instantly share code, notes, and snippets.

@mastoj
Last active February 16, 2016 07:47
Show Gist options
  • Save mastoj/efa01160b62457ed6c24 to your computer and use it in GitHub Desktop.
Save mastoj/efa01160b62457ed6c24 to your computer and use it in GitHub Desktop.
/// 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