...

пятница, 23 августа 2013 г.

NodeJS Cluster-hub. Обмен сообщениями в cluster, запросы, межпроцессные эксклюзивные блокировки (критические секции)

Работая в очередной раз с модулем cluster, у меня возникла необходимость обмена сообщениями между рабочими процессами. К сожалению стандартный функционал модуля позволяет отправлять сообщения только с master процесса на worker, и в обратном направлении. При этом нет возможности получить какой-то ответ на сообщение, а очень хотелось бы. Поэтому я написал модуль cluster-hub. Возможно кому-нибудь он пригодится.

Модуль позволяет



  • Отправлять сообщения master->worker, worker->master, master->master

  • Отправлять запросы и получать ответы (через callback)

  • Использовать эксклюзивные блокировки по ключу (критические секции)


Кому интересно — прошу под кат.


Обмен сообщениями




Самый простой функционал — просто отправка сообщений в другие процессы. Есть возможность отправлять сообщения из master в worker, из worker в master, из master->master.

var Hub = require('cluster-hub');
var cluster = require('cluster');

var hub = new Hub(cluster);
if (cluster.isMaster) {
var worker = cluster.fork();

hub.on('master-to-master', function (data) {
console.log('master-to-master received');
});
hub.on('worker-to-master', function (data) {
console.log('worker-to-master received');
});

hub.sendToMaster('master-to-master', 1);
hub.sendToWorker(worker, 'master-to-worker');
} else {
hub.on('master-to-worker', function () {
console.log('master-to-worker received');;
process.exit();
});

hub.sendToMaster('worker-to-master', 2);
}


Отправка запросов




Данный функционал позволяет отправить запрос из одного процесса в другой и получить результат внутри callback функции. Пример сам за себя все скажет:

var Hub = require('cluster-hub');
var cluster = require('cluster');
var hub = new Hub(cluster);

if (cluster.isMaster) {
// in master process
hub.on('sum', function (data, sender, callback) {
callback(null, data.a + data.b);
});

var worker = cluster.fork();
} else {
//in worker process
hub.requestMaster('sum', {a: 1, b:2}, function (err, sum) {
console.log('Sum in worker: ' + sum);
process.exit();
});
}




По аналогии можно использовать метод requestWorker, чтобы с master процесса вызвать метод на worker процессе.

Эксклюзивные блокировки / Критические секции




Данный функционал позволяет получить эксклюзивный доступ к какому-либо ресурсу одному из процессов (неважно — master или один из worker). Если worker процесс прекращает свою работу, не вызвав unlock для заблокированного ресурса — ресурс освободится автоматически.

var Hub = require('cluster-hub');
var cluster = require('cluster');

var hub = new Hub(cluster);

if (cluster.isMaster) {
var worker = cluster.fork();

hub.lock('foo', function (unlock) {
console.log('foo lock in master');
setTimeout(unlock, 1000);
});


} else {
hub.lock('foo', function (unlock) {
console.log('foo lock in worker 1');
setTimeout(unlock, 500);
});

hub.lock('bar', function (unlock) {
console.log('bar lock in worker');
unlock();
})

hub.lock('foo', function (unlock) {
console.log('second foo lock in worker');
unlock();
process.exit();
})
}


исходные коды модуля доступны тут: github.com/sirian/node-cluster-hub


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers. Five Filters recommends: 'You Say What You Like, Because They Like What You Say' - http://www.medialens.org/index.php/alerts/alert-archive/alerts-2013/731-you-say-what-you-like-because-they-like-what-you-say.html


Комментариев нет:

Отправить комментарий