Bug report for the gRPC plugin

Not sure where to put this, the gRPC plugin is not in the Gatling repo.


callOptions should take an Expression instead of a static value.

In the test cases we can see .callOptions(CallOptions.DEFAULT.withDeadlineAfter(100, MILLISECONDS)). This CallOptions object is created once, when the test initializes, and has a static deadline. By the time the action is run the deadline has already expired.

Perhaps because the call never started, the request is not registered in the simulation.log. Maybe this is the expected behaviour, but the demo project failing with “There were no requests sent during the simulation, reports won’t be generated” does not look good.


BTW are there plans to incorporate other features of the community plugin into Gatling’s gRPC plugin?

Hello, you can post issues directly in the main repo: Issues · gatling/gatling · GitHub

For the callOptions, thanks for finding that one cause we did not! We are not sure how to go about it yet, as there are issues with when you should evaluate the expression when using a throttler, but will release a fix soon.

For the features, we decided to start with a subset only to speed things up but we will cover everything in the end. We will prioritise based on user feedback.

we will cover everything in the end

That’s great to hear. But some of the things I did in the community plugin was code heavy, I worry that they might be philosophically incompatible with the rest of Gatling.


Speaking of philosophy, what do you think about the use of lens+expression with ScalaPB generated messages?

Compare the following Scala snippet:

for {
  firstName <- session("firstName").validate[String]
  lastName <- session("lastName").validate[String]
} yield Greeting(firstName, lastName)

and the corresponding Kotlin code:

greeting {
    firstName = session.get("firstName") ?: "null"
    lastName = session.get("lastName") ?: "null"
}

In the Scala version firstName appears 3 times (will be four if you use named arguments) - twice are intermediate variables; and the type String has to be provided explicitly. It doesn’t sit well with me that the Scala code is more verbose than the Kotlin version.

But I also know that the lens magic I did was confusing for many. I’d love to hear your thoughts on that.

Hi @phiSgr,

Those snippets are not really comparable.
In Kotlin code, you will end with partial value (ie with default value) if one is missing. But in scala code, each argument of the Greeting constructor is check and ONLY if both are valid, there is a valid Greeting.

In Kotlin code, you lose the error handling.

Cheers!

The snippets are copied from the official examples. To make them behave more similarly, just change the ?: "null" to !! in Kotlin.

This difference is not the point, neither is the difference between NullPointerException/ClassCastException and monadic error handling of Validation.

The point is the verbosity of explicit types and intermediate variables.

The Kotlin snippet feels the same as the following scala code:

Greeting(session("firstname").as[String], session("lastName").as[String])

(See? Only one occurrence of each, less verbose than the Kotlin code)

But monadic error handling is more common in scala, and exception handling is more common in Kotlin (I can only guess for the later, as I’m not a heavy user of Kotlin myself)

So I think the real question is not about verbosity or not in the sample, but if the sample is more in the common convention of the language.
Once again, I’m not a Kotlin user, so perhaps the written Kotlin code is not idiomatic as well.

Cheers!

Not something we want to do. We want to keep things simple and consistent across languages. So we won’t explore fancy language features in the end-user layer.

Let me start by saying that this is a philosophical rabbit hole I don’t have strong feelings about. It’s just fun to argue.


The Kotlin snippet feels the same as the following scala code

It’s closer to your snippet plus named argument. The difference is that the generated Kotlin code requires you to write the field name.

Named arguments (or the property setter syntax in Kotlin) give you more confidence that the values go to the correct fields; whereas the intermediate variables in a for-comprehension only adds indirection.

So I think the real question is not about verbosity or not in the sample, but if the sample is more in the common convention of the language.

It’s both. I don’t like that the idiomatic/suggested usage is more verbose.


We want to keep things simple and consistent across languages. So we won’t explore fancy language features in the end-user layer.

Yeah that’s fair.

Agreed!

You first say it was a shame that scala was more verbose than Kotlin, and now, you defend Kotlin by the fact it requires that. double standards!

Exists too in scala, so no debate here ^^

I don’t care if the suggested usage is more verbose or not. My (personal) concern is that the sample are more appealing to the actual user (in their favorite) language.
So, if (troll intended) the java users prefer 3 lines and 6 javadoc lines for something we can do in half a line in kotlin and scala, it doesn’t bother me that the sample in scala is 5 lines, in kotlin 3 lines and java 35 lines.

The API should be consistent across languages, but way to use it (my opinion) should embrace the way the language is used elsewhere.

Cheers!

1 Like

double standards!

They are apples and oranges so of course I have two standards. :smiley:

In the case of Kotlin, the generated code forces you to add some verbosity which adds value;
in Scala, the doc suggests you to add some verbosity which has no value.

Cheers!

So, my point is scala sample is better because the added verbosity is acceptable compared to the monadic error handling. As Kotlin doesn’t help to manage such errors, we are going back to exception handling that add runtime complexity (and try catch add verbosity AND indirections).

Cheers!

Try-catch is done in library code, written once.
The for comprehension has to be written by users every time.

I’m not sure how try-catch adds indirections.

You mean that errors from user code can correctly be handled in library code?
Indeed, try catch is done in library code, to avoid user code can break library behavior. But it isn’t error handling. Handling error is (or at least should be) in the same scope as the scope producing the error in order to correctly react to the specific use case.

Monadic error handling ensure that this handling is done on duty place.

Cheers!

1 Like

phiSgr
But I also know that the lens magic I did was confusing for many. I’d love to hear your thoughts on that.

Sorry for interrupting tech talk,
I have read your lens magic, I do agree that it helps the dynamic data struct to be easier to handle, rather than to define new session block and work there, but Haskell’s tutorial was hard to consume (at least in my POV). I suggest to have a clearer example only in the tutorial.

I have not got the chance to work with Gatling’s official gRPC yet, I’m looking forward to it.
Kudos to Gatling team and phiSgr, you guys are amazing !

I was half trolling linking to Haskell.

The community version of the plugin allowed* me to experiment with what I can do with the language. Quite a lot as it turned out, probably more than healthy. And writing a tutorial for concepts with multiple prerequisites was unfun.

* Note the past tense, I have archived the repository.

Glad that you like the lens way. I was quite proud to find a way that uses the monadic errors, but avoids repetitions and having to specify explicit types.

1 Like

@phiSgr Thank you for your hard work on the community Gatling gRPC plugin. I have used it in several projects. It is unfortunate that you archived the project, as the Official Gatling plugin is only usable for Enterprise subscriptions. The limits of:
5 users max
5 minute duration tests
It too limiting to bother using. We are not interested in an Enterprise subscription as we dont load test enough or high enough loads to needed. So unfortunately we will have to investigate a different load testing solution.

@ColinR Thank you for liking my work. But one thing to keep in mind is that I was able to build the community plugin only because Gatling Corp has built the framework. And they have to get paid somehow. Out of respect for them I archived my plugin.

It looks like load testing is not that important for your business. You can stay on Gatling 3.9.
Or if load testing is important, forking the open source project is always an option.

1 Like

Thanks phiSgr,

I’d also like to say that the Enterprise subscription starts at €99/month, which really isn’t too prohibitive if you require the gRPC plugin with additional users and duration.

All the best,
Pete