avsm/ocaml-cohttp — pull request #88 by rgrinberg (2014-02-08 08:39:52+00:00)
Title: Async backend improvements

The main feature this is adding is support for persistent connections like Lwt which also supports pipelining at the moment.

To do this I've mainly had to refactor the type of response to be `Response.t * Body.t` instead of just a thunk that writes to the socket. The reason is that we'd like to append custom headers to a response, and with the old response type they were not modifiable. This makes it very similar to the lwt backend with its `Cohttp_lwt_body` module.

There are some interface breaking changes:

* body type is abstract and is not just a string pipe. I think this is better and more inline with the lwt module.
* `val respond` now returns a deferred. More consistent with the other respond helpers. Also I don't think the interface should promise not be async here in the future.

I have a branch of my sinatra clone opium that's upgraded to use this branch and changes seemed trivial and obvious.

Still this is a rather big change and I'd like some feedback before diving in to make further improvements (pipelining, timeouts, max connections per client, etc.) For example:

* `Cohttp_lwt_body` uses option to support empty bodies. I made the choice of inlining option. I feel this way is better because it makes pattern matching cleaner and it doesn't mislead the user into thinking that the `Some _` constructor will give you a non empty body. Also it leads to less pointer chasing perhaps?

* Why not expose the type `Cohttp_lwt_body.t`? This way we can have have a backend independent body: `[`String of string | `Empty | `Buffer of Buffer.t ....]` and have the lwt and async bodies subtypes of that bringing in pipes or lwt streams.