Skip to content
This repository has been archived by the owner on Feb 14, 2023. It is now read-only.

Support async Hyper #40

Open
abonander opened this issue Jun 11, 2016 · 6 comments
Open

Support async Hyper #40

abonander opened this issue Jun 11, 2016 · 6 comments

Comments

@abonander
Copy link
Owner

This might necessitate creating a new crate architected around async requests.

@e00E
Copy link

e00E commented Jun 25, 2017

@abonander
As far as I can tell Hyper is now async and I cannot use this crate with it anymore, is that correct?

@abonander
Copy link
Owner Author

It still works with Hyper 0.10 and below. I am working on a version that supports asynchronous requests but I'm not sure if I want to publish it as a separate crate or what. I can make everything work in the same crate and it can share a lot of code, which is a big plus. The downside is that, to support two different versions of Hyper I will have to move one to a separate crate. I was actually thinking of just moving all integrations to a separate crate, in fact.

This is what I've been thinking:

  • Keep multipart as the core crate, supporting client and server with an agnostic API, i.e.:

    • the client API generates a readable body or takes a Write impl, and provides the boundary to be manually added to the request

    • the server API takes a boundary and a Read impl and yields entries (as it does now)

    • asynchronous versions of both using futures::Stream

  • multipart-legacy: support for Hyper synchronous (< 0.11 and whatever synchronous wrapper they're planning on introducing in the future), Iron, tiny-http, and possibly Nickel (though probably will keep that in multipart-nickel), using extension traits to add conveniences to the multipart API

  • multipart-async: support for Hyper async (>= 0.11) and other asynchronous crates that might appear later

@chpio
Copy link
Contributor

chpio commented Jun 26, 2017

Keep multipart as the core crate, supporting client and server with an agnostic API, i.e...

cool, i thought about that too, i had started a toy project for that

multipart-legacy: support for Hyper synchronous (< 0.11 and whatever synchronous wrapper they're planning on introducing in the future), Iron, tiny-http, and possibly Nickel (though probably will keep that in multipart-nickel), using extension traits to add conveniences to the multipart API

is this really necessary? if anyone needs legacy support they can just use an old version of multipart, also that's why we use SemVer.

multipart-async: support for Hyper async (>= 0.11) and other asynchronous crates that might appear later

why not call it "multipart-hyper"? 1. async is an essential part of the "new" hyper, so it shouldn't be part of the name 2. the implementation agnostic stuff is already in the multipart crate

@abonander
Copy link
Owner Author

abonander commented Jun 26, 2017

is this really necessary? if anyone needs legacy support they can just use an old version of multipart, also that's why we use SemVer.

The issue with having legacy users "just use an old version" is that they won't get any performance improvements or bugfixes, or backwards-compatible API improvements, without an additional effort to backport them. With all unstable public dependencies relegated to the legacy crate, the core crate can reach 1.0 relatively quickly, and then the legacy crate can be set at multipart = "^1.0" which will automatically get all future backwards-compatible upgrades.

Alternately, it could be multipart-sync to imply integration with synchronous APIs as compared to multipart-async. However, I'm not sure if there's going to be a whole load of new developments in this space, thus why I chose the term "legacy". We might see synchronous wrapper-crates, but those would be higher-level than multipart and I would expect them to abstract over both the underlying HTTP crate and multipart itself.

why not call it "multipart-hyper"?

Because the point isn't specific crate integrations, it's support for the paradigm. Any future async HTTP crates should be easy to integrate even if they have a callback-style API instead of a futures-based one. One of the conveniences I plan to provide for the asynchronous API is some sort of background file loader since blocking operations shouldn't occur within event loops, and that could be shared by all asynchronous integrations.

Also, because I don't want to publish separate crates for every integration. Nickel is a special-case for reasons outlined in #72.

@chpio
Copy link
Contributor

chpio commented Jun 27, 2017

The issue with having legacy users "just use an old version" is that they won't get any performance improvements or bugfixes, or backwards-compatible API improvements, without an additional effort to backport them. With all unstable public dependencies relegated to the legacy crate, the core crate can reach 1.0 relatively quickly, and then the legacy crate can be set at multipart = "^1.0" which will automatically get all future backwards-compatible upgrades.

yeah, but you could just let them use an "older" SemVer-version and backport feature (i don't know how as i assume the code for async and sync is very different)/fix bugs for that version (say 1.x being the async version and 0.x the sync; and on the dev side sync branch for the 0.x/sync version and master branch for the 1.x/async part). Also they wouldn't need to "upgrade" to another crate.

cause the point isn't specific crate integrations, it's support for the paradigm.

ok, so "mutlipart" would contain some shared code which can be used for the async and the sync crate.

Also, because I don't want to publish separate crates for every integration. Nickel is a special-case for reasons outlined in #72.

Ok

@abonander
Copy link
Owner Author

abonander commented Jun 27, 2017

1.x can't be the async version as it would still expose public dependencies that are not yet 1.x (futures and mime, namely). Backporting is a bit of a pain, especially if the internals changed between releases. It's not always as simple as cherry-picking commits. And I intend that migrating to the new crates should be relatively painless, with future upgrades being done automatically.

What code I intend to share between async and sync is still up in the air. They would mostly just use type definitions from the main crate and maybe some internals, but otherwise would be mostly independent. I could just create a new crate entirely built around asynchronous HTTP, that was the original idea. It's seeming simpler at this point.

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

No branches or pull requests

3 participants