Skip to content

For discussion: Cohttp_lwt_body: Add `CustomStream type#534

Closed
mattjbray wants to merge 2 commits intomirage:masterfrom
mattjbray:lwt-custom-stream
Closed

For discussion: Cohttp_lwt_body: Add `CustomStream type#534
mattjbray wants to merge 2 commits intomirage:masterfrom
mattjbray:lwt-custom-stream

Conversation

@mattjbray
Copy link
Copy Markdown
Contributor

The motivation for this change is to give the user more control over how and when the response body is written. In particular, this allows the user to catch exceptions raised during the write operation.

See #528, #529 (sorry for spreading this out over multiple issues).

This API is similar to how Haskell's WAI implements streaming responses.

Benefits:

  • Currently, the user can catch write/flush exceptions in the on_exn hook, but there is no way for the user to know which connection caused the exception. The user can get finalizer-like functionality (since Ensure conn_closed is called if client goes away. #528) by keeping track of connection IDs and matching them up in the conn_closed hook. The CustomStream API provides a much simpler way of doing this.
  • The only API change is to add a constructor to Cohttp_lwt_body.t, so downstream libraries (e.g. Opium, Expose the new on_exn hook in cohttp_lwt_unix? rgrinberg/opium#65) are not affected. It is not a breaking change, c.f. adding per-connection conn_closed/on_exn hooks.

Drawbacks:

  • Complicates the API slightly; there are now two ways to create streaming responses.

Other issues:

  • I am not sure about the name CustomStream.
  • WAI also provides the user with a flush function. This seemed like a more invasive change, and I haven't got my head around the mechanics of flushing in Cohttp yet, so I haven't tried this. Do we need to?
  • I am not sure about the implementations of is_empty, to_stream and length.

Gives the user finer control over writing the body. In particular, the user can
catch exceptions raised during the write operation.
@rgrinberg
Copy link
Copy Markdown
Member

I think this approach is definitely the correct approach in general. Lwt_stream is quite fragile and should be deprecated altogether. The other benefits of this approach is that it can be made uniform between Async and Lwt.

WAI also provides the user with a flush function. This seemed like a more invasive change, and I haven't got my head around the mechanics of flushing in Cohttp yet, so I haven't tried this. Do we need to?

We need a flushing mechanism but it's probably wrong to copy how WAI does it. There are 2 saner ways to signal flushing:

  • Changing the string type input in the function to string option and signaling flushes with None.
  • Signaling flushes by sending the empty string.

I believe WAI used to do the former until they wanted to save some allocations (for reasons that I don't think should affect us). I'm leaning towards the former as well, but I'd like to check how Snap handles this as well.

I am not sure about the name CustomStream

This doesn't follow our naming convention. It should be Custom_stream. I think something like Gen_body or Gen_stream can also be considered because it's a generator like interface.

@hcarty
Copy link
Copy Markdown
Contributor

hcarty commented Mar 6, 2017

It would be nice to have support for cstruct/bigstring-like streams at some point in Cohttp to limit copying. Or Astring-style substrings. So perhaps the name could reflect that this is a stream of strings?

@rgrinberg
Copy link
Copy Markdown
Member

Most flexible here would be a stream of bodies :P. But for now perhaps we can keep it simple and accept chunks that are either substrings or cstructs

@avsm
Copy link
Copy Markdown
Member

avsm commented Mar 7, 2017

I think this approach is definitely the correct approach in general. Lwt_stream is quite fragile and should be deprecated altogether.

Agreed!

@andreas
Copy link
Copy Markdown
Contributor

andreas commented Aug 11, 2019

I think this PR can be closed (according to this comment with #647 merged).

@mattjbray mattjbray closed this Aug 11, 2019
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

Successfully merging this pull request may close these issues.

5 participants