febbraio 27, 2022

Considerazioni sul paradigma AnyCast

Quanti servizi attualmente in uso sono diventati dei grovigli di chiamate a funzioni/oggetti?
Photo by Alireza Khatami / Unsplash
  1. Premessa
  2. Orchestrare la comunicazione come un servizio
  3. Vantaggi
  4. Svantaggi
  5. Conclusione e relativi Disclaimer

Non ho considerato gli aspetti critici come sicurezza e distribuzione dei singoli servizi e relativi carichi ( di computazione e comunicazione), se non le relative indicazioni di base.

Premessa

Son passati 25 anni da quando venne pubblicata la RFC 2068 in cui vennero definiti i metodi per le comunicazioni HTTP/1.1, noti a qualsiasi sviluppatore che abbia dovuto interagire con qualsiasi comunicazione Browser-like.

Presentazione dei metodi per HTTP/1.1

Da allora la connessione al "server" ha assunto un ruolo sempre più simbolico, specie dall'avvento della diffusione di paradigmi SaaS e Paas. Ancora più rilevante è il passaggio da una connessione stateless a statefull (HTTP2.0), con interessanti conseguenze per l'evoluzione dei browser che di fatto hanno guidato l'evoluzione di interi servizi per mobile (ad esempio lo sviluppo di webApp dedicate, sino alle progressive webApp), così come l'avvento delle applicazioni desktop basate su Electron.

Ed è qui che emergono nuove necessità, come l'uso di funzionalità asincrone presenti nel server, progettate per supportare un carico specifico di lavoro senza che l'utente debba mantenere la sessione attiva. Da questo punto di vista, i pattern design Subs/Pubs e EventDriven acquisiscono appetibilità per qualsiasi software designer.  Il server passa da un monolite intricato di funzionalità, ad un grappolo di elementi più semplici, che offrono servizi (publisher) e richiedono l'esecuzione di particolari funzionalità (subscriber); questa evoluzione inizia prevalentemente dal concetto di EventDriven portato avanti da NodeJS, da cui ne segue una più facile implementazione di un design pattern ben noto.

da Wikipedia

Ogni singolo elemento del server è indipendente nel suo funzionamento: più facile da mantenere, più facile da riutilizzare; di contro, l'orchestrazione delle comunicazioni diviene la nuova sfida da superare (a.k.a microservizi e loro orchestrazione). Ed è qui che entra in gioco lo StatePattern: un pattern in grado di attivare/disattivare le opportune richieste, in base allo stato globale dell'applicazione.
Tanto comodo ed estremamente intuitivo che le attuali UI del terzo millennio parlano dialetti differenti, includendo tra le opzioni lo stesso identico pattern:

  • angular (JS)
  • react (JS/TS)
  • flutter (Dart)

Ed è qui che nasce la domanda: se condividessi lo stato della UI con il server, lasciando che ciascun singolo Publisher libero di decidere se inviare o meno una risposta, perchè non riconsiderare il ruolo delle API tramite HTTP?

La risposta è ovviamente sì, specie con l'introduzione degli webstream in cui anche lato server è possibile inviare una informazione al client, senza che questi ne faccia una richiesta esplicita. Ma, di questo passo, vien da sè che si può esagerare in una moltitudine di collegamenti punto-punto, quando esistono delle alternative.

Considerando qualsiasi scenario attuale, difficilmente la comunciazione considera solo un mittente ed un destinatario: specie in contesti a microservizi in cui la richiesta si ripercuote su molteplici microservizi. Pertanto, è corretto considerare una comunicazione "anycast" anche per il mondo "web"?

Secondo me sì.

Orchestrare la comunicazione come un servizio

Abbracciando il panorama commerciale, è evidente che ci sono sempre più realtà aziendali che per uno stesso progetto,assumono differenti sviluppatori freelance nell'arco del tempo. I motivi sono molteplici e non ne so nulla: ciò che riesco a rilevare sono le differenti modalità di progettazione che rimangono e permangono a lungo (esperienza diretta).

Se fosse possibile orchestrare la comunicazione tra servizio di interfaccia (human o machine) e tutte le sottoparti, diverrebbe facile poter incanalare gli sforzi duraturi e continui in alcune singole parti del progetto, lasciando ai freelance di turno, l'onere di considerare una singola sottoparte del progetto.

Quali tecnologie permettono di implementare un servizio AnyCast?

RabbitMQ permette di gestire lo scambio dei messaggi da una comoda interfaccia web, orchestrando tutte le Queue/Code egli Exchange/Switch di interscambio. Sarà sufficiente considerare uno dei linguaggi/librerie supportate, per sviluppare qualsiasi

