Slăbirea canalelor de grăsime din Phoenix - DEV

În acest articol, vom discuta despre o abordare pe care am aplicat-o într-un proiect Phoenix. Canalele au fost o parte importantă a soluției, dat fiind că aplicația include funcții de colaborare în timp real.

grăsime

Aveam un modul de canal specific, cu un număr tot mai mare de funcții de gestionare a mesajelor. În ceea ce privește designul, am crezut că a avea toate interacțiunile gestionate de un singur modul de canal încă avea sens. Cu toate acestea, am început să observăm că modulul în sine a scăpat de sub control, cu o mulțime de logici fără legătură și un număr mare de linii de cod. Din acest motiv, am început să ne gândim cum să împărțim codul în diferite module, dar într-un mod care funcționează încă folosind un singur canal Phoenix.

Problema

Să presupunem că vrem să implementăm o interfață de asistent în mai mulți pași care să aibă un fel de interacțiune colaborativă în timpul fiecărui pas. Înseamnă că toată lumea din grup va lucra la același pas, la un moment dat. Iată cum am implementat inițial acest vrăjitor.

După cum probabil ați observat deja, această abordare nu se amplifică bine. Pe măsură ce se adaugă mai multe acțiuni în cadrul pașilor și mai mulți pași în sine, modulul de canal devine din ce în ce mai complex.

Împărțirea logicii în diferite module

Crearea de module specifice pentru fiecare pas este probabil cea mai naturală soluție la problema noastră, așa că am încercat-o:

Destul de simplu. Doar mutăm logica către module dedicate și, în același timp, adăugăm un cod trivial care delegă de la modulul de canal. Ei bine, există o problemă. Această soluție nu compilează 🙈!

Avem probleme cu funcția broadcast/3 care nu se găsește în contextul modulului FirstStep. Același lucru s-ar întâmpla dacă am folosi oricare dintre funcțiile disponibile furnizate de Phoenix.Channel cum ar fi push/3, reply/2 și așa mai departe.

În căutarea funcțiilor lipsă

Toate acele funcții specifice canalului sunt disponibile în WizardChannel, deoarece avem această linie acolo:

Nu putem face pur și simplu același lucru în modulele noastre auxiliare, cum ar fi MyExampleAppWeb.WizardChannel.FirstStep, deoarece această linie face mai mult decât să importe o grămadă de funcții: definește un proces care va fi generat în timpul rulării și va fi responsabil pentru gestionarea tuturor mesajelor mergând înainte și înapoi în conexiunea noastră web.

Soluția este destul de ușoară. Putem importa direct funcțiile necesare definite în modulul Phoenix.Channel. Nu există nici un impediment pentru accesul la aceste funcții și fac parte din API-ul public al cadrului (deși este mai ușor să găsiți exemple de utilizare completă a modulului Phoenix.Channel în documentația oficială)

O soluție de lucru pentru FirstStep este următoarea:

Se naște un nou DSL

Să căutăm o clipă cum arată modulul nostru WizardChannel după ce am adăugat încă câțiva pași și funcții de gestionare: