Created
November 18, 2011 22:31
-
-
Save davidgrenier/1377981 to your computer and use it in GitHub Desktop.
Task limiter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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