tryMax looping on the stack?

Hi there,

it seems tryMax is looping by (non-tail) recursing on the stack. We see stack traces like this:

[many more frames like this]

at io.gatling.core.action.TryMax.execute(TryMax.scala:33)
at io.gatling.core.action.ChainableAction$class.io$gatling$core$action$ChainableAction$class$$$anonfun$1(Action.scala:70)
at io.gatling.core.action.ChainableAction$class.io$gatling$core$action$ChainableAction$class$$$anonfun$1$adapted(Action.scala:68)
at io.gatling.commons.validation.Failure.onFailure(Validation.scala:48)
at io.gatling.core.action.ChainableAction$class.recover(Action.scala:68)
at io.gatling.core.action.If.recover(If.scala:32)
at io.gatling.core.action.If.execute(If.scala:42)
at io.gatling.core.action.ChainableAction$class.io$gatling$core$action$ChainableAction$class$$$anonfun$1(Action.scala:70)
at io.gatling.core.action.ChainableAction$class.io$gatling$core$action$ChainableAction$class$$$anonfun$1$adapted(Action.scala:68)
at io.gatling.commons.validation.Failure.onFailure(Validation.scala:48)
at io.gatling.core.action.ChainableAction$class.recover(Action.scala:68)
at io.gatling.http.action.RequestAction.recover(RequestAction.scala:23)
at io.gatling.http.action.RequestAction.execute(RequestAction.scala:29)
at io.gatling.core.action.ChainableAction$class.$bang(Action.scala:64)
at io.gatling.core.action.Pause.io$gatling$core$action$ExitableAction$$super$$bang(Pause.scala:34)
at io.gatling.core.action.ExitableAction$class.io$gatling$core$action$ExitableAction$class$$$anonfun$3(BlockExit.scala:140)
at io.gatling.core.action.ExitableAction$class.io$gatling$core$action$ExitableAction$class$$$anonfun$3$adapted(BlockExit.scala:140)
at io.gatling.core.action.ExitableAction$.exitOrElse(BlockExit.scala:125)
at io.gatling.core.action.ExitableAction$class.$bang(BlockExit.scala:140)
at io.gatling.core.action.Pause.$bang(Pause.scala:34)
at io.gatling.core.action.InnerTryMax.execute(TryMax.scala:67)
at io.gatling.core.action.BlockExit.exitBlock(BlockExit.scala:37)
at io.gatling.core.action.ExitableAction$.exitOrElse(BlockExit.scala:126)
at io.gatling.core.action.TryMax.execute(TryMax.scala:33)
at io.gatling.core.action.ChainableAction$class.io$gatling$core$action$ChainableAction$class$$$anonfun$1(Action.scala:70)
at io.gatling.core.action.ChainableAction$class.io$gatling$core$action$ChainableAction$class$$$anonfun$1$adapted(Action.scala:68)
at io.gatling.commons.validation.Failure.onFailure(Validation.scala:48)
at io.gatling.core.action.ChainableAction$class.recover(Action.scala:68)
at io.gatling.core.action.If.recover(If.scala:32)
at io.gatling.core.action.If.execute(If.scala:42)
at io.gatling.core.action.ChainableAction$class.io$gatling$core$action$ChainableAction$class$$$anonfun$1(Action.scala:70)
at io.gatling.core.action.ChainableAction$class.io$gatling$core$action$ChainableAction$class$$$anonfun$1$adapted(Action.scala:68)
at io.gatling.commons.validation.Failure.onFailure(Validation.scala:48)
at io.gatling.core.action.ChainableAction$class.recover(Action.scala:68)
at io.gatling.http.action.RequestAction.recover(RequestAction.scala:23)
at io.gatling.http.action.RequestAction.execute(RequestAction.scala:29)
at io.gatling.core.action.ChainableAction$class.$bang(Action.scala:64)
at io.gatling.core.action.Pause.io$gatling$core$action$ExitableAction$$super$$bang(Pause.scala:34)
at io.gatling.core.action.ExitableAction$class.io$gatling$core$action$ExitableAction$class$$$anonfun$3(BlockExit.scala:140)
at io.gatling.core.action.ExitableAction$class.io$gatling$core$action$ExitableAction$class$$$anonfun$3$adapted(BlockExit.scala:140)
at io.gatling.core.action.ExitableAction$.exitOrElse(BlockExit.scala:125)
at io.gatling.core.action.ExitableAction$class.$bang(BlockExit.scala:140)
at io.gatling.core.action.Pause.$bang(Pause.scala:34)
at io.gatling.core.action.InnerTryMax.execute(TryMax.scala:61)
at io.gatling.core.action.Action$class.$bang(Action.scala:35)
at io.gatling.core.action.InnerTryMax.io$gatling$core$action$ChainableAction$$super$$bang(TryMax.scala:36)
at io.gatling.core.action.ChainableAction$class.$bang(Action.scala:60)
at io.gatling.core.action.InnerTryMax.$bang(TryMax.scala:36)
at io.gatling.core.action.TryMax.io$gatling$core$action$TryMax$$$anonfun$1(TryMax.scala:33)
at io.gatling.core.action.TryMax.io$gatling$core$action$TryMax$$$anonfun$1$adapted(TryMax.scala:33)
at io.gatling.core.action.ExitableAction$.exitOrElse(BlockExit.scala:125)
at io.gatling.core.action.TryMax.execute(TryMax.scala:33)
at io.gatling.core.action.Action$class.$bang(Action.scala:35)
at io.gatling.core.action.TryMax.$bang(TryMax.scala:24)

Is this expected? We don’t yet crash with StackOverflowException but it seems we would if the number of attempts in tryMax gets too high.

Johannes

Hey Johannes,

In 2.2, we’ve tried to reduce message passing to the minimum. This has greatly improved performance on some cases.

Yet, I don’t really get your stack. For example, why don’t you jump into the LARS in the pause?
Could you provide a reproducer, please?

Cheers,