Как полностью использовать `lwt` в этом случае

Вот что я собираюсь сделать:

У меня есть список task и мне нужно запускать их все каждые 1 час (планирование).

Все эти задачи похожи. например, для выполнения одной задачи мне нужно загрузить некоторые данные с сервера (используя протокол HTTP и это займет 5–8 секунд), а затем выполнить вычисление данных (это займет 1–5 секунд).


Я думаю, что я могу использовать lwt чтобы достичь этого, но не могу найти лучший путь для эффективности.


Для части планирования задач я могу сделать так ( Как запланировать задачу в OCaml?):

let rec start () = 
  (Lwt_unix.sleep 1.)  >>= (fun () -> print_endline "Hello, world !"; start ())

let _ = Lwt_main.run (start())  

Вопросы взяты из фактической части do_task.

Так что задача включает в себя http download а также computation,

http download часть должна была ждать от 5 до 8 секунд. Если я действительно выполняю каждую задачу одну за другой, то это приводит к потере пропускной способности и, конечно, я хочу, чтобы процесс загрузки всех задач был параллельным. Так я должен поместить эту часть загрузки в lwt? и будет ли lwt обрабатывать все загрузки параллельно?

По коду, я должен сделать так?:

let content = function
  | Some (_, body) -> Cohttp_lwt_unix.Body.string_of_body body
  | _ -> return ""


let download task = 
  Cohttp_lwt_unix.Client.get ("http://dataserver/task?name="^task.name)

let get_data task = 
  (download task)  >>= (fun response -> Lwt.return (Content response))

let do_task task = 
  (get_data task) >>= (fun data -> Lwt.return_unit (calculate data))

Таким образом, с помощью приведенного выше кода все задачи будут выполняться параллельно, по крайней мере, для http download часть?

Для расчетной части все вычисления будут выполняться последовательно?

Кроме того, любой может кратко описать механизм lwt? Внутренне, какова логика light weight thread? Почему он может обрабатывать ввод-вывод параллельно?

1 ответ

Решение

Чтобы выполнить параллельные вычисления с использованием lwt, вы можете проверить модуль lwt_list, и особенно iter_p.

val iter_p : ('a -> unit Lwt.t) -> 'a list -> unit Lwt.t

iter_p fl вызывает функцию f для каждого элемента l, а затем ожидает завершения всех потоков. Для вашей цели это будет выглядеть так:

let do_tasks tasks = List.iter_p do_task tasks

Предполагая, что "задачи" - это список задач.

Другие вопросы по тегам