Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

writev support #281

Closed
rgrinberg opened this issue Oct 19, 2016 · 5 comments
Closed

writev support #281

rgrinberg opened this issue Oct 19, 2016 · 5 comments
Assignees
Milestone

Comments

@rgrinberg
Copy link
Contributor

From this comment: inhabitedtype/faraday@5eb16a9

This seems like a limitation in Lwt that shouldn't be hard to lift.

@aantron
Copy link
Collaborator

aantron commented Oct 19, 2016

It's worth doing.

Lwt already has types Lwt_unix.io_vector (carrying strings) and Lwt_bytes.io_vector (carrying bigarrays). Implementing writev using those should require Faraday only to allocate these io_vector records. Not sure if there is a better way.

However, looking briefly at Faraday, it seems like some kind of "heterogenous" writev is needed, where the buffers can carry a mixture of strings and bigarrays.

Thoughts?

@rgrinberg
Copy link
Contributor Author

A mixture makes sense if it's possible to write OCaml strings to an fd without
copying. But from what I've seen, an OCaml string has to be copied to a bigarray
to be written. If there's no way to avoid the copying a bigarray based io vector
is enough. But perhaps there's a way to avoid the copying?

do @avsm, @seliopou, or @diml know perhaps?

On 10/19, Anton wrote:

It's worth doing.

Lwt already has types Lwt_unix.io_vector (carrying strings) and Lwt_bytes.io_vector (carrying bigarrays). Implementing writev using those should require Faraday only to allocate these io_vector records. Not sure if there is a better way.

However, looking briefly at Faraday, it seems like some kind of "heterogenous" writev is needed, where the buffers can carry a mixture of strings and bigarrays.

Thoughts?

You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub:
#281 (comment)

@seliopou
Copy link
Contributor

The only function in Lwt that can handle an io_vecotor is send_msg (and recv_msg), which has undesirable semantics for connection-based protocols. Specifically from the BSD and Linux man page:

If the message is too long to pass atomically through the underlying protocol, the error
EMSGSIZE is returned, and the message is not transmitted.

In other words if the combined length of the io_vectors exceed the MTU, it'll fail rather than attempt to send multiple packets. This is in contrast to the behavior of writev, which is fine accepting any number of bytes the caller gives it.

With respect to the heterogenous iovecs in Faraday, that's up to the user to handle as they see fit, given whatever implementation is available.

@aantron
Copy link
Collaborator

aantron commented Oct 19, 2016

@rgrinberg Looking in the implementations of Lwt_unix.write and Lwt_unix.send_msg (as examples), I don't think any copy is done of the bytes/string buffer(s) before the write/sendmsg system calls. I'm not sure what the stdlib does, but I guess, since Lwt reimplements these things, Lwt can do anything, as long as the runtime system is respected :)

@seliopou I think the proposal is to add to Lwt a new function Lwt_unix.writev or Lwt_bytes.writev, or another more suitable one, as implicitly suggested by your comment, not for Faraday to use send_msg.

The query is: for easy and efficient of implementation in Faraday's Faraday_lwt_unix, is it sufficient to type the arguments to the new Lwt_*.writev at (list, array) of the existing Lwt_unix.io_vector/Lwt_bytes.io_vector, or will this not work well, due to e.g. excessive copying or allocations? Which alternative would you prefer? Would such a function be useful for Faraday?

I'm not clear on how dealing with heterogenous iovecs is up to the user to handle as they see fit, assuming they already chose to use Faraday_lwt_unix.writev_of_fd, per the context of this issue.

@aantron
Copy link
Collaborator

aantron commented Oct 19, 2016

I don't think any copy is done of the bytes/string buffer(s) before the write/sendmsg system calls.

@rgrinberg But Lwt_unix.write, when Lwt is using blocking I/O on the fd, does do a copy of the string, as you describe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants