我在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" ~host:"127.0.0.1" ~port:5984 ~path:(coll ^ "/" ^ _id) () in
Cohttp_lwt_unix.Client.put ~body:(Cohttp_lwt_body.of_string (Yojson.Safe.to_string doc)) uri
>|= fun (r, _) -> Code.code_of_status @@ Response.status r
let callback _conn req body =
body |> Cohttp_lwt_body.to_string
>>= (fun body ->
let mc = Yojson.Safe.from_string body |> create_of_yojson in
match mc with
| Ok c ->
insert "users" (create_to_yojson c)
>>= fun status -> print_endline @@ string_of_int status;
Server.respond_string ~status:(`Code status) ~body:(string_of_int status) ()
| _ -> Server.respond_string ~status:`OK ~body: "Not OK" ())
let timeit _conn req body =
let start = Unix.gettimeofday () in
callback _conn req body
>>=
fun result ->
let finish = Unix.gettimeofday () in
Lwt_io.printlf "Execution time took %fms" ((finish -. start) *. 1000.0)
>|= fun _ -> result
let server =
Server.create ~mode:(`TCP (`Port 8000)) (Server.make timeit ())
let () = ignore (Lwt_main.run server)
Run Code Online (Sandbox Code Playgroud)
谢谢!
您看到的错误是由于客户端意外断开连接时引发的未处理异常。相关异常将传递到Lwt的异步异常钩子(http://ocsigen.org/lwt/2.6.0/api/Lwt#VALasync_exception_hook),Lwt默认情况下,该异常钩子将打印回溯并以退出代码退出程序2。
在cohttp github问题跟踪器上正在进行有关此问题的讨论:https : //github.com/mirage/ocaml-cohttp/issues/511
简而言之,如果您为Lwt的async /“ background”线程定义了一个自定义的异常处理程序,则可以捕获和忽略/记录/处理客户端错误。在启动cohttp服务器之前,请添加以下内容:
Lwt.async_exception_hook := (function
| Unix.Unix_error (error, func, arg) ->
Logs.warn (fun m ->
m "Client connection error %s: %s(%S)"
(Unix.error_message error) func arg
)
| exn -> Logs.err (fun m -> m "Unhandled exception: %a" Fmt.exn exn)
);
Run Code Online (Sandbox Code Playgroud)
取自https://github.com/mirage/ocaml-cohttp/issues/511#issuecomment-258510531,并使用该logs库记录事件:http : //erratique.ch/software/logs
| 归档时间: |
|
| 查看次数: |
358 次 |
| 最近记录: |