libspdy

SPDY is a neat new protocol and possible contender to replace HTTP – at least in some areas and for some use cases. SPDY has been invented and developed mostly by Google engineers.

SPDY allows better usage of fewer TCP connections (since it sends multiple logical streams over a single physical TCP connection) and it helps clients overcome problems with TCP (like how a new connection starts slowly) while at the same time reducing latency and bandwidth requirements. Very similar to how channels are handled over an SSH connection.SPDY

Chrome of course already supports SPDY and Firefox has some early experimental support being worked on.

Of course there are also legitimate criticisms against SPDY as well, including subjects like how it makes caching proxies impossible (because everything goes over SSL), how it makes debugging a lot harder by using compressed headers, how it is impossible to extract just a single header from the stream due to its compression approach and how the compression state buffers make each individual stream use more memory than plain old HTTP (plain TCP) ones.

We can expect SPDY<=>HTTP gateways to appear so that nobody gets locked into either side of these protocols.

SPDY will provide faster transfers. libcurl is currently used for speed reasons in many cases. To me, it makes perfect sense to have libcurl use and try to use SPDY instead of HTTP exactly like how the browsers are starting to do it, so that the libcurl using applications will get their contents transferred faster.

My thinking is that we introduce some new magic option(s) that makes libcurl use SPDY, and for normal easy interface transfers it will remain to use a single connection for each new SPDY transfer, but if you use the multi interface and you enable pipelining you’ll instead make libcurl do multiple transfers over the same single SPDY connection (as long as you speak with the same server and port etc). From an application’s stand-point it shouldn’t make any difference, apart from being faster than otherwise. Just like we want it!

Implementation wise, I would like to use a reliable and efficient third-party library for the actual SPDY implementation. If there doesn’t exist any, we make one and run that one independently. I found libspdy, but I found some concerns about it (no┬ámailing list, looks like one-man project, not C89 compliant, no API docs etc). I mailed the libspdy author, I hoping we’d sort out my doubts and then I’d base my continued work on that library.

After some time Thomas Roth, primary libspdy author, responded and during our subsequent email exchange I’ve gotten a restored faith and belief in this library and its direction. Not only did he fix the C89 compliance pretty quickly, he is also promising rather big changes that are pending to get committed within a week or so.

Comforted by what I’ve learned from Thomas, I’ll wait for his upcoming changes and I’ll join the soon to be created mailing list for the libspdy project and I’ll contribute some ideas and efforts to help shape it into the fine SPDY library we all want. I can only encourage other fellow SPDY library interested persons to do the same!

Updated: Join the SPDY library development

