Javascript-форум (https://javascript.ru/forum/)
-   Node.JS (https://javascript.ru/forum/node-js-io-js/)
-   -   Получение ответа из другого модуля (https://javascript.ru/forum/node-js-io-js/77213-poluchenie-otveta-iz-drugogo-modulya.html)

acerbis 06.04.2019 22:22

Получение ответа из другого модуля
 
Всем доброго времени суток. Я недавно начал применять node js в реальных проектах, но все еще часто натыкаюсь на грабли, в первую очередь архитектурные, особенно после очень тесного общения с PHP, где для меня все просто и так знакомо (получил запрос - обработал - отдал ответ, никакой асинхронности, коллбэков и т.п.).

Я разрабатываю приложение, позволяющее руководству колл центра управлять его работой.

В приложении есть два модуля, Ami для взаимодействия с Asterisk Manager Interface (телефония) и ApiServer для приема запросов от пользователей (грубо говоря fastify с прописанными маршрутами).
Я решил жестко не связывать модули друг с другом, используя require a в b и require b в a, а настроить связь через pub sub.

В результате я получил два совершенно автономных модуля, которые ничего не знают друг о друге и занимаются своими делами, но я столкнулся с огромным подводным камнем.

Если старший смены захочет убрать агента из очереди все отработает замечательно, на ApiService придет запрос, он отправит сообщение, Ami примет сообщение и отправит в астериск команду на удаление агента.
Но что если старший смены захочет получить статус агента, глубину очереди и т.п?

Тогда Api серверу нужно не просто отправить сообщение в Ami, а получить на него ответ и отдать его клиенту в контексте обработки этого запроса.

И тут пошли хождения по мукам, решением "в лоб" было зарекваерить Ami в ApiService и вызывать метод из него, но оно мне не нравилось потому что тогда нарушало принцип независимости модулей друг от друга.

Я придумал другое решение: при запросе на сервер Api я генерирую uuid запроса и помещаю коллбэк, в котором происходит отдача ответа пользователю в специальный пул, после чего отправляю сообщение в модуль Ami.

Обработчик в модуле Ami вытаскивает данные из астериска, после чего отправляет их, вместе с uuid запроса в специальный канал pub sub, на который подписан пул в модуле Api и который при поступлении сообщения вызывает связанный с этим uuid коллбэк.

Работать то оно работает, но из-за отсутствия опыта я не могу понять насколько такое решение приемлимо и оптимально.

В качестве альтернативы я написал свой модуль в котором модуль может запросить данные у другого:
let response = await ModuleRequest.request('channel', 'topic', {
data: {},
timeout: 1000
});

А другой модуль может ответить ему:
ModuleRequest.on('channel', 'topic', (data) => {
//SomeActions
return 'some data';
});

Но опять же, насколько такой подход удачен с точки зрения архитектуры? Как обычно решаются подобные задачи, подскажите пожалуйста.


Часовой пояс GMT +3, время: 00:12.