How can distributed message sending result in a reply, if there is no registered processed on the remote node?

123 Views Asked by At

According to the Erlang Reference Manual, the send operator (!) syntax is Expr1 ! Expr2.
It states that

  • Expr1 can be a tuple in the form of {Name, Node}, where "Name is an atom and Node is a node name, also an atom", and
  • "distributed message sending [...] never fails".

When using FreeSWITCH with mod_erlang_event (that starts up an Erlang C node), and a message is sent with any atom as Name, it will result in a response:

$ erl -sname test -setcookie ClueCon
Erlang/OTP 19 [erts-8.2.1] [source] [64-bit] [async-threads:10] [kernel-poll:false]

Eshell V8.2.1  (abort with ^G)

(test@tr2)1> {polgarjenohivatalba, freeswitch@tr2} ! {api, msleep, 500}.
{api,msleep,500}

(test@tr2)2> receive X -> X after 1000 -> to end.        
{ok,"+OK"}

(test@tr2)3> {vizbolveszikiazoxigent, freeswitch@tr2} ! holafafonok.       
holafafonok

(test@tr2)4> flush().              
Shell got {error,undef}

(test@tr2)5> nodes().
[]

(test@tr2)6> nodes(connected).
[freeswitch@tr2]

Why wouldn't this work with two regular Erlang nodes below?

The atoms above are also not registered processes, and message sending feels like a remote procedure call.

Peeked into mod_erlang_event's source, but I don't have much C experience, and haven't used non-native Erlang nodes. It feels though as if running a C node would result in
(1) running an Erlang node
(2) with a process automatically started
(with the C logic serving as the receive loop of that process)
(3) that will match any atom.

So maybe that is why that only explicitly registered processes can be used with native Erlang nodes. (Again, I'm probably completely wrong.)

Starting node "def":

$ erl -sname def -setcookie lofa
Erlang/OTP 19 [erts-8.2.1] [source] [64-bit] [async-threads:10] [kernel-poll:false]

Eshell V8.2.1  (abort with ^G)

(def@tr2)1> {lofa, abc@tr2} ! miez.
miez

(def@tr2)2> nodes(connected).
[abc@tr2]

Going back to node "abc" started earlier:

$ erl -sname abc -setcookie lofa
Erlang/OTP 19 [erts-8.2.1] [source] [64-bit] [async-threads:10] [kernel-poll:false]

Eshell V8.2.1  (abort with ^G)

(abc@tr2)1> receive X -> X after 27000 -> timeout end.
timeout

(abc@tr2)2> nodes(connected).
[def@tr2]

The freeswitch@tr2 and test@tr2 got also immediately connected as hidden nodes, but this behaviour seems to be the same with abc@tr2 and def@tr2.

2

There are 2 best solutions below

0
On BEST ANSWER

Should've just RTFM because the answer is right in the first section of C nodes (emphases mine):

7.1 Erlang Program

From Erlang's point of view, the C node is treated like a normal Erlang node. Thus, calling the functions foo and bar only involves sending a message to the C node asking for the function to be called, and receiving the result. Sending a message requires a recipient, that is, a process that can be defined using either a pid or a tuple, consisting of a registered name and a node name. In this case, a tuple is the only alternative as no pid is known:

{RegName, Node} ! Msg

The node name Node is to be the name of the C node. If short node names are used, the plain name of the node is cN, where N is an integer. If long node names are used, there is no such restriction. An example of a C node name using short node names is thus c1@idril, an example using long node names is [email protected].

The registered name, RegName, can be any atom. The name can be

  • ignored by the C code, or,
  • for example, be used to distinguish between different types of messages.
1
On

There's a difference between the message send "succeeding", i.e. no error is thrown, and "getting a response message". It looks to me like in one case, the sent message succeeds AND a message is returned; and in the other case the sent message succeeds and no message is returned.