0

My node app is simple, for a request querying the total customers in mysql databases, i do a block call using await to wait for query to finish. The problem is it can only handle ~75 requests per second, too low.

So i try to return 200 whenever i get the request, telling caller i get the request. Then return the query result when ready, mysql query could take a while.

But not working for me yet, this is the code:

router:

router.get('', controller.getCustomers);

controller:

const getCusomers = (req, res) => {
    try {
        service.getCustomers(res);
        res.write('OK');
        //res.send(200); this will end the response before query ends
    } catch (err) {
        res.end(err);
    }

service:

const getCustomers = async (res) => {
    customers = await mysqlPool.query('select * from cusomerTable');
    res.send(customers);
}

Error: Can't set headers after they are sent to the client.

How to fix this pls ?

user3552178
  • 2,719
  • 8
  • 40
  • 67
  • It looks like you're writing "OK" to the response after you await grabbing the data from your service.. Basically, what is happening is: client sends request -> server gets it -> you query mysql -> you send query results -> you write "OK" .. things are not happening in the order you think they are. `service.getCustomers` contains a blocking call... that is why you get the error about headers..(specifically, res.write is causing error) I dont understand the need/want to notify the client you got the request. if youre sending the req using XHR it shoudnt block the browser from doing its thing.. – Matt Oestreich Oct 12 '19 at 04:16
  • 1
    With that being said, a 200 will close communication, I dont think it fits here, but you can look more into [206 Partial Content](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/206).. Or use res.write(customers) versus res.send(customers) as this streams the response...All in all, I think you should just let the client wait for the response, without letting them know you got it... I don't understand the use case, so it's hard for me to see why you would want to do this. – Matt Oestreich Oct 12 '19 at 04:19

1 Answers1

1

You can use Server-Sent Events. You can send an event as soon as you get the request. When the result is ready, you can send another event. Kindly find my GitHub repo useful for a SSE sample.

OR

You can just use res.write() to stream the response. Find this StackOverflow answer useful.

Sudhakar Ramasamy
  • 1,736
  • 1
  • 8
  • 19
  • Initially i was planning to use res.write() in controller, then res.json() in service as mysql query returns a json object. It didn't work. Since you said so, i replaced res.json() with res.write(JSON.stringify(queryResult); res.end(). It worked, doesn't make any sense, i thought res.json() is doing the similar thing. – user3552178 Oct 12 '19 at 04:36