multiple "async" checks for websocket

Hi,

I am trying gatling only for 1 day now and I am pretty impressed by its nice API.
I am currently writing a simple websocket test with only 1 client sending a bunch of requests to the server and waiting for exactly 1 response for each of those requests.

I came up with this version using a non-blocking check because i want to avoid the coordinated ommision problem.

`

.repeat(50000, "i") {
  exec(ws("Send GetUserSessionRequest")
    .sendText( """{"messageType": "request.getUserSession","payload": {"requestId": "${i}"}}""")
    .check(wsListen.within(2 seconds).until(1).jsonPath("$.payload.requestId").is("${i}"))
  )
  .pause(3 milliseconds, 30 milliseconds)
}

`

Basically I want to send a lot of requests with very short pause times inbetween and I expect a response for each of those requests.

Unfortunatly this does not work (when running gatling it tells me that some checks did not succeed in time when the next check was defined), most likely because of the same problem as described here: https://groups.google.com/forum/#!topic/gatling/vr6GknCI7r4

My questions are:

  1. Do I need to use wsListen If I do not want to block gatling from sending the next request? or can I also use wsAwait? (my primary concern is again the coordinated omission problem)
  2. Is gatling buffering inbound messages? If this is not the case, how would duplex protocols like websockets be checked without blocking the sender? (For me it looks like wsAwait is blocking gatling from sending the next message)
  3. Are there already some plans for extending the Websocket API? Maybe I can help.

Hi David,

In short, the current WebSocket support was more intended for use cases such as a web chat, than yours that looks like a messaging service.
We’re really eager to getting more feedback on the WebSocket support and DSL, it’s still really experimental.

Supporting multiple concurrent checks raises many questions:

  • How do you know which inbound message relates to with check? In your case, that would be thanks to a correlation id (your use case really looks like our JMS support: messaging with one single connection, a message/correlation id and each outbound message expecting one and only one matching inbound one)
  • Can you mix blocking and non-blocking checks? What’s the behavior then?
  • What happens when you set a new check on WebSocket that already has one registered? We currently fail it and replace it. But what should we do when there’s multiple checks?
    I wonder if you’re no actually looking for a new DSL component for messaging over WebSocket.

Thoughts?

Hi Stephane,

Thanks for your answer. Your right, my use case is more like a messaging service, one where the server can push message at any time and the client needs to correlate it to its requests or feature.
I think thats a very natural and common way of using websockets therefore it would be awesome to support this in gatling.

  • How do you know which inbound message relates to with check? In your case, that would be thanks to a correlation id (your use case really looks like our JMS support: messaging with one single connection, a message/correlation id and each outbound message expecting one and only one matching inbound one)

As you said, you most likely need a correlationId for this. In our case we correlate Request/Response via the requestId and we also have a dedicated correlationId that correlated multiple message that belong to the same feature/message flow (imo it should have been called flowId or something like this). I will take a look at your JMS support, havn’t checked it out yet.

For example our message definition looks like this:

`

{
    "messageType": "com.XXX.ps.account.response.getUserSession",
    "payload": {
        "requestId": "customClientRequestId001",
        "correlationId": "1b7f2f17-f958-4c0f-86c6-914436f57bf5",
        "sessionId": "f1ae57e6-c0f3-42ec-8f0f-726d181bf5f7",
        "heartbeatInterval": 60,
        "statusCode": {
            "classification": "ok"
        }
    }
}

`

If you have virtual channels (one per client session) you might get away without explicit correlationIds but i think its anyway good practice to define a correlationId and/or sequenceNr in a full-duplex link.

  • Can you mix blocking and non-blocking checks? What’s the behavior then?
  • What happens when you set a new check on WebSocket that already has one registered? We currently fail it and replace it. But what should we do when there’s multiple checks?

Because Websocket allows for much more complex message flows and patterns than HTTP, the gatling API will most likely need to be changed/extended to accommodate for these use cases.

I would perform checks sequentially as they are defined. A new check does not overwrite an existing one, instead its added to the pending “checks queue”.
With actors its usually straight forward to implement. For every received message you look if the current check is completed. If yes you take the next check from the queue otherwise you keep the check until its completed or timed out. (Of course you never block in the actor when you check the current received message)

The client must be able to send messages “concurrently” while its actor is also performing checks. So sending messages and performing checks can be interleaved with each other.

Here is an example of the API of my own little framework (using TestNG) which allows testing with multiple web socket clients.
Ignore the test structure and the thread model but take a look at the assertion API, i think it is quite useful.
I don’t suggest to do the same but rather want to show you one way of doing such checks.
As my example shows a check usually requires more than one messages to be received.

`