Skip to content

Instantly share code, notes, and snippets.

@davidgrenier
Created November 18, 2011 22:31
Show Gist options
  • Select an option

  • Save davidgrenier/1377981 to your computer and use it in GitHub Desktop.

Select an option

Save davidgrenier/1377981 to your computer and use it in GitHub Desktop.
Task limiter
open System
type IParallelLimiter =
abstract GetToken : unit -> Async<IDisposable>
type Message=
| GetToken of AsyncReplyChannel<IDisposable>
| Release
let start count =
let agent =
MailboxProcessor.Start(fun inbox ->
let newToken () =
{ new IDisposable with
member x.Dispose () = inbox.Post Release }
let rec loop n = async {
let! msg = inbox.Scan <| function
| GetToken _ when n = 0 -> None
| msg -> async.Return msg |> Some
return!
match msg with
| Release ->
loop (n + 1)
| GetToken port ->
port.Reply <| newToken ()
loop (n - 1)
}
loop count)
{ new IParallelLimiter with
member x.GetToken () =
agent.PostAndAsyncReply GetToken}
let limiter = start 100;;
for _ in 0..1000 do
async {
use! token = limiter.GetToken ()
Console.WriteLine "Sleeping..."
do! Async.Sleep 3000
Console.WriteLine "About to release..."
} |> Async.Start
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment