I'm using vert.x 3.5.1. I've built a streaming API in which I get events from a third-party lib and write the strings in the response for each request. This is part of my final handler:
rc.response().write("{json of each event}");
We don't end the response at any time since it's a streaming API with keep-alive. When something happens with the client connection, we often get a Connection reset by peer:
2018-04-10 11:23:15 SEVERE [io.vertx.core.net.impl.ConnectionBase] Unhandled exception
java.io.IOException: Connection reset by peer
at sun.nio.ch.FileDispatcherImpl.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
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:126)
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)
That's fine since I managed to catch that via the connection exceptionHandler:
rc.request().connection().exceptionHandler()
I'm probably writing more than my client can consume, the buffers will be queued -- I suppose -- but I can't pause or degrade the stream like this doc suggests: http://vertx.io/docs/vertx-core/java/#streams
The real problem comes next, that exceptionHandler -- or just the log.error("Unhandled exception", t) from ConnectionBase -- is called thousands of times, CPU spikes, threads start to block and eventually I get a OutOfMemory. Is there a way
I can stop that behaviour as soon as I catch the first exception? Maybe closing or cleaning up the buffer queue in the response. I've tried a couple of calls but none seemed to work.
I appreciate any help on this.