2016-11-08 14 views
1

私はOcamlにCohttpとLwtを持つ単純なHTTPサーバーを持っています。 wrkを実行すると、wrkが終了するとアプリケーションは約50%の時間でクラッシュします。クラッシュは接続の予期せぬ破損によって引き起こされると私は想像する。LwtとCohttp: `致命的なエラー:例外Unix.Unix_error(Unix.ECONNRESET、" read "、" ")`

私は、コンソールに次のエラーが表示されます。

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 

はこれを防ぐために、とにかくはありますか?

私の完全なソース・コードは次のとおりです。

(* 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) 

ありがとう!

答えて

3

表示されているエラーは、クライアントが予期せず切断された場合に発生する未処理の例外からです。関連する例外は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の非同期/「バックグラウンド」のスレッドのカスタム例外ハンドラを定義するならば、あなたはログ/キャプチャし、無視することができます/クライアントのエラーを処理します。あなたは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) 
); 
https://github.com/mirage/ocaml-cohttp/issues/511#issuecomment-258510531から撮影

し、イベントをログに記録するlogsライブラリを使用して:http://erratique.ch/software/logs

+1

感謝を!私は "Lwt.async_exception_hook:= ignore;"を追加しました。問題を見るのをやめました。 –

関連する問題