Едновременни/паралелни Http повиквания в опашка с газ

Ако имате много URL адреси за извикване, има ли модели на опашка във F# с някакъв вид ограничение, като да кажем 5 или 10 извиквания наведнъж, преди да продължите към следващата група.

let urls = [
    "http://example.com/1", 
    "http://example.com/2", 
    "http://example.com/3",
    ....
    "http://example.com/100"]

Докато предавате функция за извикване

let getAsync (url:string) = 
    async {
        let httpClient = new System.Net.Http.HttpClient()
        let! response = httpClient.GetAsync(url) |> Async.AwaitTask
        response.EnsureSuccessStatusCode () |> ignore
        let! content = response.Content.ReadAsStringAsync() |> Async.AwaitTask
        return content
}

и след това получавате списък с всички резултати и всички грешки, тъй като някои обаждания може да са неуспешни поради някаква причина като грешки 404 или 500.


person App2015    schedule 12.03.2018    source източник
comment
какво не е наред с въпроса?   -  person App2015    schedule 12.03.2018
comment
Технически, това не е въпрос? За малко google foo може да намерите http://www.fssnip.net/oz/title/Throttling-agent.   -  person kaefer    schedule 12.03.2018
comment
страхотно, благодаря за линка,   -  person App2015    schedule 12.03.2018


Отговори (1)


Първо, накарайте вашата функция действително да връща информацията за грешката, вместо да я хвърля като изключение:

let getAsync url : Result<_,_> =
    async {
        try
            ...
            return (Ok content)
        with ex ->
            return (Error ex)
    }

След това използвайте Async.Parallel , за да ги изпълните паралелно. Тази функция приема list<Async> и връща Async<list>:

let allResults = urls |> List.map getAsync |> Async.Parallel
person Fyodor Soikin    schedule 12.03.2018
comment
благодаря за опита, цитираният документ казва, че първоначално всеки е поставен на опашка като работен елемент, не ми е ясна частта за дросела, изисква ли се един url наведнъж или всичките 100 паралелно? - person App2015; 12.03.2018
comment
има ли начин да контролирам дросела с Async.Parallel, също гледам Mailbox Processor и не съм сигурен дали там е решението, fsharpforfunandprofit.com/posts/concurrency-actor-model - person App2015; 12.03.2018
comment
Поставянето на опашка като работен елемент означава, че следващата налична нишка от пула от нишки ще изпълни задачата. Така че в зависимост от размера на пула от нишки ще имате едновременни извиквания. тук можете да видите добро резюме на async в .net (F#): medium.com/ jettech/f-async-guide-eb3c8a2d180a - person TGN12; 25.11.2018