4
votes

I am using grpc to communicate between a Java server and node client. When either of them die/crash the other dies to.

Here is the exception thrown on Java server when node client dies -

Nov 08, 2016 11:28:03 AM io.grpc.netty.NettyServerHandler onConnectionError
WARNING: Connection Error
java.io.IOException: An existing connection was forcibly closed by the remote host
    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:1100)
    at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:349)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:112)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:571)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:512)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:426)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:398)
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:877)
    at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
    at java.lang.Thread.run(Thread.java:745)

Here is the exception thrown on node when java dies:

events.js:141
      throw er; // Unhandled 'error' event
      ^
Error: {"created":"@1478623914.082000000","description":"An existing connection was forcibly closed by the remote     host.\r\n","file":"..\src\core\lib\iomgr\tcp_windows.c","file_line":171,"grpc_status":14}    
    at ClientReadableStream._emitStatusIfDone (    C:\HarshalDev\Live_TDFX\TDSL0007-TDFXPlatfo    rmsDesignandBuild\tdfxlive\node_modules\grpc\src\node\src\client.js:189:19)
    at ClientReadableStream._receiveStatus (C:\    HarshalDev\Live_TDFX\TDSL0007-TDFXPlatformsDesignandBuild\tdfxlive\node_modules\grpc\src\node\src\client.js:169:8)
    at C:\HarshalDev\Live_TDFX\TDSL0007-TDFXPlatformsDesignandBuild\tdfxlive\node_modules\grpc\src\node\src\client.js:577:14
[nodemon] app crashed - waiting for file changes before starting...

QUESTION - How do I handle those exceptions?

I tried without any success adding try/catch and adding a uncaught exception handlers for threads.

Java code to initialize -

ServerBuilder<?> serverBuilder = ServerBuilder.forPort(getPort());
server = serverBuilder
        .addService(createBwayStreamingService())
        .addService(ServerInterceptors.intercept(createBwayOrderService(), authServerInterceptor))
        .addService(createBwayInstrumentService())
        .addService(createBwaySettlementService())
        .addService(createBwayDateTimeService())
        .addService(ServerInterceptors.intercept(createBwayConfService(), authServerInterceptor))
        .addService(ServerInterceptors.intercept(createBwayTradeService(), authServerInterceptor))
        .addService(ServerInterceptors.intercept(createBwayAuthService(), authServerInterceptor))
        .build();
Preconditions.checkNotNull(server);
server.start();
System.out.println("Server started, listening on " + getPort());
Runtime.getRuntime().addShutdownHook(new Thread() {
    @Override
    public void run() {
        System.out.println("Shutting down gRPC server");
        TocGateway.this.stop();
        System.out.println("Server shut down");
    }
});
server.awaitTermination();

Node client handler (one of the services, all other services use the same pattern) -

let protoDescriptorStreaming = grpc.load((process.env.FX_LIVE_PROTO_DIR || '../tocGateway/src/main/proto') + '/streaming.proto');
let streamingService = new protoDescriptorStreaming.tds.fxlive.bway.BwayStreamService(process.env.TOC_GATEWAY_ADDRESS || 'localhost:8087', grpc.credentials.createInsecure());
1

1 Answers

2
votes

The Java warning is harmless. Your application should continue running normally after the exception. It would be nice to reduce the log level to have less logspam, but it also shouldn't impact the correctness of your application.