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

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 7

      +3
      Хорошая штука, радует, что сделали простой. Хотя если что серьезное — то я бы смотрел все же в сторону ZeroMQ или nanomsg так как позволит в одной инфраструктуре получить и IPC и сетевое взаимодействие если придется на разные машины разносить + разные топологии
        0
        Спасибо, буду знать, что под nodejs уже появились биндинги 0mq
          0
          давно-давно, еще с версии 0.3.х
            0
            Очень давно работал с nodejs, тогда вообще ничего не было для mq. Мне пришлось писать свой драйвер для amqp (rabbitmq), но, к сожалению, компания не разрешила раскрыть исходники :(
          –1
          например вот хороший — github.com/JustinTulloss/zeromq.node
        0
        Добрый день! К сожалению этот комментарий не по теме, но иного способа связаться с вами не нашел. Вы писали статью www.pvsm.ru/javascript/26295 хотел бы с вами связаться по поводу написания фреймворка под node.js Как с вами связаться? Или напишите мне khusamov@yandex.ru

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

        Самое читаемое