2014-04-09 32 views

risposta

15

ci sono alcune piccole differenze:

  • Ovviamente, il gen_server gestisce calchi in handle_cast e messaggi "normali" in handle_info.
  • Un cast non fallisce mai; restituisce sempre ok. L'invio di un messaggio con ! non riesce con badarg 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 per gen_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.

4

Oltre al post di legoscia, direi che è più facile tracciare l'API di funzione dedicata rispetto ai messaggi. Soprattutto in ambiente di produzione.