Magento fundamentals: che differenza c'è tra eventi e plugin?
Lettura 5 minutiI plugin sono una novità introdotta da Magento 2 e rappresentano un nuovo modo di estenderne le funzionalità.
Purtroppo, però, come recita una famosa legge, quando in mano abbiamo un martello, tutto il mondo ci sembra un chiodo. In altre parole, spesso si ricorre ai plugin anche quando non ce ne sarebbe bisogno.
In questo articolo approfondiremo le differenze tra i plugin e i cari vecchi eventi e cercheremo di capire quando ha senso usare gli uni o gli altri per personalizzare la piattaforma.
La differenza tra dipendenze deboli e forti
Una importante differenza tra eventi e plugin è costituita dal fatto che i primi costituistono dipendenze deboli mentre i secondi dipendenze forti, rispettivamente indicate in inglese come soft dependencies e hard dependencies.
Cerchiamo di capire in cosa consiste tale differenza.
Se un observer dipende da un evento che per qualche motivo (intenzionale o meno) non è più dispacciato, l’observer non si attiva e in apparenza tutto continua a funzionare. Naturalmente qualcosa non sta funzionando ma senza compromettere la navigabilità del sito.
In questo caso si dice che la dipendenza (dall’evento) è di tipo debole.
I plugin si comportano in maniera diversa: se un plugin dipende da una classe che per qualche motivo non è presente a sistema, viene generato un runtime exception che rompe la navigabilità del sito.
In questo caso si dice che la dipendenza (dal plugin) è di tipo forte.
Conoscere questa differenza è importante perché può guidarci nella scelta dell’uno o dell’altro meccanismo quando dobbiamo applicare le nostre personalizzazioni.
Facciamo un paio di esempi; sono estremamente semplici giusto per rendere l’idea.
Se dobbiamo mostrare un messaggio nella pagina del carrello che indica quanto manca per ottenere la spedizione gratuita, potremmo utilizzare un evento (ad esempio il
sales_quote_collect_totals_after
). Se l’evento non viene dispacciato, non vogliamo che la navigabilità sia compromessa per un messaggio mancante, per quanto possa essere importante. L’evento sembra essere in questo caso la scelta migliore.Se dobbiamo impedire agli utenti di inserire ordini che non garantiscono una determinata marginalità di guadagno al negoziante, potremmo optare per un plugin. Se il plugin dipende da una funzionalità che viene meno, il sito si romperà e nessuno sarà in grado di piazzare ordini. Non è certo desiderabile compromettere la navigabilità ma potrebbe essere meglio che ricevere ordini in perdita. Il plugin in questo caso sembra essere una scelta migliore.
Ambito di applicazione
Sussistono dei limiti nell’ambito di applicazione di eventi e plugin che occorre conoscere.
Sin dai tempi di Magento 1, sappiamo che se nel punto in cui vogliamo applicare le nostre modifiche non viene dispacciato un evento, non possiamo contare su questo meccanismo.
Ci sono moltissimi eventi utili dispacciati da Magento, ma prima o poi ci imbatteremo in un punto di codice dove manca il dispatch di un evento.
I plugin sono più flessibili: consentono di agganciare qualsiasi metodo pubblico di qualsiasi classe, preferibilmente annotata con @api
.
☝ Le classi annotate con @api
garantiscono che le loro interfacce pubbliche non cambieranno a meno di un major o minor update.
Per approfondire: : https://devdocs.magento.com/guides/v2.4/extension-dev-guide/versioning/codebase-changes.html
Esistono tre tipi differenti di plugin:
- before plugin: consentono di intercettare (da qui il nome di interceptor) l’invocazione di un metodo e di modificare i suoi parametri;
- after plugin: consentono di intercettare il risultato dell’invocazione di un metodo e modificarlo, nonché di accedere ai parametri;
- around plugin: consentono di controllare l’esecuzione del metodo originale e di eventuali successivi plugin.
Una spiegazione più dettagliata dei plugin esula dagli obiettivi di questo articolo e per approfondire vi rimando alla documentazione ufficiale.
Mi interessa invece soffermarmi su alcuni aspetti legati alle prestazioni.
Uno sguardo alle prestazioni
L’esecuzione dei plugin e degli eventi ha un impatto sulle prestazioni perché fa aumentare lo stack di chiamate ma l’esecuzione di alcuni tipi di plugin è decisamente più onerosa.
Di seguito riporto una misurazione di tale impatto.
☝ Ho utilizzato Blackfire (uno strumento che consiglio caldamente) per profilare il tempo di esecuzione di un observer e di tre plugin; questi non fanno altro che aggiungere uno statement sleep(1)
, per forzare Blackfire a segnalarli come potenziali colli di bottiglia.
Observer: 225 µs di CPU time
Before plugin: 1.53 ms di CPU time
After plugin: 645 µs di CPU time
Around plugin: 17.7 ms di CPU time
Possiamo notare come gli around plugin sono più lenti di almeno un ordine di grandezza rispetto agli altri.
Il vero problema è che spesso sono utilizzati a sproposito: se non abbiamo bisogno di impedire l’esecuzione del metodo originale o quella dei plugin successivi, gli around plugin non ci danno niente di più, aggiungono inutilmente del tempo di calcolo in più.
In questo caso è raccomandato scegliere un tipo di plugin più adatto allo scopo.
Sebbene una singola chiamata di pochi microsecondi o millisecondi non influisca più di tanto sulle prestazioni, è bene considerare che in una installazione di default di Magento ci sono centinaia di chiamate dovute a observer e plugin, senza contare quelle aggiunte da moduli e personalizzazioni di terze parti.
Il tempo di esecuzione totale di tali chiamate può avere quindi un impatto non indifferente sulle prestazioni, soprattutto quando i plugin sono utilizzati impropriamente.
☝ Doverosa precisazione: anche gli eventi possono impattare negativamente sulle prestazioni se non si adottano le necessarie linee guida. Per approfondire, fare riferimento alla documentazione ufficiale.
Conclusioni
Abbiamo visto quali sono le principali differenze tra eventi e plugin e che non tutti i plugin sono dello stesso tipo.
Quando si sviluppa su Magento, adottare il giusto approccio può fare la differenza in termini di prestazioni.
Ricordiamo che gli eventi costituiscono ancora una valida scelta, perciò teniamoli in considerazione la prossima volta che dovremo applicare le nostre personalizzazioni.
Articolo scritto da
Alessandro Ronchi☝ Ti piace quello che facciamo? Unisciti a noi!