Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use asynchronous initialization in a Connect middleware?

I wrote a middleware for Connect and Express that requires some heavy lifting in its setup method. Due to the nature of the initialization tasks this stuff is asynchronous, so I have the problem that the middleware shall only be accessible once the initialization has been run.

Currently I have solved it using a callback:

function setupMiddleware(callback) {
  doSomeAsyncInitialization(function () {
    callback(function (req, res, next) {
      // The actual middleware goes here ...
    });
  });
}

This works, but it's not nice for the caller. Instead of being able to do

app.use(setupMiddleware());

I have to do:

setupMiddleware(functin (middleware) {
  app.use(middleware);
});

Now I was thinking whether there is a better approach, e.g. let the middleware initialize in the background and delay all incoming requests until the middleware is ready.

How could I solve this? Any ideas or best practices that I should use here?

like image 692
Golo Roden Avatar asked Mar 22 '13 11:03

Golo Roden


1 Answers

I now solved it using an isInitialized variable and delaying the middleware function itself. See the following example:

var connect = require('connect');

var setup = function () {
  var isInitialized = false;

  setTimeout(function () {
    isInitialized = true;
  }, 10000);

  function run (req, res, next) {
    res.write('Foo');
    res.end();
  }

  function delay (req, res, next) {
    if (isInitialized) {
      return run(req, res, next);
    }

    setTimeout(function () {
      delay(req, res, next);
    }, 1000);
  }

  return function (req, res, next) {
    if (req.url === '/foo') {
      delay(req, res, next);
      return;
    }
    next();
  }
};

var app = connect();
app.use(setup());
app.use(function (req, res) {
  res.write('Fertig!');
  res.end();
});

var http = require('http');

http.createServer(app).listen(5000);

Please note that this code has not been optimized or refactored in any way, it just is a demonstration that the idea itself works.

like image 162
Golo Roden Avatar answered Nov 15 '22 10:11

Golo Roden