Ich arbeitete zwar ein Problem und bemerkte etwas Code, wo ein vorheriger Programmierer Nachrichten mit der Standardkonvention von PID passierte! Botschaft. Ich habe gen_server verwendet: cast/2. Ich habe mich gefragt, ob mir jemand die kritischen Unterschiede und Überlegungen bei der Wahl zwischen den beiden erklären könnte?Erlang: Unterschied zwischen der Verwendung von gen_server: Cast/2 und Standard Message Passing
Antwort
Es gibt ein paar kleine Unterschiede:
- Offensichtlich ist die gen_server Griffe Abgüsse in
handle_cast
und "normalen" Nachrichten inhandle_info
. - Eine Besetzung schlägt nie fehl; es gibt immer
ok
zurück. Das Senden einer Nachricht mit!
schlägt mitbadarg
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ürgen_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.
Zusätzlich zu Legoscia Beitrag würde ich sagen, dass es einfacher ist, dedizierte Funktion API als Nachrichten verfolgen. Besonders in der Produktumgebung.