<Query Kind="FSharpProgram" />

open System
open System.Threading
open System.Threading.Tasks

let acount = ref 2
let adone = TaskCompletionSource<unit> ()
let m = 1000000000

let cons = new MailboxProcessor<int> (fun inbox ->
    let rec loop n = async {
        let! n' = inbox.Receive ()
        if n' % 100 = 0 then printfn "... %d %d: %d" n inbox.CurrentQueueLength n'
        do! Async.Sleep 10
        
        if n > m then 
            if Interlocked.Decrement acount = 0 then adone.SetResult ()
            return ()
        else 
            return! loop (n+1)
        }
    loop 1)

let prod = new MailboxProcessor<int> (fun inbox ->
    let rec loop n = async {
        //do! Async.Sleep 0
        cons.Post n
        
        if n > m then 
            if Interlocked.Decrement acount = 0 then adone.SetResult ()
            return ()
        else 
            return! loop (n+1)
        }
    loop 1)

cons.Start ()
prod.Start ()

adone.Task.Wait ()
printfn "..."

