简体   繁体   中英

Simplest approach to Node.js request serialisation

I've got the classic asynchronous/concurrency problem that folks writing a service in Node.js at some point stumble into. I have an object that fetches some data from an RDBM in response to a request, and emits a fin event (using an EventEmitter ) when the row fetching is complete.

As you might expect, when the caller of the service makes several near-simultaneous calls to it, the rows are returned in an unpredictable order. The fin event is fired for rows that do not correspond to the calling function's understanding of the request that produced them.

Here's what I've got going on (simplified for relevance):

var mdl = require('model.js');

dispatchGet: function(req, res, sec, params) {
    var guid = umc.genGUID(36);

    mdl.init(this.modelMap[sec], guid);

    // mdl.load() creates returns a 'new events.EventEmitter()'

    mdl.load(...).once('fin', 
      function() { 
        res.write(...);

        res.end();
      });

 }

A simple test shows that the mdl.guid often does not correspond to the guid .

I would have thought that creating a new events.EventEmitter() inside the mdl.load() function would fix this problem by creating a discrete EventEmitter for every request, but evidently that is not the case; I suppose the same rules of object persistence apply to it as to any other object, irrespective of new .

I'm a C programmer by background: I can certainly come up with my own scheme for associating these replies with their requests, using some circular queue or hashing scheme. However, I am guessing this problem has already been solved many times over. My research has revealed many opinions on how to best handle this--various kinds of queuing implementations, Futures , etc.

What I'm wondering is, what's the simplest possible approach to good asynchronous flow control here? I don't want to get knee-deep in some dependency's massive paradigm shift if I don't have to. Is there a relatively simple, canonical, definitive solution, and/or widespread consensus on which third-party module is best?

Could it be that your model.js looks something like this?

module.exports = {
  init : function(model, guid) {
    this.guid = guid;
    ...
  }
};

You have to be aware that the object you're passing to module.exports there is a shared object, in the sense that every other module that runs require("model.js") it will receive a reference to the same object .

So every time you run mdl.init() , the guid property of that object is changed, which would explain your comment that "...a simple test shows that the mdl.guid often does not correspond to the guid" .

It really depends on your exact implementation, but I think you'd want to use a class instead:

// model.js
var Mdl = function(model, guid) {
  this.guid  = guid;
};

Mdl.prototype.load = function() {
  // instantiate and return a new EventEmitter.
};

module.exports = Mdl;

// app.js
var Mdl = require('model.js');
...
var mdl = new Mdl(this.modelMap[sec], guid);
mdl.load(...)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM