Отмена Lwt. нить
Я не могу на всю жизнь найти способ справиться с отменой lwt-темы.
Вот что я упростила.
#require "lwt.unix, lwt.ppx"
open Lwt.Infix
let program =
let counter = ref 1 in
let can_cancel = fst (Lwt.task ()) in
Lwt.async_exception_hook := (fun _ ->
prerr_endline "some exception");
Lwt.on_cancel can_cancel (fun () ->
Lwt_io.printl "correct ending" |> Lwt.ignore_result);
Lwt.async begin fun () ->
let rec forever () =
try%lwt
Lwt_io.printl "Hello World" >>= fun () ->
if !counter = 3 then Lwt.cancel can_cancel
else counter := !counter + 1;
Lwt_unix.sleep 0.5 >>= forever
with
Lwt.Canceled -> Lwt_io.printl "canceled inside function"
in
Lwt.catch forever begin function
| Lwt.Canceled -> Lwt_io.printl "Cancled exception happened"
| _ -> Lwt.return ()
end
end;
can_cancel
let () =
Lwt_main.run program
Вы можете видеть мои несколько попыток поймать исключение Отменено, ни одна из которых не работает. Мой вывод
utop cancelable.ml ⏎
Hello World
Hello World
Hello World
correct ending
Exception: Lwt.Canceled.
В более грандиозной схеме вещей у меня есть unit Lwt.t list ref
, которые были созданы с Lwt.task
, а потом я планирую делать List.iter Lwt.cancel
в списке, а затем заменить его на новые темы типа unit Lwt.t
1 ответ
Решение
Я ставил попытку / с на неправильном уровне.
Этот код показывает правильное место для размещения try/with для исключения Lwt.Canceled
#require "lwt.unix, lwt.ppx"
open Lwt.Infix
let program =
let counter = ref 1 in
let can_cancel = fst (Lwt.task ()) in
Lwt.async begin fun () ->
let rec forever () =
Lwt_io.printl "Hello World" >>= fun () ->
if !counter = 3 then Lwt.cancel can_cancel
else counter := !counter + 1;
Lwt_unix.sleep 0.5 >>= forever
in
forever ()
end;
can_cancel
let () =
try
Lwt_main.run program
with
Lwt.Canceled -> Lwt_io.printl "ended" |> Lwt.ignore_result