You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It is common for client libraries to have some kind of Connection struct,
which have various protocol-related methods, ex. abstract client (let's say, redis-like) can have methods like these:
Speaking about Service again, with a current futures crate (0.1.20 as for now) it is hard to implement call method.
For example, if Connection struct contains Framed<_, _> in it, it's own sink method can be used to send incoming request to an underline framed object, ex.:
struct Connection {
inner: Framed<TcpStream, MyCodec>
}
fn call(&mut self, req: Self::Request) -> Self::Future {
self.inner.send(req);
// and return a result
}
Two caveats appear here:
futures::Sink::send is moving Self, which is okay by itself, but became a problem if you still want to keep it in the Connection;
call should return future that will resolve into MyResponse later, but it can't be achieved easily; inner Framed<_, _>, as a stream, should be polled somehow and somewhere and should resolve returned earlier future (MyResponseFuture in an example above).
@benashford have a redis-async-rs crate, which solves second problem via multiple channels: MyResponseFuture in that case contains oneshot::Receiver<MyResponse> and Connection by itself polls inner stream and keeping track of the oneshot::Sender<MyResponse> instances.
While it seems to solve the problem, it looks kinda complicated and might reduce tokio + tower expansion.
Can we elaborate here and provide more complex examples of how clients should be done properly?
AFAIR, there were examples of the pipelined and multiplexed protocols at the tokio repo earlier, maybe we can do something similar?
I'm not sure how exactly can I help here, but I'm willing too, just give me a hint :)
The text was updated successfully, but these errors were encountered:
It is common for client libraries to have some kind of
Connection
struct,which have various protocol-related methods, ex. abstract client (let's say, redis-like) can have methods like these:
If that
Connection
implementstower::Service
trait, it should providecall
method, ex.Hard part here is that current tokio implementation is not very easy; at least as for me and for a other random people from the internet:
Speaking about
Service
again, with a currentfutures
crate (0.1.20 as for now) it is hard to implementcall
method.For example, if
Connection
struct containsFramed<_, _>
in it, it's own sink method can be used to send incoming request to an underline framed object, ex.:Two caveats appear here:
Self
, which is okay by itself, but became a problem if you still want to keep it in theConnection
;call
should return future that will resolve intoMyResponse
later, but it can't be achieved easily; innerFramed<_, _>
, as a stream, should bepoll
ed somehow and somewhere and should resolve returned earlier future (MyResponseFuture
in an example above).@benashford have a redis-async-rs crate, which solves second problem via multiple channels:
MyResponseFuture
in that case containsoneshot::Receiver<MyResponse>
andConnection
by itselfpoll
s inner stream and keeping track of theoneshot::Sender<MyResponse>
instances.While it seems to solve the problem, it looks kinda complicated and might reduce tokio + tower expansion.
Can we elaborate here and provide more complex examples of how clients should be done properly?
AFAIR, there were examples of the pipelined and multiplexed protocols at the tokio repo earlier, maybe we can do something similar?
I'm not sure how exactly can I help here, but I'm willing too, just give me a hint :)
The text was updated successfully, but these errors were encountered: