I recently started playing with Hopac and think that this is just awesome. Here is, however a problem that I cannot wrap my head around. Below is the code snippet:
let rnd = new Random()
let logger (msg:string) =
let c = Ch<string>()
let msgLoop = job {
for i in [1..15] do
let msgStr = sprintf "%s %d" msg i
do! timeOutMillis (rnd.Next(1000,3000))
do! c *<- msgStr
}
printfn "Started job %s" msg
msgLoop |> start
c
let timeout = timeOutMillis 3000
let c = logger "Instance Foo"
let rec printLoop () = Job.delay <| fun () ->
Alt.choose[
timeout ^=> fun () -> printfn "job timed out"
Job.result ()
Ch.take c ^=> fun msg -> printfn "Log: %s" msg
printLoop ()
]
printLoop () |> start
I supposed that after 3000 msec is elapsed timeout alternative will become available and will abort printing messages. This is not happening, and timeout gets fired only when nothing is left in channel c
.
I placed timeout at the first placein Alt.choose list since as per documentation if multiple alternatives are available at the same time, the one which appears first in the list gets picked (On the Semantics of Alternatives)
Any help is highly appreciated
Here is a quick answer. The timeout is not started on the line:
Rather, the timeout is (re)started on the line
every time the line is evaluated. The shortest fix to the program would be to change the line where you define the timeout as: