nodejs — блокировки, ключи и рабочие элементы — синхронный код и ожидание в мире javascript

#javascript #synchronization #task #worker

#javascript #синхронизация #задача #рабочий

Вопрос:

классическая проблема, на этот раз возникшая в среде nodejs, и, подумав об этом некоторое время, я не уверен, какой лучший способ решить эту проблему.

у меня есть:

  • 4 ресурса — давайте назовем эти «ключи».
  • X задачи — давайте назовем эти «блокировки».
  • Y рабочих — на самом деле от 1 до 4.

Комбинация из 1 задачи и 1 ресурса (неважно, какого) — это задание, которое должен выполнить рабочий: или, другими словами, рабочий открывает замок ключом 🙂

Я хочу открыть, чтобы открыть эти блокировки как можно быстрее, используя мои ресурсы и рабочие.
Каждый рабочий должен попытаться захватить ключ, захватить блокировку, разблокировать блокировку, затем вернуть свой ключ обратно.
Когда ключи недоступны, рабочему нужно подождать, пока они не появятся.
Когда все блокировки открыты, рабочие могут идти домой и наслаждаться пивом.

как бы вы решили это в среде javascript / nodejs?
не стесняйтесь использовать redis / mongo / любой инструмент, который вам нужен, чтобы это произошло.

Пожалуйста, помогите мне сегодня пораньше отправить моих рабочих домой! 🙂

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

1. Это вопрос домашнего задания? Создайте своих рабочих, дайте каждому из них ключ и обратный вызов. Когда они выполнят обратный вызов, дайте им другой ключ…

2. не домашнее задание, реальная живая проблема, которая настолько классическая, что звучит как домашнее задание. Я решил это раньше с Java, где у вас есть все инструменты для выполнения заданий — блокирующие очереди, ожидание и уведомление, семафоры и так далее. в javascript это немного сложнее, потому что все асинхронно. Я уже искал этот abit в Google, но все ответы всегда связаны только с одной блокировкой и 2 процессами, ожидающими ее. ситуация здесь более сложная (но, возможно, решаемая таким же образом, и я просто еще не понял этого). Если вы хотите ответить, пожалуйста, сделайте это в форме ответа с более подробной информацией.

3. Если ваша проблема требует, чтобы задачи одновременно взаимодействовали с одними и теми же данными в режиме записи, тогда может потребоваться более подробное решение — в противном случае это действительно так, как сказал Олег. изучая nodejs.org/api/child_process.html это помогло бы справиться с обычными проблемами.

Ответ №1:

Вы можете использовать RabbitMQ для решения этой проблемы. Вы можете поддерживать 4 разные очереди для каждого рабочего. Каждый рабочий будет привязан к отдельной очереди.

Таким образом, рабочий будет ждать, пока в очереди не появится сообщение. Как только в вашем случае появится сообщение о ключе, рабочий начнет обработку, завершит задачу и снова будет ждать следующего ключа.

Будет один издатель и несколько слушателей, т.Е. Один супервизор и несколько рабочих. Вы даже можете реализовать пакетную обработку, если требуется.

например:

   connection.on('ready', function () {
    connection.queue("queue_name", function(queue){
        connection.exchange('exchange_name', {type: 'topic', confirm: true},function(exchange){
            queue.bind('exchange_name'); 
            queue.subscribe({ack: true},function (message, headers, deliveryInfo) {
                try{
                    var data = unescape(message.data);
                    processMessage(data); // whatever needs to be done with the received message
                    queue.shift();
                }
                catch(e){
                    console.log('Some error occured.'  e);
                }
            })
        })
    })
})
  

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

1. На самом деле я решил это немного по-другому, не используя RabbitMQ, но применяется тот же основной принцип: используйте что-то внешнее для обеспечения механизма блокировки. в моем случае это был Kue Redis. требовалась только одна очередь заданий с 4 рабочими, прослушивающими это имя задания и выполняющими свои действия. После выполнения каждого задания я удалял его, чтобы я мог сказать, что все задания были выполнены, когда в Kue больше не было заданий такого рода.