Interrupted iterations if I don't close the socket

I have a test with lot of socket connections (50K) and I intensionally want to keep the socket connection because my systeam broadcast messages and I need to test the load of that broadcast over 50k connected “users”… The problem is that not clossing the connection, the result is:

running (5m30.9s), 00000/50000 VUs, 0 complete and 50000 interrupted iterations

I tried with teardown but I couldn’t close the sockets from there…

This is my scenario:

scenario_50000_5_mins_users: {
    executor: "constant-arrival-rate",
    rate: 167,
    timeUnit: "1s",
    duration: "5m",
    preAllocatedVUs: 50000,
    maxVUs: 50000,
    gracefulStop: "30s",
  },

and clossing the socket on message works fine:

socket.on("message", (message) => {
        let json_message = JSON.parse(message);
        if (json_message[3] === "phx_reply") {
          checkSocketResponse(json_message);
        }
        console.log(socket);
        socket.close();
      });

Any idea?

Hi @julsmz,

Welcome to our community, thanks for sharing your question here :tada:

Are you using k6/ws or k6/experimental/websockets?
Have you experienced the same behavior with both?

Thanks! :bowing_man:

Hi again @julsmz,

Sorry, I think I got confused at the first read. Apologies! :pray:

I see, your problem is that if you close the socket within the “main” (default) function, it works as expected, but if you don’t, all the VUs remain blocked and although you can replicate the behavior of having multiple VUs connected concurrently (right?), the test doesn’t finish successfully.

Then, my question is: what is the “condition” that determines that the load test has concluded?
For instance, could you use your server, once you have tested what you need, confirmed that there are are up to X (50k?) clients connected, etc, to broadcast a extra message to all clients telling them they can be closed? Or alternatively, although not very efficient, could you use setTimeout with a “safe” value on each VU (in the “main” function) to close the socket after some time, and set k6’s duration/timeout with a higher value?

I hope any of those ideas helps! :bowing_man:

Thanks so much for your answer @joanlopez

I fixed it (so far) adding a while true statement on the code like this:

 wsSocket.on("message", (message) => {
        const jsonMessage = JSON.parse(message);
        if (jsonMessage[3] === "phx_reply") {
          checkSocketResponse(jsonMessage);
          while (true) {    
            const heartbeatMsg = JSON.stringify([
              null,
              0,
              "phoenix",
              "heartbeat",
              {}
            ]);
            
            wsSocket.send(heartbeatMsg);    
            sleep(30);
          }
        }
      });

      wsSocket.on("error", handleWsError);
      wsSocket.on("close", () => {
        console.log("WebSocket disconnected");
      });

Seems like there were some timeouts errors and that caused the problem…

For my surprise setInterval doesn’t work so I had to implement that old-fashionist solution.

Thanks again!

Great @julsmz, that’s definitely good news!

For my surprise setInterval doesn’t work so I had to implement that old-fashionist solution.

Could you open an issue in k6 repository, with the details and the minimum example script possible that reproduces it, please?

That would be really appreciated, so we can put some efforts on improving that, if it really doesn’t work well / as expected.

Thanks! :bowing_man: