Зменшення жирових каналів у Феніксі - DEV
У цій статті ми обговоримо підхід, який ми застосували у проекті Фенікса. Канали були важливою частиною рішення, враховуючи те, що програма включає функції співпраці в режимі реального часу.

У нас був специфічний модуль каналу зі збільшенням кількості функцій обробника повідомлень. Що стосується дизайну, ми вважали, що наявність усіх взаємодій, керованих лише одним модулем каналу, все ще має сенс. Однак ми почали помічати, що сам модуль виходить з-під контролю, з великою кількістю не пов'язаної логіки та великою кількістю рядків коду. З цієї причини ми почали думати про те, як розділити код на різні модулі, але таким чином, що все ще працює, використовуючи лише один канал Фенікса.
Проблема
Скажімо, ми хочемо реалізувати багатоступеневий інтерфейс майстра, який має певну спільну взаємодію на кожному кроці. Це означає, що всі в групі працюватимуть на одному кроці в певний момент. Ось як ми спочатку реалізували цей майстер.
Як ви вже могли помітити, цей підхід погано масштабується. Оскільки до майстра додається більше дій за кроки та більше кроків, модуль каналу стає все більш і більш складним.
Розбиття логіки на різні модулі
Створення конкретних модулів для кожного кроку є, мабуть, найбільш природним рішенням нашої проблеми, тому ми спробували це:
Досить просто. Ми просто переносимо логіку до виділених модулів і одночасно додаємо якийсь тривіальний код, який делегує з модуля каналу. Ну, є проблема. Це рішення не компілюється 🙈!
У нас є проблеми з функцією трансляції/3, яку не можна знайти в контексті модуля FirstStep. Те ж саме сталося б, якби ми використовували будь-яку з доступних функцій, наданих Phoenix.Channel, як push/3, reply/2 тощо.
Шукаємо відсутні функції
Усі ці функції для конкретного каналу доступні в нашому WizardChannel, оскільки у нас є такий рядок:
Ми не можемо просто зробити те ж саме у наших допоміжних модулях, таких як MyExampleAppWeb.WizardChannel.FirstStep, оскільки цей рядок робить більше, ніж імпортує купу функцій: він визначає процес, який буде виникати під час виконання і буде відповідальним за обробку всіх повідомлень рухаючись туди-сюди в нашому веб-з'єднанні.
Рішення досить просте. Ми можемо безпосередньо імпортувати необхідні функції, визначені в модулі Phoenix.Channel. Немає перешкод для доступу до цих функцій, і вони є частиною загальнодоступного API фреймворку (хоча простіше знайти приклади повного використання модуля Phoenix.Channel в офіційній документації)
Робочим рішенням для нашого FirstStep є наступне:
Народжується новий DSL
Давайте на мить подивимося, як виглядає наш модуль WizardChannel після додавання ще кількох кроків та функцій обробника: