Search code examples
scalagatling

Gatling: Producer and consumer users


I have a load test where three sets of users create something and a different set of users perform some actions on them.

What is the recommended way to co-ordinate this behaviour in Gatling?

I'm currently using an object which contains a LinkedBlockingQueue which the "producers" put the ID and consumers take, see below.

However, it causes the test to hang after ~20s (targeting 1tps). I've also tried using poll with a timeout, but instead of hanging the poll almost always fails (after 30s) or causes a hang if the timeout is larger (1m+).

This seems to be because all the threads are blocked waiting for something from the queue so isn't compatible with the way Gatling tests run (i.e. not 1 thread per user). Is there a non-blocking way to wait in the Gatling DSL?

Producer.scala

// ...
scenario("Produce stuff")
    .exec(/* HTTP call which extracts an ID*/)
    .exec(session => Queue.ids.put(session("my-id").as[String])
// ...

Consumer.scala

// ...
scenario("Consume stuff")
    .exec(session => session.set("my-id", Queue.ids.take()))
    .exec(/* HTTP call which users ID*/)
// ...

Queue.scala

object Queue {
    val ids = new LinkedBlockingQueue[String]()
}

As an alternative I've tried to use the application functionality but it seems a harder problem to ensure that each user picks a unique item from the app.


Solution

  • Acknowledging this is all a hack, my current solution in Consumer.scala is:

    doIf(_ =>  Queue.ids.size() < MIN_COUNT)(
      pause(30) // wait for 30s if queue is initially too small
    )
    .doWhile(_ => Queue.ids.size() >= MIN_COUNT)(
      exec(session => session.set("my-id", Queue.ids.take()))
        .exec(...)
        .pause(30)
    )