Получение ответа из другого модуля
Всем доброго времени суток. Я недавно начал применять 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. |