NewJ
NewJ

Reputation: 389

GRPC connection state listeners Java

I'm interesting - could i have some notifies about connection/disconnection events for GRPC client/server? Now, when client terminates connection to server i'm getting exception on server:

июн 22, 2018 9:34:47 AM io.grpc.netty.NettyServerTransport notifyTerminated
INFO: Transport failed
java.io.IOException: Удаленный хост принудительно разорвал существующее подключение
    at sun.nio.ch.SocketDispatcher.read0(Native Method)
    at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:43)
    at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)
    at sun.nio.ch.IOUtil.read(IOUtil.java:192)
    at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380)
    at io.netty.buffer.PooledUnsafeDirectByteBuf.setBytes(PooledUnsafeDirectByteBuf.java:288)
    at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1108)
    at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:345)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.lang.Thread.run(Thread.java:745)

Exception translate: "The remote host forcibly broke the existing connection"

I'm interesting, how could i manage connect/disconnect events both for client and server?

Maybe there is some ways to attach my own listener to client or server? From sources i didn't figure out how to make it

Upvotes: 5

Views: 3246

Answers (2)

Chris Jansson
Chris Jansson

Reputation: 65

From the client side, you can use the Channel State API to monitor your channel state in real time.

Since notifyWhenStateChanged only registers a one-off callback, you can set it up inside a Runnable that re-registers itself after each state change.

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        ConnectivityState currentState = channel.getState(true);
        log.info("Channel state: ", currentState);
        channel.notifyWhenStateChanged(currentState, this);
    }
};

channel.notifyWhenStateChanged(ConnectivityState.CONNECTING, runnable);

Upvotes: 0

Eric Anderson
Eric Anderson

Reputation: 26394

gRPC does not provide, on purpose, connection-level notifications. You don't mention your use-case, but the vast majority of use-cases are broken by load balancing, proxies, and gRPC's reconnect logic.

There is a way to determine whether a Channel is healthy, via ManagedChannel.getState(false), which can be useful to provide a UI for users or to tell other clients the server is not healthy. Other use cases should be built on individual RPCs.

Upvotes: 2

Related Questions