Note that there are some explanatory texts on larger screens.

plurals
  1. PONode.js blocking the event loop?
    text
    copied!<p>I am writing an API, and I got stuck at the point where I am mixing asyncronous and syncronous code depending on the incoming request, take a look at the examples below.</p> <p><strong>routes.js</strong></p> <pre><code>module.exports = [ { method: 'GET', path: '/', controller: 'main', action: 'main', description: 'lists the API functionality', access: 'auth' }, { method: 'POST', path: '/users', controller: 'users', action: 'create', description: 'creates a new user', fields: { fullName: { format: { min: 2, max: 64, minWords: 2, disableDoubleSpaces: true }, description: 'the full name of the new user', examples: 'Thomas Richards, Richard Jones, Michael J. Fox, Mike Vercoelen, John Johnson' }, email: { format: { min: 2, max: 64, maxWords: 1, match: 'email' }, description: 'the email address of the new user', examples: 'mike@grubt.com, lilly@gmail.com, thomas.richards@mail.com, peter@mymail.com' }, password: { format: { min: 2, max: 64 }, description: 'the password of the new user', examples: '123abcdfg, 7373kEjQjd, #8klKDNfk' } } } ]; </code></pre> <p>the routes.js file is basically a very essential part of the API, it validates incoming data, routes to the correct controller/action and defines if the method is public, or requires authentication (basic auth).</p> <p><strong>api-server.js</strong></p> <pre><code>var http = require('http'); var url = require('url'); var os = require('os'); var dns = require('dns'); var apiServer = module.exports; var routes = require('./routes.js'); // Routes file from above. var req, res, controller, action, serverInfo, httpServer; apiServer.start = function(){ prepare(function(){ httpServer = http.createServer(handleRequest).listen(3000); }); }; // // We need to do this function, we need the local ip address of the // server. We use this local ip address in logs (mongoDb) so we can // refer to the correct server. // function prepare(callback){ var serverName = os.hostname(); dns.lookup(serverName, function(error, address){ if(error){ throw error; } serverInfo = { name: serverName, address: address }; callback(); }); } function getRoute(){ // loops through routes array, and picks the correct one... } function getAuth(callback){ // parses headers, async authentication (mongoDB). } function getRequestData(callback){ // req.on('data') and req.on('end'), getting request data. } function parseRequestData(callback){ // parse request data at this point. } function validateRequestData(callback){ // loop through route fields (see routes.js) and validate this data with the ones // from the request. } function requireControllerAndCallAction(){ // do actual job. } function handleRequest(request, response){ req = request; res = response; req.route = getRoute(); // First step for a request, syncronous. if(req.route === false){ // 404... } // If in the routing schema access was "auth", // this route requires authentication, so do that... if(req.route.access === 'auth'){ getAuth(function(error, user){ if(error){ // 401 } else { req.user = user; } } } if(req.method === 'POST' || req.method === 'PUT'){ // Async functions. getRequestData(function(){ parseRequestData(function(){ validateRequestData(function(){ requireControllerAndCallAction(); }); }); }); } else { requireControllerAndCallAction(); } } </code></pre> <p>As you can see, some functions are asyncronous (getAuth, getRequestData) and some are syncronous (parseRequestData, validateRequestData).</p> <p>Now here is the thing:</p> <p>Request 1. comes in with method POST, url '/users' and data:</p> <ul> <li>fullName = 'Rick'</li> <li>email: 'rick@'</li> <li>password: 'a'</li> </ul> <p>So we loop through the workflow of the API:</p> <ol> <li><p>get the current route (controller: users, action: create) see the second array element in routes.js</p></li> <li><p>get the request data and on callback: a. parse data b. validate data</p></li> </ol> <p>Now lets IMAGINE, the validation of the data takes 5 seconds (which is retarded, but just for example) and during that validation, a new request comes in, the new request is not handled untill the previous one was finished right?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload