Advertisement
Guest User

Untitled

a guest
Jan 30th, 2019
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 1.73 KB | None | 0 0
  1. type Timer = { incomingTasks: Ch<DateTime * Alt<unit> * IVar<Alt<unit>>> }
  2.  
  3. module Timer =
  4.     type Task = {
  5.         wakeTime:   DateTime
  6.         cancel:     Alt<unit>
  7.         fire:       IVar<unit>
  8.     }
  9.  
  10.     let takeFirst tasks = tasks |> List.head |> Some, tasks |> List.tail
  11.  
  12.     let create () =
  13.         let incomingTasks = Ch ()
  14.         let rec loop currentTask nextTasks =
  15.             Alt.choose (seq {
  16.                 yield Ch.take incomingTasks ^=> (fun (wakeTime, cancel, res) ->
  17.                     let fire = IVar ()
  18.                     let newTask = { wakeTime = wakeTime; cancel = cancel; fire = fire }
  19.                     res *<+ fire >>- fun _ ->
  20.                         currentTask |> Option.fold (fun l x -> x::l) (newTask::nextTasks)
  21.                         |> List.sortBy (fun task -> task.wakeTime)
  22.                         |> takeFirst)
  23.                                
  24.                 match currentTask with
  25.                 | Some task ->
  26.                     yield task.cancel ^->. (nextTasks |> takeFirst)
  27.                     let waitTime = task.wakeTime - DateTime.Now
  28.                     yield
  29.                         (if TimeSpan.Compare (waitTime, TimeSpan.Zero) <= 0 then
  30.                             Alt.always ()
  31.                         else
  32.                             (timeOut waitTime))
  33.                         ^=>. (task.fire *<= () >>-. (nextTasks |> takeFirst))
  34.                 | None -> ()
  35.             })
  36.             >>= (fun (currTask, nextTasks) -> loop currentTask nextTasks)
  37.         loop None [] |> Job.startIgnore >>-. { incomingTasks = incomingTasks }
  38.  
  39.     let submit wakeTime cancel timer =
  40.         let res = IVar ()
  41.         timer.incomingTasks *<+ (wakeTime, cancel, res)
  42.         >>=. res
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement