在一台 tonic 服务器中将不同的层应用于不同的服务

问题描述 投票:0回答:1

我有两个版本的图层,

EndpointTimer_1
EndpointTimer_2
,它们跟踪的指标略有不同。我希望将
EndpointTimer_1
应用于
Server_1
,并将
EndpointTimer_2
应用于
Server_2

使用通用 ServerBuilder 对象来实现此目的的正确方法是什么?目前我有类似的东西

use tonic::transport::Server;

let mut server_builder = Server::builder()
    .layer(EndpointTimerLayer::new())
    .layer(ConcurrencyGaugeLayer::new());

let provider_1 = provider_1_impl::new(&CONFIG)?;
let provider_2 = provider_2_impl::new(&CONFIG)?;
let router = server_builder
    .add_service(Server_1::new(provider_1))
    .add_service(Server_2::new(provider_2));
router.serve(addr).await?;

想要类似的东西

use tonic::transport::Server;

let mut server_builder = Server::builder()
    .layer(ConcurrencyGauge::new());

let provider_1 = provider_1_impl::new(&CONFIG)?;
let provider_2 = provider_2_impl::new(&CONFIG)?;
let router = server_builder
    .add_service(Server_1::new(provider_1).layer(EndpointTimerLayer_1::new())
    .add_service(Server_2::new(provider_2).layer(EndpointTimerLayer_2::new());
router.serve(addr).await?;

但我无法找出使其发挥作用的正确方法。

rust rust-tonic
1个回答
0
投票

进行了大量的实验和阅读 tonic 源代码,我仍然有一些不明白的东西,但功能性的答案是首先,为每一层实现

NamedService
特征:

use tonic::transport::server::NamedService;

impl<T> NamedService for EndpointTimer_1<T>
where
    T: NamedService,
{
    const NAME: &'static str = T::NAME;
}

注意,图层服务的错误类型必须是

Infallible
,例如

use std::convert::Infallible;

impl<T, RequestBody, ResponseBody> Service<tonic::codegen::http::Request<RequestBody>>
    for EndpointTimer_1<T>
where
    T: Service<
            tonic::codegen::http::Request<RequestBody>,
            Response = tonic::codegen::http::Response<ResponseBody>,
            Error = Infallible,
        > + Send,

而不是提供的示例

type Error = Box<dyn Error + Send + Sync>;
。 AFAICT 这是可行的,因为 protobuf 生成的服务器也是
Infallible
?不确定,希望知情者对此进行解释。

最后,可以通过单独分层包装服务来注册服务:

let mut server_builder = Server::builder()
    .layer(ConcurrencyGauge::new());

let provider_1 = provider_1_impl::new(&CONFIG)?;
let server_1 = Server_1::new(provider_1);

let provider_2 = provider_2_impl::new(&CONFIG)?;
let server_2 = Server_2::new(provider_2);


let router = server_builder
    .add_service(EndpointTimer_1::new(Server_1))
    .add_service(EndpointTimer_2::new(Server_2));
router.serve(addr).await?;
© www.soinside.com 2019 - 2024. All rights reserved.