Il Reactor Pattern è un Design Pattern per la programmazione orientata agli eventi e rientra nella categoria dei pattern concorrenti. Si applica ad un modello Client-Server in cui le richieste da parte dei client possono arrivare in qualsiasi momento in maniera concorrente. Viene anche chiamato dispatcher di eventi o notificatore.

Applicazione modifica

Questo pattern trova applicazione in quei sistemi in cui il server deve gestire le richieste dei client in maniera concorrente senza:

  • bloccarsi indefinitivamente gestendo una singola richiesta,
  • troppe difficoltà per aggiungere nuove funzionalità.

Struttura modifica

La soluzione prevede un Dispatcher che invia le richieste dei client al corrispondente gestore, disaccoppiando le componenti software di carattere generale da quelle specifiche dell'applicazione.

Componenti modifica

  • Risorsa: un oggetto che rappresenta una risorsa del sistema operativo utilizzato dai client, su cui le operazioni possono essere bloccanti.
  • Demultiplexer sincrono di eventi: resta in attesa di eventi su un set di handle. In C/C++ nei sistemi UNIX questo può essere implementato con la chiamata di sistema select().
  • Inizializzatore del dispatcher: definisce i metodi per registrare, rimuovere e richiamare gli oggetti che gestiscono gli eventi (event handler).
  • Event handler: è un'interfaccia generica che espone il metodo gestisci_evento(). Le classi derivate implementano questo metodo secondo la loro necessità (fanno l'override del metodo)

Dinamica modifica

  • L'applicazione registra un gestore di eventi (event handler) concreto sull'inizializzatore del dispatcher e gli fornisce un riferimento alla risorsa corrispondente.
  • L'inizializzatore crea un'associazione tra la risorsa su cui avverrà un evento e l'event handler in grado di gestirlo.
  • quando un evento viene rilevato su una risorsa, il demultiplexer sincrono chiama la funzione gestisci_evento() dell'event handler corrispondente.

Proprietà modifica

I benefici apportati da questo pattern di programmazione sono un demultiplexing indipendente dall'applicazione e quindi riutilizzabile, oltre a modularità, estensione di funzionalità configurabilità molto elevate.

Si riscontrano però anche alcuni svantaggi:

  • applicabilità ristretta: gli eventi devono essere riferiti a oggetti del sistema operativo e quest'ultimo deve fornire una chiamata di sistema corrispondente alla select() in Unix.
  • non c'è prelazione: se un gestore di eventi chiama una funzione bloccante tutto il sistema si blocca. Le funzioni gestori di eventi devono quindi ritornare in tempi molto brevi per massimizzare la concorrenza
  • il debug è complicato in quanto il controllo oscilla tra demultiplexer e event handler.

Bibliografia modifica

  • Yves Roudier, "Distributed Systems and Middleware", Institut Eurécom 2015

Voci correlate modifica