0

POST /add-request - adds new request

POST /get-request - returns first (oldest) request

I have many Java apps which are called "slaves". Their job is to call POST /get-request to get request to process and after processing it save it to database. All requests are stored in mongoDB. /add-request just adds request to db. /get-request uses findAndModify mongo query to get first request from queue and set its status to "processing" (this status is required to avoid situation when same request is taken twice from DB). For now slaves just call api every 2 seconds. But I want to use some long-polling here. It should look like this:

  1. I have to keep slave requests in a queue.
  2. I have to set timeout foreach slave request to send for example 404 after 4 seconds if there is no new request.
  3. When new request is added through /add-request I have to take first slave request from queue, remove it from this queue, get request from DB and send it to this slave.

so let's say i have to handlers (i am using express):

function addRequest(req,res,next){ 
    // add request to db and check if there is waiting slave request in queue
    // if there is one remove it from queue, clear timeout on it, get request from db
    // and send it to slave
}

function getRequest(req,res,next){ 
    // get request from db - if there is no request add this slave request to queue
    // set timeout to send 404 after 4 seconds
}

The problem is with the queue - I tried many qpproaches but there is no any "synchronization" and I can't make it works... Is it possible to ensure consistency in a queue when two express handlers operate on it in the same time? The problem is with removing requests from queue after timeout. I have to search for request in queue using some uid and then removing it...

Maybe there is some library/tool to accomplish my goal?


404 is returned when there is no request for slave to process. I want to slave get the new request as fast as possible - so if I would return response instantly (new request or 404 when there is no request) then each slave would have to call api all the time non-stop and it would have impact on server performance I think. So I wanted each slave to "hold" on request for 4 seconds on server before returning any data.

4

1 回答 1

1

Interesting technique to ensure you process queued requests asap.

In terms of synchronising your queue, there is no need to as Node is single threaded. You don't need to worry about multithreading issues like in Java which is really nice I think.

Here's some rough code which might work. Add error handling and proper Mongo db calls.

var queue = {};

function addJob(req,res,next){ 
  var job = req.body;
  mongo.add(job, function(err){ // pseudo code to add request to db. 
    res.send(200); // request is stored, no need to keep the client waiting.
    // find a random slave in the queue:
    for(var slaveName in queue) {
      queue[slaveName].send(job);
      delete queue[slaveName];
      break;
    }      
  });
}

function getRequest(req,res,next){ 
  // get request from db - if there is no request add this slave request to queue
  mongo.get(..., function(err, job){
    if(job){
      return res.send(job);
    }
    // no job, add slave to queue:
    var slaveName = req.body;
    queue[slaveName] = res;

    // set timeout to send 404 after 4 seconds
    setTimeout(function(){
      delete queue[slaveName];
      res.send(404);
    }, 4000);
  }
}
于 2013-06-10T13:19:46.177 回答