Skip to content

Instantly share code, notes, and snippets.

@Szer
Last active April 3, 2018 12:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Szer/162810c83a4a1920668cb9cf2c7c838e to your computer and use it in GitHub Desktop.
Save Szer/162810c83a4a1920668cb9cf2c7c838e to your computer and use it in GitHub Desktop.
async work
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