2014-04-09 13 views

Antwort

15

Es gibt ein paar kleine Unterschiede:

  • Offensichtlich ist die gen_server Griffe Abgüsse in handle_cast und "normalen" Nachrichten in handle_info.
  • Eine Besetzung schlägt nie fehl; es gibt immer ok zurück. Das Senden einer Nachricht mit ! schlägt mit badarg fehl, wenn Sie eine Nachricht an ein Atom senden, das derzeit nicht von einem Prozess registriert wird. (Das Senden einer Nachricht an eine PID führt nie zu einem Fehler, auch wenn der Prozess tot ist.)
  • Wenn der gen_server auf einem Remote-Knoten ausgeführt wird, der derzeit nicht mit dem lokalen Knoten verbunden ist, wird gen_server:cast einen Hintergrundprozess generieren Herstellen der Verbindung und Senden der Nachricht und sofortiges Zurückgeben, während ! erst zurückkehrt, sobald die Verbindung hergestellt wurde. (Siehe den Code für gen_server:do_send.)

Als für die eine oder andere wählen, ist es vor allem eine Frage des Geschmacks. Ich würde sagen, wenn die Nachricht als eine asynchrone API-Funktion für den gen_server gedacht werden könnte, dann sollte sie cast verwenden, und haben eine bestimmte API-Funktion im gen_server Callback-Modul. Das heißt, statt gen_server:cast direkt aufrufen, wie folgt aus:

gen_server:cast(foo_proc, {some_message, 42}) 

einen Funktionsaufruf:

foo_proc:some_message(42) 

und diese Funktion wie die direkte Besetzung oben implementieren. Das kapselt das spezifische Protokoll des gen_servers in seinem eigenen Modul.

In meinen Augen würden "einfache" Nachrichten für Ereignisse verwendet, im Gegensatz zu API-Aufrufen. Ein Beispiel wären Überwachungsnachrichten, {'DOWN', Ref, process, Id, Reason}, und ähnliche Ereignisse, die in Ihrem System auftreten können.

4

Zusätzlich zu Legoscia Beitrag würde ich sagen, dass es einfacher ist, dedizierte Funktion API als Nachrichten verfolgen. Besonders in der Produktumgebung.