Conversation
|
Hi @vog, Thank you for the PR. Unfortunately this would change the semantics of Also you will need to expose Note also that you can, with a little boiler plate, workaround this by doing things manually: let of_flow ~sw flow =
(* Copied from https://github.com/ocaml-multicore/eio/blob/62b9714f0e2ed8e72046c8e5808202e1e3ca9cd7/lib_eio/buf_write.ml#L507
We have to do our own copy, because we can't [shift] until the write is complete. *)
let copy t flow =
let rec aux () =
let iovecs = Eio.Buf_write.await_batch t in
let wrote = Eio.Flow.single_write flow iovecs in
Eio.Buf_write.shift t wrote;
aux ()
in
try aux ()
with End_of_file -> ()
in
let t = Eio.Buf_write.create ~sw 0x1000 in
Eio.Switch.on_release sw (fun () -> Eio.Buf_write.close t);
Fiber.fork ~sw (fun () -> copy t flow);
tNote that this will likely have the same problems as before (perhaps a |
|
The Eio API is trying to avoid the mistake where you think you've finished writing but the buffer hasn't been flushed yet. Adding In the PR you link, perhaps it would be simpler to return the flow and let the caller wrap it in a buffer? |
Very good point. These types of bugs are really nasty and hard to pin down. However, in the context of buffered writers, aren't users of such buffers already aware of the danger, and used to having to call
Well, the "caller" is generic code that is independent from EIO, LWT, etc., and even if I would refactor all that code as well, I'm pretty sure this would sneak into the library's API surface. However, maybe I'm overlooking a simple solution, and PRs for pgx-eio are always welcome, especially from experienced EIO developers. |
For buffered serialization into a
flow, at the moment there is onlyBuf_write.with_flow, so those serializers are expected to always run wrapped within a single function.This PR introduces
Buf_write.of_flowwhich allows a serializer to outlive its invocation, but instead being restricted by a surroundingSwitch, as usual. Also, proper closing of the write is ensured bySwitch.on_releasein success as well as error cases.. This makesBuf_writemore straight forward to use e.g. in network protocols, which otherwise need unfortunate workarounds like this one:Moreover,
Buf_write.with_flowis simplified by just callingBuf_write.of_flowwithin a localSwitch.