IllegalReferenceCountException followed by HTTP/1.1 crash

Hello,

I’m trying to add logic in my gatling performance script where the scenario is exited when a failure is detected. The way I am exiting the scenario at the moment is by using the session.exit() method. However, doing so I am getting the following error:

`
16:10:12.293 [gatling-http-1-1][ERROR][Action.scala:71] i.g.c.a.b.SessionHookBuilder$$anon$1 - ‘hook-1’ crashed with ‘i.n.u.IllegalReferenceCountException: refCnt: 0, decrement: 1’, forwarding to the next one
16:10:12.293 [gatling-http-1-7][ERROR][HttpAppHandler.java:85] i.g.h.c.i.HttpAppHandler - Exception while handling HTTP/1.1 crash, please report to Gatling maintainers
io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
at io.netty.util.internal.ReferenceCountUpdater.toLiveRealRefCnt(ReferenceCountUpdater.java:74)
at io.netty.util.internal.ReferenceCountUpdater.release(ReferenceCountUpdater.java:138)
at io.netty.util.AbstractReferenceCounted.release(AbstractReferenceCounted.java:76)
at io.netty.handler.ssl.ReferenceCountedOpenSslContext.release(ReferenceCountedOpenSslContext.java:675)
at io.netty.util.ReferenceCountUtil.release(ReferenceCountUtil.java:88)
at io.gatling.http.util.SslContexts.close(SslContexts.scala:140)
at io.gatling.http.protocol.HttpComponents.$anonfun$onExit$3(HttpComponents.scala:45)
at io.gatling.http.protocol.HttpComponents.$anonfun$onExit$3$adapted(HttpComponents.scala:45)
at scala.Option.foreach(Option.scala:407)
at io.gatling.http.protocol.HttpComponents.$anonfun$onExit$1(HttpComponents.scala:45)
at io.gatling.http.protocol.HttpComponents.$anonfun$onExit$1$adapted(HttpComponents.scala:43)
at io.gatling.core.protocol.ProtocolComponentsRegistry.$anonfun$onExit$2(Protocol.scala:84)
at io.gatling.core.protocol.ProtocolComponentsRegistry.$anonfun$onExit$2$adapted(Protocol.scala:84)
at scala.collection.mutable.HashMap$$anon$2.$anonfun$foreach$3(HashMap.scala:158)
at scala.collection.mutable.HashTable.foreachEntry(HashTable.scala:237)
at scala.collection.mutable.HashTable.foreachEntry$(HashTable.scala:230)
at scala.collection.mutable.HashMap.foreachEntry(HashMap.scala:44)
at scala.collection.mutable.HashMap$$anon$2.foreach(HashMap.scala:158)
at io.gatling.core.protocol.ProtocolComponentsRegistry.$anonfun$onExit$1(Protocol.scala:84)
at io.gatling.core.protocol.ProtocolComponentsRegistry.$anonfun$onExit$1$adapted(Protocol.scala:84)
at io.gatling.core.session.Session.exit(Session.scala:302)
at io.gatling.core.action.Exit.execute(Exit.scala:31)
at io.gatling.core.action.ChainableAction.$bang(Action.scala:72)
at io.gatling.core.action.ChainableAction.$bang$(Action.scala:61)
at io.gatling.core.action.builder.SessionHookBuilder$$anon$1.io$gatling$core$action$ExitableAction$$super$$bang(SessionHookBuilder.scala:29)
at io.gatling.core.action.ExitableAction.$bang(BlockExit.scala:141)
at io.gatling.core.action.ExitableAction.$bang$(BlockExit.scala:139)
at io.gatling.core.action.builder.SessionHookBuilder$$anon$1.$bang(SessionHookBuilder.scala:29)
at io.gatling.http.engine.response.RootNextExecutor.executeNextOnCrash(NextExecutor.scala:50)
at io.gatling.http.engine.response.DefaultResponseProcessor.handleFailure(ResponseProcessor.scala:73)
at io.gatling.http.engine.response.DefaultResponseProcessor.onComplete(ResponseProcessor.scala:59)
at io.gatling.http.engine.GatlingHttpListener.onThrowable(GatlingHttpListener.scala:105)
at io.gatling.http.client.impl.HttpAppHandler.crash(HttpAppHandler.java:81)
at io.gatling.http.client.impl.HttpAppHandler.channelRead(HttpAppHandler.java:196)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352)
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:438)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:328)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:302)
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:253)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1422)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:931)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:700)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:635)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:552)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:514)
at io.netty.util.concurrent.SingleThreadEventExecutor$6.run(SingleThreadEventExecutor.java:1044)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:834)

`

The sample source code below basically has a web application that simulates a failure past 1000 calls. The idea is that the gatling simulation should stop calling the service, exit and capture the result in the report as a new baseline (as per my previous post https://groups.google.com/d/msgid/gatling/721b9bd0-ad5c-40ac-9526-f8b2b15049c5%40googlegroups.com?utm_medium=email&utm_source=footer)

Is there anything else I should be calling instead of session.exit() to exit make gatling exit the scenario?

Versions:

`
<gatling-maven-plugin.version>3.0.5</gatling-maven-plugin.version>
<gatling-charts-highcharts.version>3.3.0</gatling-charts-highcharts.version>

`

Source code: https://github.com/manthanhd/spring-boot-gatling-example

Thanks,
Manthan

Session#exit is an internal (we’ll be fixing visibility in a next release).

You definitively mustn’t use it and it doesn’t do what you think.
It doesn’t make the user forcefully terminate, it releases internal resources associated to this user.