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

ссылка на оригинал статьи http://habrahabr.ru/post/191192/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *