How to disable a slow middleware connection and return a Node response instead?

I have a Node server that uses Connect to insert some middleware that is trying to convert the response stream from node-http-proxy. Sometimes this conversion can be quite slow, and it would be preferable in such cases to simply return a response that does not include the transformations or, alternatively, includes their partial application.

In my application, I tried to use setTimeoutto call nextafter some milliseconds in the context of the conversion middleware. This usually works, but provides a race condition if the middleware has already called next, and then it setTimeoutfires and does the same with an error that looks like this:Error: Can't set headers after they are sent.

In the end, I developed setTimeoutto call nextwith an instance Erroras my first argument, and then I would catch this error in my middleware chain and assuming that I res.headersSentwas false, it would start sending the response through res.end.call(res). It worked and it was amazing that I could set a timeout for almost nothing, and the answer would be much faster and complete.

I feel that this last method is a bit hacked and not immune to the same race condition, but perhaps it seems to be a little more stable. So I would like to know which idiomatic Node and Connect approaches deal with such things.

How can I find the time of slow middleware and just return a response stream?

Currently, it seems to be doing what I want, more or less, but again it feels a little rude.

let resTimedout = false;
const timeout = setTimeout(() => {
  if (!resTimedout) {
    resTimedout = true;
    next();
  }
}, 100);


getSelectors(headers, uri, (selectors) => {
  const resSelectors = Object.keys(selectors).map((selector) => {
    ...
  };

  const rewrite = resRewrite(resSelectors);
  rewrite(req, res, () => {
    if (!resTimedout) {
      resTimedout = true;
      clearTimeout(timeout);
      next();
    }
  });
});
+4
source share
3 answers

setTimeout returns a timeout id, so you can run clearTimeout passing in id. Therefore, when the conversion is complete, just clear the timeout before you call the next one.

var a = setTimeout(()=>{}, 3000);
clearTimeout(a);

https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout

0

async.timeout Promise.timeout Bluebird Q

0

:

const rewrite = resRewrite(resSelectors);
rewrite(req, res, () => {
    // set a timer to fail the function early
    let timer = setTimeout(() => {
        timer = null;
        next();
    }, 100);

    // do the slow response transformation
    transformResponse((err, data) => { // eg. callback handler
        clearTimeout(timer);
        if (timer) next();
    });
});

, null next(). , , - null, next().

, -, .

0

Source: https://habr.com/ru/post/1667088/


All Articles