我试图使用的OBU库Lwt_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) (交叉发布到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项目,我没有看到使用过的语言中的内置Streams.即使在最近的Real World Ocaml书中,也没有提到Streams,这很奇怪.
这是什么原因?是因为Lwt或Core取代了它们吗?
我正在尝试使用 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 是否有其他或更好的方法来处理这个问题?
你如何正确使用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) 这是我要做的事情:
我有一个列表,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 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 = …Run Code Online (Sandbox Code Playgroud) 我在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) 我对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),但我很好奇您如何在没有冗余的情况下执行此操作。
可以使用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)
我很确定我做错了.但是我使用的实际功能比这个例子复杂得多,所以我很难调试它.