0

I try to create a loading test script but I faced with weird behaviour I use https://github.com/prisma-labs/graphql-request module for graphql request.

But I don't see that the process run into the callback

I see the next result. It stoped on the 5 first items.

GET:  MX
GET:  MX
GET:  DE
GET:  LT
GET:  US

I think maybe I don't have access to the requestCount variable in the callback function but I don't even see that the request was sent.

import { request, gql } from 'graphql-request'

const MAX_REQUESTS = 5;
const countries = ['GB', 'UK', 'US', 'LT', 'IT', 'DE', 'MX']
const getRandomElement = (items) => {
    return items[Math.floor(Math.random()*items.length)];
}

let requestCount = 0;
while (true) {
    let country = getRandomElement(countries);
    let query = gql`
{
  country(code: "${country}") {
    name
    native
    capital
    emoji
    currency
    languages {
      code
      name
    }
  }
}`
    if (requestCount >= MAX_REQUESTS) {
        continue;
    }

    console.log('GET: ', country);

    request('https://countries.trevorblades.com/', query).then((data) => {
        console.log('OK: ', country);
        requestCount--;
    }).catch((error) => {
        console.log('FAILED: ', country);
        requestCount--;
        console.error(error)
    })

    requestCount++;
}
Vlad
  • 25
  • 5
  • Do you want to continuously make 5 requests to the server? If one request succeeds than it should make another one ? – Sagar Sep 02 '21 at 13:03
  • shouldn't it `requestCount++;` instead? – ikhvjs Sep 02 '21 at 13:18
  • What does the Network tab say in your browser? If the response times out, it can pile up the requests without getting a response right away (and then it feels like it "skipped" the callback, but it's just waiting for the timeout) – jkoestinger Sep 02 '21 at 13:20
  • 1
    @Sagar You are absolutely right – Vlad Sep 02 '21 at 15:09

2 Answers2

1

This is behaviour of Node.js (Sync)

If you have snippet that is sync and inside it has the async Callbacks. It will wait for the sync execution and then it will move to callback queue.

A simple example

let counter = 0;
while(true) {
    console.log("While", counter++)
    setTimeout(() => {
        console.log("Inside Timeout")
    }, 0)
}

In your use case either you can maintain queue or change while condition

Sagar
  • 1,374
  • 10
  • 18
0

Your while loop never break and it keeps executing and occupy the tread. Your async function (Promises) never has a chance to go back to the thread to execute.

Edit: send a request with 5 items every time.

import { request, gql } from "graphql-request";

const MAX_REQUESTS = 5;
const arr = ["GB", "UK", "US", "LT", "IT", "DE", "MX"];

const getRandomElements = (items, numberOfElements) => {
  return Array.from({ length: numberOfElements }).map(
    _ => items[Math.floor(Math.random() * items.length)]
  );
};

const getQuery = country => gql`
    {
        country(code: "${country}") {
            name
            native
            capital
            emoji
            currency
            languages {
            code
            name
            }
        }
    }`;

(async function run() {
  while (true) {
    const countries = getRandomElements(arr, MAX_REQUESTS);
    const promises = countries.map(country =>
      request("https://countries.trevorblades.com/", getQuery(country))
    );
    const results = await Promises.allSettled(promises);

    results.forEach((res, i) => {
      if (res.status === "fulfilled") {
        console.log(`OK: Country:${countries[i]} data:${res.value}`);
      } else {
        console.log(`FAIL: Country:${countries[i]} Error:${res.reason}`);
      }
    });
  }
})();
ikhvjs
  • 5,316
  • 2
  • 13
  • 36
  • The problem is I don't need to break the loop I have a lot of requests which I need to run by 5 items running in the same time – Vlad Sep 02 '21 at 14:47
  • @Vlad, OK, I updated my answer for your updated requirement. – ikhvjs Sep 02 '21 at 15:17
  • Great It works well If I got it right the function which use the callbacks should be async – Vlad Sep 02 '21 at 15:56
  • @Vlad, The callback you mentioned is actually promise. If you are not familiar with promise, it would be hard for you to understand the async/await syntax because the async/await is based on promise. You may have a look of promise and async/await in js. – ikhvjs Sep 02 '21 at 21:18
  • Yes, I've looked the documentation about async/await I just misunderstood them in a loop – Vlad Sep 03 '21 at 08:34
  • @Vlad, Good to hear. If my question help, may you accept it? It may help people to see it in the future. – ikhvjs Sep 04 '21 at 21:16