user1153660
user1153660

Reputation: 413

ExpressJS and matching delayed responses with original requests

I am looking for a design pattern than can match a stream of answers with the original request and response objects.

Suppose I receive a web request for all dog pictures. I want to submit that request to a message queue so that a worker process can eventually handle it. When a worker machine grabs the dog picture request, it performs the work and submits the response to an answer queue which is being monitored by Express. As I process the incoming queue, I want to match up the dog picture response with the original request and response objects so I can return the dog list or process it further.

Two solutions occur to me, but each seems inelegant. I could keep a global reference to the original context, find it, then delete it from the global list.

Or I could create a subscription to the response queue and look for my answer among all the answers. This would work, but is brutally inefficient and its complexity rises geometrically. (10x10, 100x100, 1000x1000)

Upvotes: 0

Views: 638

Answers (1)

user1153660
user1153660

Reputation: 413

var express = require('express');
var app = express();
app.get('/doglist.txt', function(req, res){
  putReqIntoQueue(req,res,"dogs");
});
var theRequests ={};
var i = 0;
var giveUpSecs = 60;
var putReqIntoQueue = function(req,res,payload) {
   var index = 'index_'+i;
   i++
   var obj = {req:req,res:res,payload:payload,index:index}
   theReqests[index] = obj;
   var timeoutId = setTimeout(function(theIndex) {
      theRequest[theIndex].res.send('timeout error');
      delete theRequest[theIndex];
   }(index),giveUpSecs*1000);
   // insertIntoQueue(index,payload,timeoutId)
}
var onNewQueueResponse = function(index,payload,answer,timeoutId) {
   clearTimeout(timeoutId);
   if (index in theRequests) {
      var obj = theRequests[index];
      obj.res.send(payload);
      delete theRequests[index];
   } else {
      // must have already timed out
   }
}
// Queue("onNewMessage",onNewQueueResponse)

app.listen(3000);
console.log('Listening on port 3000');

This answer assumes some kind of queue that accepts work (insertIntoQueue) and then returns data when it is done through "onNewMessage" event. It times out after 60 seconds.

Upvotes: 1

Related Questions