bidirectional gRPC server with maxConnectionIdle

167 views
Skip to first unread message

airas yaqub

unread,
Aug 30, 2023, 8:45:11 AM8/30/23
to grpc.io
Hi, we have a bidirectional java gRPC server & we are using NettyServerBuilder to configure the server. I have read all the docs in order to implement the ping/pong mechanism for the gRPC connection. Below is our server config 

server code: 

((NettyServerBuilder) serverBuilder)
        .executor(executor)
        //Allow client pings even if no ongoing calls are happening (default is false)
        .permitKeepAliveWithoutCalls(true)
        //Least keep alive time allowed for clients to configure
        .permitKeepAliveTime(10,TimeUnit.SECONDS)
        //How long a channel can stay idle (idle means no pings & messages received)
        .maxConnectionIdle(5,TimeUnit.SECONDS)
        //How long a channel can stay at all (even if not idle)
        .maxConnectionAge(1,TimeUnit.MINUTES)
        //Grace period after the channel ends
        .maxConnectionAgeGrace(10,TimeUnit.SECONDS)
        //Max payload size
        .maxInboundMessageSize(Integer.MAX_VALUE)
        //Max headers size
        .maxInboundMetadataSize(Integer.MAX_VALUE);
}


client code:

ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50004)
        .usePlaintext()
        .keepAliveTime(30, TimeUnit.SECONDS)
        .keepAliveTimeout(5, TimeUnit.SECONDS)
        .keepAliveWithoutCalls(true)
        .build();

FabricGrpc.FabricStub stub = FabricGrpc.newStub(channel);

Metadata headers = new Metadata();
headers.put(Metadata.Key.of("userId", Metadata.ASCII_STRING_MARSHALLER), identificationInputs[0]);
FabricGrpc.FabricStub stubWithHeaders = MetadataUtils.attachHeaders(stub, headers);

StreamObserver<Envelope> observer = stubWithHeaders.biDiEnvelopeChannel(new StreamObserver<Envelope>() {
    @Override
    public void onNext(Envelope value) {
        System.out.println("Received message =====> " + value + " ******* ");
    }

    @Override
    public void onError(Throwable t) {
        System.out.println("error on grpc client: " + t.getMessage());
    }

    @Override
    public void onCompleted() {

    }
});


what we need is if the connection is idle for a given time, the server should kill the connection. But I think I am not getting how maxConnectionIdle actually works. My previous thought was a connection is idle from the server's perspective if it does not get any message or ping, but then I read this line in the doc " Idleness duration is defined since the most recent time the number of outstanding RPCs became zero or the connection establishment" which I guess means that not any ongoing RPC calls should be there in order to consider a connection as idle. But since it's a bidirectional RPC call, it will be long-lived obviously. 

Right now maxConnectionAge is working fine, but how can we configure idle connection on a server with bidirectional RPC. Meaning if the server does not get a ping or any message in a given time frame, it will consider that connection as idle & will terminate it.   

airas yaqub

unread,
Aug 30, 2023, 9:00:55 AM8/30/23
to grpc.io
I think current options are only for unary RPC done on a channel, but in the case of bidirectional streaming, we have a channel where a long-lived bidirectional RPC is made & within that RPC connection, we send messages. But these server options do not take account of the stream messages, they only consider RPC calls. correct me guys if I am wrong in my understanding.

sanjay...@google.com

unread,
Aug 31, 2023, 12:43:25 AM8/31/23
to grpc.io
Yes, your understanding is correct. If a connection has an active bi-di call and even if there is no activity in that call gRPC will keep the connection active using PING frames. It is alluded to in this spec . Hope that answers your questions.

airas yaqub

unread,
Aug 31, 2023, 3:50:25 AM8/31/23
to grpc.io
Hey Sanjay, thanks for replying. So I have a follow-up question now, 

  • My client code is configured with a keepalive time of 30sec, so is there a config on the server side that says "cancel connection if I do not receive ping in given time"? Previously I thought maxConnectionIdle on the server side would do the trick but it did not work due to the reason mentioned above i.e. idle in maxConnectionIdle means there is no ongoing RPC call, but in bidi, RPC call will always be there as a persistent connection. 

sanjay...@google.com

unread,
Aug 31, 2023, 5:41:47 PM8/31/23
to grpc.io
Hi,

Are you thinking of the case where the client has died or otherwise has lost connectivity? Note that a broken TCP connection will be detected on the server side and will do the necessary clean up. If that's not your case please describe what your use-case is.

Arpita Chattopadhyay

unread,
Aug 31, 2023, 5:50:45 PM8/31/23
to sanjay...@google.com, grpc.io
Is there a good documentation around the broken TCP connection detected by server side and if we can inject specific cleanup methods like clean up cache etc


Sent from my iPhone

On Aug 31, 2023, at 2:41 PM, 'sanjay...@google.com' via grpc.io <grp...@googlegroups.com> wrote:

Hi,
--
You received this message because you are subscribed to the Google Groups "grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email to grpc-io+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/grpc-io/7f158458-e3ec-4123-9dd4-9de5988a859cn%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages