dream icon indicating copy to clipboard operation
dream copied to clipboard

write on closed websocket hangs with 100% CPU, does not handle EPIPE properly

Open bewo001 opened this issue 6 months ago • 1 comments

I like this framework a lot, but this bug is pretty serious.

setup: browser opens websocket to Dream server; browser gets killed, Dream server does a single Dream.send. expected behaviour: exception / a result to indicate the websocket is no longer available. observed behaviour: Dream server process uses 100% cpu. strace shows endlessly repeated writev calls with identical payload returning EPIPE:

11557 writev(17, [{iov_base="\201l", iov_len=2}, {iov_base="{..}}", iov_len=108}], 2) = -1 EPIPE (Broken pipe)
11557 --- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=11557, si_uid=1001} ---
11557 rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [PIPE], 8) = 0
11557 rt_sigprocmask(SIG_SETMASK, [PIPE], NULL, 8) = 0
11557 rt_sigreturn({mask=[]})           = -1 EPIPE (Broken pipe)
11557 writev(17, [{iov_base="\201l", iov_len=2}, {iov_base="{..}}", iov_len=108}], 2) = -1 EPIPE (Broken pipe)

according to perf record, it spends the most time in these functions:

   6.81%  vsdt     vsdt               [.] Lwt_unix.append_3711
   6.66%  vsdt     vsdt               [.] Faraday_lwt_unix.anon_fn[faraday_lwt_unix.ml:6,2--482]_12
   6.28%  vsdt     vsdt               [.] Lwt.catch_2580
   5.90%  vsdt     vsdt               [.] Stdlib.List.iter_740
   5.02%  vsdt     vsdt               [.] Lwt_unix.writev_4104
   4.63%  vsdt     vsdt               [.] Gluten_lwt.write_loop_step_277
   4.48%  vsdt     vsdt               [.] Lwt_unix.append_bigarray_3746
   4.25%  vsdt     vsdt               [.] Lwt_unix.flatten_3761
   3.73%  vsdt     vsdt               [.] Lwt.bind_2077
   3.56%  vsdt     vsdt               [.] Stdlib.List.rev_append_366
   3.43%  vsdt     vsdt               [.] caml_find_frame_descr
   3.43%  vsdt     vsdt               [.] Lwt_unix.check_3892
   3.12%  vsdt     vsdt               [.] caml_modify
   3.10%  vsdt     vsdt               [.] Faraday.map_to_list_294
   2.68%  vsdt     vsdt               [.] Lwt.underlying_344
   2.63%  vsdt     vsdt               [.] Faraday.operation_1544
   2.53%  vsdt     vsdt               [.] Httpun_ws.Wsd.next_432
   2.22%  vsdt     vsdt               [.] Lwt_unix.check_io_vectors_3937
   1.32%  vsdt     vsdt               [.] Faraday_lwt_unix.anon_fn[faraday_lwt_unix.ml:12,6--82]_50
   1.17%  vsdt     vsdt               [.] caml_raise_exn````

bewo001 avatar Oct 28 '25 20:10 bewo001

I've open an issue on the gluten lwt git containing a fix. Gluten does not check the result of the writev which keeps returning EPIPE when trying to write on a closed socket.

bewo001 avatar Nov 01 '25 19:11 bewo001