Last active
April 3, 2018 12:52
-
-
Save Szer/162810c83a4a1920668cb9cf2c7c838e to your computer and use it in GitHub Desktop.
async work
This file contains 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.Threading | |
open System | |
let random = Random(int DateTime.UtcNow.Ticks) | |
let asyncMockup s = async { | |
let sleepFor = int (random.NextDouble() * 3000.) | |
do! Async.Sleep sleepFor | |
return sprintf "resulted %s" s | |
} | |
let inline (>>=) x f = async.Bind(x, f) | |
let inline (>>-) x f = async.Bind(x, f >> async.Return) | |
let requestMasterAsync limit urls = | |
let results = Array.zeroCreate (List.length urls) | |
let mutable running = 0 | |
let mutable order = -1 | |
let completed = Event<_>() | |
let rec loop = function | |
| [] when running = 0 -> results |> async.Return | |
| [] -> | |
Async.AwaitEvent completed.Publish | |
>>= fun _ -> loop [] | |
| work::left when running < limit -> | |
Interlocked.Increment &running |> ignore | |
let orderId = Interlocked.Increment &order | |
work |> asyncMockup | |
>>- fun result -> | |
results.[orderId] <- result | |
Interlocked.Decrement &running |> ignore | |
completed.Trigger() | |
|> Async.Start | |
loop left | |
| left -> | |
Async.AwaitEvent completed.Publish | |
>>= fun _ -> loop left | |
loop urls | |
let results = | |
List.init 20 string | |
|> requestMasterAsync 3 | |
|> Async.RunSynchronously |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment