Страницы

среда, 10 июля 2013 г.

Node.js + Redis. В очередь ...

Допустим на сервере нужно выполнить какую-нибудь дорогостоящую операцию, а выполнять ее непосредственно в ответ на запрос пользователя, особенно если таких запросов тысяч несколько в секунду - не хотелось бы. Предлагаю построить запросы в очередь и грузить апельсины бочками :). Приведенный ниже код решает вопрос каждые 20 секунд партиями по 100 штук.


var dbIndex = 10, interval = 20000, key = 'stack', count = 100;
var express = require('express');
var app = express();
var redis = require("redis");
app.get('/', function(req, res){
 var client = redis.createClient();
 client.select(dbIndex, function() {
  client.on("error", function (err) {
   console.log("Error " + err);
  });   
  client.lpush(key, req.query.key, function() {
   console.log('Got key: ' + req.query.key);
   client.quit();
  });   
 });  
 res.send('Got key: ' + req.query.key + '. Thanks.'); 
});

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

(function schedule() {
 setTimeout(function() {
  var client = redis.createClient();
  client.select(dbIndex, function() {
   client.on("error", function (err) {
    console.log("Error " + err);
   });
   client.llen(key, function(err, llen) {    
    if (err) {
     console.log('Error ' + err);
    } else {
     if (llen != 0) {
      client.lrange(key, 0, count, function(err, reply) {
       if (err) {
        console.log('Error ' + err);
       } else {
        console.log(reply);       
        process.nextTick(function() {
         for (var i=0; i<reply.length; i++) {
          console.log('Key ' + reply[i] + ' is processed');
          client.lrem(key, 1, reply[i], redis.print);
         }
         client.quit();
        });
       }       
      });
     } else {
      console.log('Stack is empty');
      client.quit();
     }
    }    
   });   
  });  
  schedule();
 }, interval);
}());

Открываем блокнот, создаем файл app.js, копируем в него код, сохраняем.
Не забываем установить Express и node_redis:
- npm install express
- npm install redis
Запускаем redis-server, выполняем app.js.
Через 20 секунд получаем подобную картину:

Отправляем серверу несколько ключей:

После очередного цикла обработки данных наблюдаем следующее:

Данные обработаны, стек снова пуст.