javascriptk6

Do functions wait for async methods to finish in K6?


So I have a bit of a question, that relates both to k6 and to I guess JavaScript itself. (Also I realize k6 is built upon Go language but uses JS).

Anyways in K6 you have a default function that looks like this:

export default function () {
  http.get('https://test.k6.io');
  sleep(1);
}

In my scenario I need to wait 400ms between two different HTTP requests. K6 has an experimental setTimeout function that does this. So I simply did the below:

export default () => {
http.patch(firstURL,body,params)
setTimeout(() => {
  const res = http.post(secondURL,body,params)
  console.log(res.status)
}, "400");
}

So this did indeed work. It appeared to wait 400ms before executing the second request. However my question is: While it's waiting for that 400ms to end, does the main default function "end"?

As in will it move to the next iteration while that 400ms is finishing up, or will the default function wait for everything to finish before it finally finishes itself? Apologies if the question is confusing, not sure of a better way to explain it.

My initial guess is that the execution stalls until the second request finishes anyways?


Solution

  • Frame challenge ahead.

    sleep in k6 is a synchronous call and blocks execution, there is (currently) no need to use asynchronous methods to do the same.

    The documentation states that it takes the "duration, in seconds", but fails to explicitly mention that fractional seconds are supported as well. There are two hints on the page though:

    1. It specifies the parameter type as "number" (not "integer", mind you).
    2. The first example sleeps a random amount: sleep(Math.random() * 30). Math.random() returns a floating point number between 0 and 1, thus the duration of the sleep method will also be a floating point number.

    Don't believe me? This is easy to verify:

    import { sleep } from 'k6';
    export default function() {
        console.log(new Date());
        sleep(0.1);
        console.log(new Date());
    }
    

    Output:

    INFO[0002] "2023-05-16T16:25:18.085Z"                    source=console
    INFO[0002] "2023-05-16T16:25:18.187Z"                    source=console
    

    Which gives roughly 100 ms (i.e. 0.1 seconds) between the two log calls.