8 Responses to “libspdy”

  1. Jeremiah Says:

    How does SPDY relate to protocol buffers? And aren’t there other protocols out there that compete with SPDY?

  2. Mark Nottingham Says:

    I think that the next few steps are going to be critical for SPDY; it’s easy to define one implementation and have good interop, but its future depends on the next few implementations that get traction.

    In particular, the APIs they choose will effectively profile the spec; they’ll define what interop is. This isn’t helped by the spec, which is pretty loose.

    Might be time to dust off my Python SPDY implementation and do it for real…

    Daniel, I’d also very interested in quantifying how well curl does pipelining; when I looked at browsers, it was really suboptimal across the board, with the exception of Patrick’s recent work in Firefox (still not out, but when it is, I expect it’s going to have pretty huge perf impact). E.g., I looked at it with htracr to identify how often and under what conditions pipelining took place.

    Jeremiah – Protocol Buffers is about as much of a competitor to SPDY as WebSocket is, or BEEP, or a thousand other proposals. The difference with SPDY is that it preserves the semantics of, and therefore compatibility with, HTTP — and that’s where the value is.

  3. daniel Says:

    In regards to SPDY APIs, I decided I want a library with a certain API “paradigm” that simply allows many independent streams that are multiplexed over the same physical one (which should make it fairly decent to use from within curl). I’ll see what Thomas might have in mind. I haven’t investigated what APIs Google or others provide.

    curl’s approach to HTTP pipelning is still very simplistic. If you enable pipelining, curl will basically pipeline everything possible to the same site (where site bascially is host + port combo). This ends up giving us a chicken-and-egg problem: because it is limited and not yet widely used, it has more bugs and minor quirks left and that prevents more users to use pipelining and then nobody works on improving/extending the API to make it really usable…

    From what I’ve understood, a “good” HTTP pipelining approach might still need N connections to distribute the requests over. Also, I’m not sure libcurl is used that often in such browser-like surroundings where pipelining causes the biggest gains.

    In my point of view, saturating a connection and avoiding RTT delays etc is in fact much easier done (implementation wise) with a many-channels-over-single-connection concept such as SPDY (and SCTP and SSH…) as it then allows the code maintain the same approach all the time without having to have special treatment for the pipelining case. Not that it is much to do about it now, since HTTP is what it is and it offers pipelning and the alternatives will take a very long time to reach a significant market share or importance…

  4. Mark Nottingham Says:

    Well, a ‘good’ HTTP pipelining approach definitely needs 1 + N, where N is the number of concurrent non-idempotent requests that are in flight.

    You might need more than one connection for idempotent requests, depending on things like:

    * slow server-side processing
    * large responses
    * overcoming limitations in TCP (such as initial congestion window)

    I’d note that SPDY faces the latter problem as well.

    This can be improved by signalling, so the client can make intelligent decisions about pipelining; some techniques are discussed in my pipeline draft.

    E.g., would you consider supporting 430 Would Block in libcurl? That would help in cases where the server knows it’s going to be expensive to serve a response; it’s true that it adds a round trip for that response (but not fast ones), but if it’s going to be expensive anyway, it might help (and the server could play tricks behind the scenes to get the response read, at least in cases where processing is the problem).

  5. daniel Says:

    I would love to have a better and more advance control over pipelines in libcurl, and supporting 430 Would Block would indeed be a very good idea then. With the current fairly limited single-pipe approach it probably will be hard though.

    I don’t have any particular plans myself at the moment to work on the pipelining parts of libcurl. I simply don’t have enough spare time and energy – and I’m not aware of anyone who’d pay for this feature. An ideal situation would involve a customer wanting this and paying someone to make it happen…

    I also feel a bit bad because I’m perfectly aware of your pipelining draft and I appreciate it a lot, but I’ve not really studied it in detail nor provided any feedback on it.

  6. Mark Nottingham Says:

    Don’t feel bad :)

  7. Ilya Grigorik Says:

    Daniel, about the “magic flags + pipelining”.. What would it take to make it transparent? As in, multiplexing is the very core of what SPDY offers, and it seems that the right default should be to have it “on”.

    Then again, I’m not sure how this could or should be reflected at the API layer: while we do have an upgrade path via SSL NPN, it seems like hiding SPDY behind an HTTP interface actually makes matters worse.

    I’ve been playing with Spdy (ruby parser), and also thinking about how to add support for it in em-http, and it’s a tricky problem. So far, I’m actually leaning towards an entirely new API and some easy way to switch to SPDY based on an NPN upgrade.

    P.S. libspdy looks great. In theory, we could also just bind directly against the client implementation in Chromium!

  8. daniel Says:

    My thoughts on SPDY for libcurl are still very early and far from being set in stone. The libcurl API is oriented around “requests” and yes we could indeed consider doing multiple simultaneous SPDY transfers use the same connection without any additional options being set, which as you say would be more SPDY-ish.

    I believe we should offer “raw” SPDY transfers as well as SPDY-upgrades from HTTP. But eventually it will depend a lot on what users of libcurl will use and work on.

    Chromium’s implementation is C++ which rules it out as a properly portably choice for me, and without checking very carefully I would also fear that it is too bound to other chromium code/dependencies.