Home > Software design >  Why Vert.x blocks event loop thread when using Oracle Reactive Client
Why Vert.x blocks event loop thread when using Oracle Reactive Client

Time:05-06

I try to user Vert.x Reactive Oracle Client version 4.2.6 to avoid blocking threads in event loop. I decided to test a really long query:

GlobalScope.launch(vertx.dispatcher()) {
            val result = hubConnPool.preparedQuery("""select * from MDM_OKATO_TT""")
                .execute()
                .onComplete { println("completed") }
                .onFailure { it.printStackTrace() }
}

But unfortunatelly I got such exceptions in my console:

[vertx-blocked-thread-checker] WARN io.vertx.core.impl.BlockedThreadChecker - Thread Thread[vert.x-eventloop-thread-1,5,main] has been blocked for 6866 ms, time limit is 2000 ms io.vertx.core.VertxException: Thread blocked at [email protected]/sun.nio.ch.SocketDispatcher.read0(Native Method) at [email protected]/sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:43) at [email protected]/sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:276) at [email protected]/sun.nio.ch.IOUtil.read(IOUtil.java:245) at [email protected]/sun.nio.ch.IOUtil.read(IOUtil.java:223) at [email protected]/sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:355) at app//oracle.net.nt.TimeoutSocketChannel.read(TimeoutSocketChannel.java:416) at app//oracle.net.ns.NSProtocolNIO.doSocketRead(NSProtocolNIO.java:1119) at app//oracle.net.ns.NIOPacket.readHeader(NIOPacket.java:267) at app//oracle.net.ns.NIOPacket.readPacketFromSocketChannel(NIOPacket.java:199) at app//oracle.net.ns.NIOPacket.readFromSocketChannel(NIOPacket.java:141) at app//oracle.net.ns.NIOPacket.readFromSocketChannel(NIOPacket.java:114) at app//oracle.net.ns.NIONSDataChannel.readDataFromSocketChannel(NIONSDataChannel.java:98) at app//oracle.jdbc.driver.T4CMAREngineNIO.prepareForUnmarshall(T4CMAREngineNIO.java:834) at app//oracle.jdbc.driver.T4CMAREngineNIO.unmarshalUB1(T4CMAREngineNIO.java:487) at app//oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:623) at app//oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:299) at app//oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:512) at app//oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:163) at app//oracle.jdbc.driver.T4CPreparedStatement.fetch(T4CPreparedStatement.java:1467) at app//oracle.jdbc.driver.OracleStatement.fetchMoreRows(OracleStatement.java:4127) at app//oracle.jdbc.driver.InsensitiveScrollableResultSet.fetchMoreRows(InsensitiveScrollableResultSet.java:924) at app//oracle.jdbc.driver.InsensitiveScrollableResultSet.fetchNextRows(InsensitiveScrollableResultSet.java:831) at app//oracle.jdbc.driver.InsensitiveScrollableResultSet.absoluteInternal(InsensitiveScrollableResultSet.java:803) at app//oracle.jdbc.driver.InsensitiveScrollableResultSet.next(InsensitiveScrollableResultSet.java:504) at app//io.vertx.oracleclient.impl.commands.QueryCommand.decodeResultSet(QueryCommand.java:216) at app//io.vertx.oracleclient.impl.commands.QueryCommand.decode(QueryCommand.java:165) at app//io.vertx.oracleclient.impl.commands.OraclePreparedQuery.lambda$doExecute$0(OraclePreparedQuery.java:77) at app//io.vertx.oracleclient.impl.commands.OraclePreparedQuery$$Lambda$242/0x0000000100369440.apply(Unknown Source) at app//io.vertx.core.impl.future.Composition.onSuccess(Composition.java:38) at app//io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60) at app//io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211) at app//io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23) at app//io.vertx.oracleclient.impl.Helper$1.lambda$onNext$0(Helper.java:94) at app//io.vertx.oracleclient.impl.Helper$1$$Lambda$259/0x0000000100391440.handle(Unknown Source) at app//io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:100) at app//io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:63) at app//io.vertx.core.impl.EventLoopContext.lambda$runOnContext$0(EventLoopContext.java:38) at app//io.vertx.core.impl.EventLoopContext$$Lambda$121/0x000000010023fc40.run(Unknown Source) at app//io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164) at app//io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469) at app//io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:503) at app//io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986) at app//io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) at app//io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)

So far I'm using JDBC Client running by WorkerExecutor, I hoped that by using reactive client I can simplify code but now i'm discouraged. Can you suggest me please what I am doing wrong or misunderstood. Thank you.

CodePudding user response:

I guess the problem is that the hubConnPool.preparedQuery() function is not suspend and it blocks the current thread. You can wrap it in withContext(Dispatchers.IO) function to switch context to background thread:

GlobalScope.launch(vertx.dispatcher()) {
        val result = withContext(Dispatchers.IO) { 
            hubConnPool.preparedQuery("""select * from MDM_OKATO_TT""")
                .execute()
                .onComplete { println("completed") }
                .onFailure { it.printStackTrace() }
        }
}

CodePudding user response:

This is a bug in the Vert.x Reactive Oracle Client, unfortunately. I've filed https://github.com/eclipse-vertx/vertx-sql-client/issues/1188

Thanks for sharing your findings.

  • Related