mirror of
https://github.com/OMGeeky/tarpc.git
synced 2026-01-07 03:56:48 +01:00
Add back the Client trait, renamed Stub.
Also adds a Client stub trait alias for each generated service. Now that generic associated types are stable, it's almost possible to define a trait for Channel that works with async fns on stable. `impl trait in type aliases` is still necessary (and unstable), but we're getting closer. As a proof of concept, three more implementations of Stub are implemented; 1. A load balancer that round-robins requests between different stubs. 2. A load balancer that selects a stub based on a request hash, so that the same requests go to the same stubs. 3. A stub that retries requests based on a configurable policy. The "serde/rc" feature is added to the "full" feature because the Retry stub wraps the request in an Arc, so that the request is reusable for multiple calls. Server implementors commonly need to operate generically across all services or request types. For example, a server throttler may want to return errors telling clients to back off, which is not specific to any one service.
This commit is contained in:
@@ -276,6 +276,7 @@ pub fn service(attr: TokenStream, input: TokenStream) -> TokenStream {
|
||||
ServiceGenerator {
|
||||
response_fut_name,
|
||||
service_ident: ident,
|
||||
client_stub_ident: &format_ident!("{}Stub", ident),
|
||||
server_ident: &format_ident!("Serve{}", ident),
|
||||
response_fut_ident: &Ident::new(response_fut_name, ident.span()),
|
||||
client_ident: &format_ident!("{}Client", ident),
|
||||
@@ -432,6 +433,7 @@ fn verify_types_were_provided(
|
||||
// the client stub.
|
||||
struct ServiceGenerator<'a> {
|
||||
service_ident: &'a Ident,
|
||||
client_stub_ident: &'a Ident,
|
||||
server_ident: &'a Ident,
|
||||
response_fut_ident: &'a Ident,
|
||||
response_fut_name: &'a str,
|
||||
@@ -461,6 +463,9 @@ impl<'a> ServiceGenerator<'a> {
|
||||
future_types,
|
||||
return_types,
|
||||
service_ident,
|
||||
client_stub_ident,
|
||||
request_ident,
|
||||
response_ident,
|
||||
server_ident,
|
||||
..
|
||||
} = self;
|
||||
@@ -490,6 +495,7 @@ impl<'a> ServiceGenerator<'a> {
|
||||
},
|
||||
);
|
||||
|
||||
let stub_doc = format!("The stub trait for service [`{service_ident}`].");
|
||||
quote! {
|
||||
#( #attrs )*
|
||||
#vis trait #service_ident: Sized {
|
||||
@@ -501,6 +507,15 @@ impl<'a> ServiceGenerator<'a> {
|
||||
#server_ident { service: self }
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = #stub_doc]
|
||||
#vis trait #client_stub_ident: tarpc::client::stub::Stub<Req = #request_ident, Resp = #response_ident> {
|
||||
}
|
||||
|
||||
impl<S> #client_stub_ident for S
|
||||
where S: tarpc::client::stub::Stub<Req = #request_ident, Resp = #response_ident>
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -689,7 +704,9 @@ impl<'a> ServiceGenerator<'a> {
|
||||
#[derive(Clone, Debug)]
|
||||
/// The client stub that makes RPC calls to the server. All request methods return
|
||||
/// [Futures](std::future::Future).
|
||||
#vis struct #client_ident(tarpc::client::Channel<#request_ident, #response_ident>);
|
||||
#vis struct #client_ident<
|
||||
Stub = tarpc::client::Channel<#request_ident, #response_ident>
|
||||
>(Stub);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -719,6 +736,17 @@ impl<'a> ServiceGenerator<'a> {
|
||||
dispatch: new_client.dispatch,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Stub> From<Stub> for #client_ident<Stub>
|
||||
where Stub: tarpc::client::stub::Stub<
|
||||
Req = #request_ident,
|
||||
Resp = #response_ident>
|
||||
{
|
||||
/// Returns a new client stub that sends requests over the given transport.
|
||||
fn from(stub: Stub) -> Self {
|
||||
#client_ident(stub)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -741,7 +769,11 @@ impl<'a> ServiceGenerator<'a> {
|
||||
} = self;
|
||||
|
||||
quote! {
|
||||
impl #client_ident {
|
||||
impl<Stub> #client_ident<Stub>
|
||||
where Stub: tarpc::client::stub::Stub<
|
||||
Req = #request_ident,
|
||||
Resp = #response_ident>
|
||||
{
|
||||
#(
|
||||
#[allow(unused)]
|
||||
#( #method_attrs )*
|
||||
|
||||
Reference in New Issue
Block a user