Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nodejs: How to wait for server start at http://localhost:8000

I am starting the server from my script and then want to execute my tests. But when I start the server the server start process doesn't return as it is running and control is not returned back. The server starts and the app can be accessed on http://localhost:8000. so I have used nodejs fetch and http request to check if response==200 at http://localhost:8000 but get error: console.error FetchError { message: 'request to http://127.0.0.1:8000/ failed, reason: connect ECONNREFUSED 127.0.0.1:8000', type: 'system', errno: 'ECONNREFUSED', code: 'ECONNREFUSED' } Is there any way I could poll and start my tests ? My code:

const util = require('util');
const exec = util.promisify(require('child_process').exec);
const fetch = require('node-fetch');
const http = require('http');

async function waitforlocalhost() {
    await fetch('http://127.0.0.1:8000/'), (response) => {
    //http.get({hostname:'localhost',port: 8000,path: '/',method: 'GET',agent: false}, (response) => {
        if (response.status === 200) {
            resolve();
            return;
        } else {
            setTimeout(waitforlocalhost,2000);
        }
    }
}

class CreateEnv {
    async  Execute () {
        try {
            //create database and start server
            console.log("Create database and runserver...");
            exec('python manage.py startserver');
            await waitforlocalhost();
            console.log("Server started...");
        } catch (e) {
            console.error(e);
            console.log("Error creating database and runserver...");
            return;
        }
    }
}
module.exports = CreateEnv;
like image 458
Amit Kulkarni Avatar asked Sep 15 '25 01:09

Amit Kulkarni


1 Answers

Rewrote your checker like the following,

  • loop x times with a while loop
  • before each check, sleep for x milliseconds
  • if good, resolve promise
  • if not, reject
  • catch stop or other error in outer try/catch

const fetch = require('node-fetch')

function waitforhost(url, interval = 1000, attempts = 10) {
  
  const sleep = ms => new Promise(r => setTimeout(r, ms))
  
  let count = 1

  return new Promise(async (resolve, reject) => {
    while (count < attempts) {

      await sleep(interval)

      try {
        const response = await fetch(url)
        if (response.ok) {
          if (response.status === 200) {
            resolve()
            break
          }
        } else {
          count++
        }
      } catch {
        count++
        console.log(`Still down, trying ${count} of ${attempts}`)
      }
    }

    reject(new Error(`Server is down: ${count} attempts tried`))
  })
}

async function main() {

  const url = 'http://127.0.0.1:8000/'

  console.log(`Checking if server is up: ${url}`)
  try {
    await waitforhost(url, 2000, 10)
    console.log(`Server is up: ${url}`)
  } catch (err) {
    console.log(err.message)
  }
}

main()

Results in:

Checking if server is up: http://127.0.0.1:8000/
Still down, trying 2 of 10
Still down, trying 3 of 10
Still down, trying 4 of 10
Still down, trying 5 of 10
Still down, trying 6 of 10
Still down, trying 7 of 10
Still down, trying 8 of 10
Still down, trying 9 of 10
Still down, trying 10 of 10
Server is down: 10 attempts tried

Or when success

Checking if server is up: http://127.0.0.1:8000/
Server is up: http://127.0.0.1:8000/

I'll leave you to implant into your code.

like image 118
Lawrence Cherone Avatar answered Sep 17 '25 16:09

Lawrence Cherone