Feeder csv(code.csv) is now empty, stopping engine

Hi there,
I have the issue with empty feeder when running my simulations.

So, the file has headers and one simulation writes into that file, and another one reads those info and uses during simulation. So I don’t want to use child. I’m using circular mode in the feeder, so I am not sure why I’m getting ‘Feeder csv(code.csv) is now empty, stopping engine’. As far as I saw in the documentations, the circular mode should start from the beginning after the end is reached. Will this happen when I have one one row in the file (besides headers)?

I fully understand where the issue is in my code, number of virtual users in the second simulation is greater that number of virtual users from the first simulation, and that is ok… but cannot understand why second simulation does not start with same values from csv file if the circular mode is added to feeder.

P.S. the same issue occurred with batch load mode.

Thanks for any help in advance!

Hi @evalalos,

Did you try with batch + circular?
And when there is at least some data in the csv? (the header should be present at the Simulation instanciation, and data should be present before the first call to feed)

Can you create a SCCE and share it with us?

Cheers!

@evalalos Isn’t that the same question you’ve asked and got an answer for a few months ago? Requirement failed: Feeder source is empty - #2 by sbrevet

Hello!
Indeed batch + circular fixed the issue.

I don’t know why it won’t work with circular only, I’ll try to explain as best as I can:

So the simulation1 starts with 1 virtual user and creates some data and writes that data into csv file, simulation2 waits for 10 minutes and after that starts with 3 virtual users, reads the data from the csv file using only circular method, the data exists in the csv file so the first virtual user finishes simulation2 successfully. Next v. user should start simulation2, but the execution crashes due to empty feeder - but the data exists in the csv file (only one row, but still exists). I’m expecting to have different data so the v. user 2 from simulation2 should use different data, but if it doesn’t exist, I thought the initial data (same as v. user1) should be used for user2. Because of circular, but after I added batch + circular, it looks fine for now.

    public static final ChainBuilder myCall =
                    feed(csv("data.csv").circular())
                    .exec(http("Enter data: " + ENDPOINT)
                            .post(BASE_URL + "/v1/basket")
                            .formParam(TOKEN, TOKEN_VALUE));
scenarios1.injectOpen(
                        rampUsersPerSec(0).to(1, 100.0)).during(1800),
                        constantUsersPerSec(1, 100.0)).during(10)).protocols(httpProtocol),
scenario2.injectOpen(
                        nothingFor(600),
                        rampUsersPerSec(0).to(3, 100.0)).during(1800),
                        constantUsersPerSec(3, 100.0)).during(10)).protocols(httpProtocol)
00:47:49.381 [ERROR] i.g.a.Gatling$ - Run crashed
java.lang.IllegalStateException: Feeder csv(data.csv) is now empty, stopping engine
	at io.gatling.core.action.FeedActor$$anonfun$receive$1.applyOrElse(FeedActor.scala:83)
	at akka.actor.Actor.aroundReceive(Actor.scala:537)
	at akka.actor.Actor.aroundReceive$(Actor.scala:535)
	at io.gatling.core.akka.BaseActor.aroundReceive(BaseActor.scala:25)
	at akka.actor.ActorCell.receiveMessage(ActorCell.scala:579)
	at akka.actor.ActorCell.invoke(ActorCell.scala:547)
	at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:270)
	at akka.dispatch.Mailbox.run(Mailbox.scala:231)
	at akka.dispatch.Mailbox.exec(Mailbox.scala:243)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)

Initial look of csv file:

Code,BirthDate

Csv file after simulation1 finished:

Code,BirthDate
1223,6-6-1990

Let me know if you need something else.

Cheers

Yes, I met all suggestions from the answer, but after some time, it stopped working.

Please read the documentation: Gatling - Feeders

Without batch, when the file is small, it’s loaded once in memory on boot so Gatling doesn’t have to perform slow filesystem access during the test.

And that being said, honestly, I think it’s a bad solution to use a file as a buffer for communicating between virtual users in 2 different scenarios, in particular when the data fits in memory.

What I would do (assuming the consumer scenario starts only once the producer scenario terminates, using andThen):

  • have the producer scenario push the data into a thread-safe structure such as a ArrayBlockingQueue
  • have the consumer scenario pull from the buffer in a thread-safe way, eg if the buffer is an array and you want a circular/looping iterator, use an AtomicInteger and a modulo for the current index.

Hey, really appreciate your help! No, the simulation2 should start after 10 minutes, not after the simulation1 finishes, thats why I cannot use andThen method. This is the use case, so I have to follow it :slight_smile:

Thanks a lot once again.

My suggestion is still valid. It’s just that you might have to deal with the possibility that your consumer is faster than your producer and might end up with an empty buffer at some point.

Yes, I agree. I will think about reimplementing and using andThen