Параллельные/параллельные вызовы 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
Технически, это не вопрос? Чтобы немного погуглить, вы можете найти 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, я также смотрю на процессор почтовых ящиков и не уверен, что это решение, fsharpforfunandprofit.com/posts/concurrency-actor-model - person App2015; 12.03.2018
comment
Постановка в очередь как рабочий элемент означает, что следующий доступный поток из пула потоков выполнит задачу. Поэтому в зависимости от размера пула потоков у вас будут одновременные вызовы. вы можете увидеть здесь хороший обзор асинхронности в .net (F#): medium.com/ jettech/f-async-guide-eb3c8a2d180a - person TGN12; 25.11.2018