MQTT  garantisce uno scambio rapido tra tutti i client appesi per specifici topic: basta fornire un wrapper idoneo, in cui gestire in maniera accorta a quali topic si ha diritto di accedere (in letture e/o scrittura).

ZMQ lascia al software designer la scelta di definire i centri di controllo delle comunicazioni, arrivando a gestire il tipo di comunicazione (a token, a semafori o asincrona).

Ci sono degli assenti? Sì, ad esempio Redis

Ho sempre usato Redis per il coordinamento tra microservizi rilasciati sulla medesima risorsa (pod, nodo, container, whatever). Mentre in scenari con molteplici client ho usato Redis come servizio di aggiornamento unidirezionale (e quindi lontano dal paradigma AnyCast).
Per mia scelta non ho mai implementato Redis come accesso per client esterni: se pensi che ci sia un modo, oppure hai avuto una esperienza diretta, scrivilo nei commenti (sicuramente posso impararne di più).


Se dovessi investire tempo e risorse in progetto, devo verificare tutti i pro ed i contro di ciascuna architettura: pertanto ecco una carrellata di vantaggi e svantaggi.

Vantaggi

Software semplice

Per quanto sia complesso il sistema, il risultato di una qualsiasi analisi top-down e successiva bottom-up mostrerebbe le unità atomiche da considerare. Per ciascuna di queste (o al più per ciascun gruppo di queste) è possibile identificare singole interfacce, singoli JSON (o protocol buffer) per avviare lo sviluppo del software e relativo unit-test.

Software riutilizzabile

Ovviamente, la stessa unità atomica presente in più punti del sistema, è costituita da un singolo codice che deve adattarsi al contesto in cui opera.

Suggerimento: il factory pattern è sicuramente la scelta preferita per cui adattare ciascuna singola unità atomica ad uno specifico contesto.

Organizzazioni delle comunicazioni

Come le ACL permettono di accedere a determinate funzioni, anche nei Broker è possibile considerare una diversificazione delle comunicazioni, senza modificare alcun servizio.

Costi contenuti grazie al testing automatizzato...

Durante il rilascio dei singoli microservizi e dei singoli client, il testing automatizzato è una parte fondamentale per testare il servizio complessivo.

Solo grazie a questo test è possibile monitorare comportamenti anomali e le ovvie performance di comunicazione/traffico tra le parti.

Svantaggi

...senza il testing (non solo automatizzato) non si fattura!

Oltre allo sviluppo del software è necessario investire risorse per automatizzare il testing di tutto il servizio. Le alternative sono molto più appetibili: lo stesso framework di testing usato per lo unit-test, in poche righe può concorrere per testare ambienti più complessi (se scritti con la stessa tecnologia).

Autenticazione sul Broker

A meno che il broker non dispone di un sistema di autenticazione comodo (come un token JWT), l'autenticazione dei client avviene tramite una password (spesso salvata nei file di configurazione o tramite cli).
Nota: Rabbitmq offre un comodo plugin web per creare virtualhost e credenziali utente.

AnyCast è un buon paradigma?

Considero come plausibile l'imminente aumento di richieste di integrazione di client da parte di terze parti, senza modificare nessun servizio presente. Non posso parlare di innovazione se il tutto si riduce ad un apigateway; è plausibile pensare che presto o tardi, determinati approcci saranno abbandonati e sostituiti, in virtù di una metodologia di lavoro efficiente e redditizia (non solo in termini economici). Un modo di lavorare che permetta a ciascun singolo utente di personalizzare ed adattare la configurazione dei microservizi.

Pertanto bisogna cambiare il paradigma e cominciare a considerare qualsiasi client, come un potenziale elemento che sia in grado di fornire servizi a terzi. Di conseguenza, non è immaginabile considerare il cloud, come unico centro di coordinamento di tutti i microservizi.

Disclaimer #1: esistono molteplici librerie per i client

Non mi sono soffermato sui client perchè ho sempre trovato molteplici  linguaggi di programmazione supportati. Oltre ai soliti noti (C, Python, Java) sovente trovo JS tramite uno opiù specifici npm.

Di recente ho trovato alcuni porting per Flutter sia per amqp, mqtt che zmq, con relativo supporto per Android ed iOS; alcuni hanno esteso il supporto per Windows, MacOS, iPadOS e Linux.

Disclaimer #2: RabbitMQ non è la panacea, ma è un buon inizio.

Permettimi un commento: RabbitMQ è uno dei broker con cui ho maggiore confidenza e con cui riesco a realizzare architetture distribuite.