Open ColonelThirtyTwo opened 4 years ago
FYI I haven't tested this too hardly yet, but I'm planning on working on a project that makes use of this crate on WASM, so that should exercise all the functionality.
Wow! Thanks for the PR! This is pretty big. So does this allow implementing/creating your own Sender
as discussed in #281?
I tried updating to futures 0.3 yesterday and it is a doozy... I wonder if this could help? Would it be crazy if we just remove sync sender now that async
/await
is stable? I digress and I'll open a different issue to discuss further.
Yes, you can implement your own sender in your own crate. Example for wasm using stdweb: https://gitlab.com/colonelthirtytwo/elastic-stdweb-rs
IMO I'd rather keep syncsender around; tokio and the async stuff is a bit heavy and I would not be surprised if people would not want to include all that.
Any chance you can rebase this onto master so we can run the tests? I assume they might need to be updated too?
Could do. Just wanted a look-over of the code beforehand in case I had to change anything.
One issue I've noticed is that since send
is now implemented on RequestBuilder
, there is no documentation for send
on the request type's pages, which isn't very helpful.
~...and now with the new version, cargo keeps pulling in reqwests even with default-features: false
set... humm~ Nevermind my fault with a dependency.
I am just now starting to look more at this and I have a few initial questions:
Sender
& TypedSender<TReqInner>
traits? It will just be the Sender
trait with an associated type that indicates the type of the sender (WASM vs async etc.)sync-sender
the default and just make async-sender
the default? reqwest
is going this route with their next breaking change release (see: https://github.com/seanmonstar/reqwest/commit/7e3c1bc461dd51a9b59ca6b06b82e1699cc1a1ce). Our next release v0.21.0
will have a few breaking changes in it already. Granted this would be a much bigger breaking change but might be worth it? I guess it doesn't pull in any extra dependencies so it might not matter?I'll add more to my review asap...
Sender
trait could have a type InProgressResponse<Response>;
, which is Result<Response, Error>
for SyncSender
, Pending<Response>
for AsyncSender
, and Promise<Response, Error>
for StdwebSender
. Then typed_send
could be moved to the Sender
trait and return Self::InProgressResposne<SomeResponseType>
.#[tokio::main]
or #[runtime::main]
—assuming the prerequisite dependencies are all downloaded and in order) and then using async/await. I bet their thinking is that while it is a bit more annoying, it kinda forces the ecosystem into using async I/O which is a benefit in performance and utility in the long run...? But I can't speak for the reqwest
devs of course.
Allows external crates to write their own
Sender
implementations and use them withClient
.This involved refactoring a decent amount of the crate, and probably has some backwards-incompatible changes. I didn't change any of the usual APIs though; most code that just does querying should still work.
The primary impetus of this change is getting this crate to work in WebAssembly. In that environment, requests must be made via the
XMLHttpRequest
API, and this crate must return JS promises. I have written such a backend, which serves as an example; code is here: https://gitlab.com/colonelthirtytwo/elastic-stdweb-rsMajor changes off the top of my head, see commits for more details:
TypedSender<TReqInner>
, a subtrait ofSender
that all backends should implement for allT: ReqInner
. This handles deserializing the response from the backend once it is available (ex. usingResult.map
forSyncSender
,Future::map
forAsyncSender
, andPromise::then
forStdwebSender
). The response type (an associated type of the trait) has to vary depending on the type being deserialized, hence why this is a separate trait fromSender
. Once Generic Associated Types are stabilized, the trait can be merged intoSender
.SyncSender
andAsyncSender
into one that uses theTypedSender
. Rust orphaning rules would forbid implementingRequest<MySender>
in external crates, so that approach would not scale.Sender
field fromSniffedNodes
and replace it with an API that was not responsible for fetching the request, since how to fetch the request would change based on backend.NextParams
trait and move its functionality toSender::next_params
.TypedSender
.SyncSender
,AsyncSender
, and related code are now behind cargo features, allowing this crate to be built without them (default is to include both, for backwards compatibility). WASM needs this, since the reqwest-based senders won't even build for that target.Fixes #281