Stavo lavorando nonostante un problema e ho notato del codice in cui un programmatore precedente stava trasmettendo messaggi usando la convenzione standard di PID! Messaggio. Ho usato gen_server: cast/2. Mi stavo chiedendo se qualcuno potesse spiegarmi le differenze e le considerazioni critiche nella scelta tra i due?Erlang: differenza tra l'utilizzo di gen_server: cast/2 e il passaggio di messaggi standard
risposta
ci sono alcune piccole differenze:
- Ovviamente, il gen_server gestisce calchi in
handle_cast
e messaggi "normali" inhandle_info
. - Un cast non fallisce mai; restituisce sempre
ok
. L'invio di un messaggio con!
non riesce conbadarg
se si sta inviando un messaggio a un atomo che non è attualmente registrato da un processo. (L'invio di un messaggio a un pid non causa mai un errore, anche se il processo è morto.) - Se gen_server è in esecuzione su un nodo remoto che non è attualmente connesso al nodo locale, allora
gen_server:cast
genererà un processo in background per stabilire la connessione e inviare il messaggio e restituire immediatamente, mentre!
restituisce solo una volta stabilita la connessione. (Vedi il codice pergen_server:do_send
.)
Per quanto riguarda quando scegliere l'uno o l'altro, è principalmente una questione di gusti. Direi che se il messaggio potrebbe essere pensato come una funzione API asincrona per il server gen, allora dovrebbe usare il cast, e avere una specifica funzione API nel modulo callback gen_server. Cioè, invece di chiamare direttamente gen_server:cast
, in questo modo:
gen_server:cast(foo_proc, {some_message, 42})
effettuare una chiamata di funzione:
foo_proc:some_message(42)
e attuare tale funzione come il cast diretta sopra. Questo incapsula il protocollo specifico di gen_server all'interno del proprio modulo.
Nella mia mente, i messaggi "semplici" verrebbero usati per gli eventi, al contrario delle chiamate API. Un esempio potrebbe essere i messaggi di monitoraggio, {'DOWN', Ref, process, Id, Reason}
e gli eventi di un tipo simile che potrebbero verificarsi nel sistema.
Oltre al post di legoscia, direi che è più facile tracciare l'API di funzione dedicata rispetto ai messaggi. Soprattutto in ambiente di produzione.