2012-10-20 7 views
6

Nel mio server websocket sviluppato con Erlang, mi piacerebbe utilizzare un timer (start_timer/3), per ciascuna connessione, per terminare la connessione se il timeout è trascorso senza ricevere un "ping" dal client.La scala di timer Erlang è in scala?

I timer di Erlang si adattano bene, supponendo che avrò un numero elevato di connessioni client?

risposta

8

Che cos'è un numero elevato di connessioni? Erlangs VM utilizza internamente una rotella del timer per gestire i timer in modo che riduca abbastanza bene fino a qualche migliaio di connessioni. Quindi potresti incontrare dei problemi.

Generalmente il trucco consiste nel raggruppare i pids sui timer. Questo è anche ciò che i kernel tendono a fare. Se ad esempio hai un timer che deve essere svegliato a 200 ms, ti pianifichi prima del tempo, non sul prossimo, ma il prossimo 200ms timer di nuovo. Ciò significa che dovrai attendere almeno 200ms e forse 400ms, mentre 300ms saranno tipici. Approssimando i timer come questo, sei in grado di eseguire molti altri in quanto puoi avere un singolo timer per svegliare un gran numero di processi in un colpo solo. Ma a seconda della frequenza del timer e della quantità di timer, uno standard send_after/3 potrebbe essere sufficiente.

In ogni caso, inizierei assumendo che sia in grado di ridimensionare e quindi gestire il problema se non fosse possibile eseguendo un timing approssimativo come previsto sopra.

0

Un modello comune per questo tipo di server è quello di sfruttare i processi leggeri di Erlang e creare un server per connessione.

È possibile costruire ad esempio il server utilizzando un comportamento gen_server che forniscono sia

  • la diversa condizione per gestire la connessione (in attesa di una connessione, login, ...) con la variabile Stato,
  • timeout individuale per ogni connessione e in ogni stato, gestito dalla VM e dal comportamento OTP.

La cosa bella è che ogni server deve prendersi cura di un singolo client, quindi è molto più facile scrivere.

La fase di init dovrebbe avviare un server in attesa per la connessione,

Poi sulla connessione il server dovrebbe lanciare uno nuovo pronto per la prossima client (idealmente attraverso un supervisore lancio bambino simple_one_for_one) e passare il login passo o si qualunque voglio fare.

Troverete informazioni molto interessanti sul sito LearnYouSomeErlang, in particolare nel capitolo http://learnyousomeerlang.com/supervisors e seguenti.