标签: ocaml-lwt

如何阻止OCaml垃圾收集我的被动事件处理程序?

我试图使用的OBULwt_react.这对属性和信号使用"功能反应式编程".

问题(如React文档中所述)是OCaml可能会在您仍在使用它时对您的回调进行垃圾回收.有一个keep函数,它永远保持处理程序,但我不希望这样.我想最终释放它,而不是在我还需要的时候.

所以,我以为我会将处理程序附加到一个开关:

let keep ~switch handler =
  Lwt_switch.add_hook (Some switch) (fun () ->
    ignore handler;
    Lwt.return ()
  )
Run Code Online (Sandbox Code Playgroud)

但是我的事件处理程序无论如何都会被垃圾收集(这是有道理的,因为当信号到达时会调用关闭开关的代码,因此只有信号处理程序才能保持交换机处于活动状态).

这是我的代码的简化(独立)版本:

(* ocamlfind ocamlopt -package react,lwt,lwt.react,lwt.unix -linkpkg -o test test.ml *)

let finished_event, fire_finished = React.E.create ()

let setup () =
  let switch = Lwt_switch.create () in

  let finished, waker = Lwt.wait () in
  let handler () = Lwt.wakeup waker () in
  let dont_gc_me = Lwt_react.E.map handler finished_event in
  ignore dont_gc_me;  (* …
Run Code Online (Sandbox Code Playgroud)

ocaml garbage-collection reactive-programming ocaml-lwt

8
推荐指数
1
解决办法
781
查看次数

Lwt泄漏文件描述符,不确定bug或我的代码

(交叉发布到lwt github问题)

我已经将我的用法归结为此代码示例,这将泄漏文件描述符.

说你有:

#require "lwt.unix"

open Lwt.Infix

let echo ic oc = Lwt_io.(write_chars oc (read_chars ic))

let program =
  let server_address = Unix.(ADDR_INET (inet_addr_loopback, 2000)) in

  let other_addr = Unix.(ADDR_INET (inet_addr_loopback, 2001)) in

  let server = Lwt_io.establish_server server_address begin fun (tcp_ic, tcp_oc) ->
      Lwt_io.with_connection other_addr begin fun (nc_ic, nc_oc) ->

        Lwt_io.printl "Created connection" >>= fun () ->
        echo tcp_ic nc_oc <&> echo nc_ic tcp_oc >>= fun () ->
        Lwt_io.printl "finished"

      end
      |> Lwt.ignore_result

    end
  in
  fst (Lwt.wait ())

let …
Run Code Online (Sandbox Code Playgroud)

ocaml resource-leak ocaml-lwt

7
推荐指数
2
解决办法
225
查看次数

是否真的使用了ocaml中的流?

看看不同的ocaml项目,我没有看到使用过的语言中的内置Streams.即使在最近的Real World Ocaml书中,也没有提到Streams,这很奇怪.

这是什么原因?是因为Lwt或Core取代了它们吗?

ocaml stream ocaml-lwt

5
推荐指数
1
解决办法
527
查看次数

Ocaml lwt 永无止境的循环

我正在尝试使用 Lwt 编写一个终端应用程序。基本上,只要我的应用程序正在运行,我就需要使用 Lwt_io.read_line 来观察终端的输入。

有没有比以下(伪代码)更好的方法来在我的程序运行时实现某种循环?

while true do
  let _ = ignore (Lwt_main.run my_application)
done
Run Code Online (Sandbox Code Playgroud)

我不确定这是否是正确的方法。每次 my_application 中的所有线程完成时,Lwt_main.run 就会一次又一次地被调用...

Lwt 是否有其他或更好的方法来处理这个问题?

ocaml ocaml-lwt

3
推荐指数
1
解决办法
630
查看次数

Lwt_io.read_int的正确用法是什么?

你如何正确使用Lwt_io.read_int?我尝试了我认为明显的用法,但我没有得到明显的结果......

open Lwt.Infix

let _ =
  Lwt_main.run
    (
      Lwt_io.print "Enter number: " >>=
      fun () -> Lwt_io.read_int (Lwt_io.stdin) >>=
      fun d -> Lwt_io.printf "%d\n" d
    )
Run Code Online (Sandbox Code Playgroud)

我在提示时编译,运行并输入了12345,程序显示为875770417.

我在这里遗漏了一些东西......

在下面的帮助下,我到达了这一点.它有效,我希望它是正确的.

open Lwt.Infix

let _ =
  Lwt_main.run
    (
      Lwt_io.print "Enter number: " >>=
      fun () -> Lwt_io.read_line (Lwt_io.stdin) >>=
      fun s -> 
      (
        try
          Lwt.return_some( Pervasives.int_of_string s)
        with
        | _ -> Lwt.return_none
      ) >>=
      fun o -> 
      Lwt_io.print
        (
          match o with
          | Some i -> Printf.sprintf "%d\n" i
          | None -> …
Run Code Online (Sandbox Code Playgroud)

ocaml ocaml-lwt

2
推荐指数
1
解决办法
250
查看次数

在这种情况下如何充分利用`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())  
Run Code Online (Sandbox Code Playgroud)

问题来自实际的do_task部分.

所以任务涉及http downloadcomputation.

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 = …
Run Code Online (Sandbox Code Playgroud)

ocaml ocaml-lwt

1
推荐指数
1
解决办法
428
查看次数

Lwt和Cohttp:致命错误:异常Unix.Unix_error(Unix.ECONNRESET,“ read”,“”)`

我在Ocaml中有带有Cohttp和Lwt的简单HTTP服务器。当我运行时wrk,应用程序一完成就崩溃约50%的时间wrk。我想象崩溃是由连接意外断开引起的。

我在控制台上看到以下错误:

Fatal error: exception Unix.Unix_error(Unix.ECONNRESET, "read", "")
Raised by primitive operation at file "src/unix/lwt_bytes.ml", line 130, characters 42-84
Called from file "src/unix/lwt_unix.ml", line 489, characters 13-24
Run Code Online (Sandbox Code Playgroud)

反正有防止这种情况发生的方法吗?

我的完整源代码是:

(* server_test.ml *)
open Unix
open Lwt
open Cohttp
open Cohttp_lwt_unix
open Yojson
open Yojson.Basic.Util
open Core.Std

type create = {
username: string;
email: string;
password: string;
} [@@deriving yojson]

let insert coll doc =
    let _id = Core.Std.Uuid.to_string (Uuid.create ()) in
    let uri = Uri.make ~scheme:"http" …
Run Code Online (Sandbox Code Playgroud)

ocaml ocaml-lwt

1
推荐指数
1
解决办法
358
查看次数

Ocaml Lwt.wait()

我对lwt的wait函数以及如何在自己的自定义函数中使用它(该函数将返回一个Lwt.t线程)有疑问。首先让我们给你看一个例子。

open Lwt_io
open Lwt.Infix

let i, o = Lwt_io.pipe()

let get_int () =
  let t, w = Lwt.wait() in
  (*what do I do here to provide the sleeping thread*)
  (*with a possible integer reply*)
  Lwt_io.read_int(i) >>= fun i -> Lwt.wakeup w i;
  t

let ans = get_int()
Run Code Online (Sandbox Code Playgroud)

在上面的函数中,我调用wait来产生一个睡眠线程及其唤醒器,但是我不确定如何为睡眠线程提供可能的整数答复,并且仍然能够从get_int函数返回睡眠线程。我提供了一行(Lwt_io.read_int(i)>> = fun i-> Lwt.wakeup wi;),该行似乎有效,但是我不确定这是否是实现此目的的正确方法。有指针,链接或评论吗?

注意:我问是因为向函数添加Lwt_io.read_int(i)是多余的。我可以消除get_int函数,而仅调用Lwt_io.read_int(i),但我很好奇您如何在没有冗余的情况下执行此操作。

ocaml ocaml-lwt

1
推荐指数
1
解决办法
441
查看次数

Lwt和递归函数

可以使用Lwt.return作为递归函数的最终调用吗?

我有一个编译正常但功能不正常的函数,它看起来像f下面的函数.请假设g在此示例中提供的任何功能都没有问题,我基本上只是试图找出是否可以使用以下形式的函数,或者是否有更好/更简单(和Lwt兼容)的方式做以下事情:

 let rec f (x : string list) (g : string -> unit Lwt.t) =
   match List.length x with
   | 0 -> Lwt.return ()
   | _ -> g (List.hd x) >>= fun () -> f (List.tl x) g
 ;;
 val f : string list -> (string -> unit Lwt.t) -> unit Lwt.t = <fun>  
Run Code Online (Sandbox Code Playgroud)

我很确定我做错了.但是我使用的实际功能比这个例子复杂得多,所以我很难调试它.

ocaml tail-recursion ocsigen ocaml-lwt

0
推荐指数
1
解决办法
367
查看次数