tonic icon indicating copy to clipboard operation
tonic copied to clipboard

"Service was not ready: transport error" when making gRPC request.

Open boxme opened this issue 11 months ago • 2 comments

Bug Report

Encounter "Service was not ready: transport error" when making gRPC requests on from a client. The client was cloned before each request.

Version

tonic = "0.12"

Description

A grpc client was created at startup before serving my backend APIs. There are a bunch of setups but the following highlighted the gRPC client setup:

pub struct Router {
    pub gprc_client: Arc<MygRpcClient>,
    ....
}

fn main() {
    let router = {
        let rt = tokio::runtime::Builder::new_multi_thread()
            .enable_all()
            .worker_threads(config.thread_config.total_thread_count)
            .build()
            .unwrap();

        rt.block_on(async move {
            let client = get_grpc_client("https://rtse-api-service.rtse.svc.cluster.local/").await.unwrap()
            let router = Router {
                gprc_client: Arc::new(client),
            };

            router
        })
    };

    let rt = tokio::runtime::Builder::new_multi_thread()
        .enable_all()
        .worker_threads(5)
        .build()
        .unwrap();

   rt.block_on(run_api(router)).unwrap();
}

async fn get_grpc_client(url: String) -> Option<MygRpcClient> {
    let channel = Endpoint::from_shared(url);
    match channel {
        Ok(endpoint) => Some(
            MyServiceClient::new(endpoint.connect_lazy())
                .accept_compressed(tonic::codec::CompressionEncoding::Zstd)
                .send_compressed(tonic::codec::CompressionEncoding::Zstd),
        ),
        Err(_) => None,
    }
}

For each request I am cloning the client in order to handle concurrent request:

pub async fn handle_request(&self) {
    ...
    let gprc_client = (*self.gprc_client).clone();
    let request =  Request::new(GetRequest {
        param_a: ...,
        param_b: ...,
    });

    let result = gprc_client.handle_grpc_request(request).await;

    match result {
        Ok(result) =>  {
            ...
        },
        Err(err) => {
            let error_code = err.code();
            let error_message = err.message();

            // Got Error: Unknown error: Service was not ready : transport error
            log::error!("Got Error: {error_code} : {error_message}");
        }
    }
}

Could someone help me understand this error better? Thanks!

boxme avatar Jan 13 '25 16:01 boxme

try calling grpc_client.ready().await;

LucioFranco avatar Jan 23 '25 15:01 LucioFranco

@LucioFranco I ran into a similar issue but ready is not an available method. Any other ideas?

dummyhs12341234 avatar Feb 11 '25 18:02 dummyhs12341234