Dynamic nodes using global registry

I apologize if this is a known issue — my searching has not turned up anything.

I have a gen_server that globally registers itself, but I cannot seem to use it from a dynamic node.

Non-dynamic nodes work: If I erl -name something, then net_adm:ping('server_node'), I can then use client functions (that do things like gen_server:call({global, ?SERVER}, ...) All good.

But, if I erl -name undefined, then net_kernel:connect_node('server_node') that succeeds as do pings, but nodes() is empty and attempts to use client functions fail with ‘noproc’. global:whereis_name('global_service_name') produces undefined.

If I register a process locally on the server node, I can send messages to it using gen_server:call({'registered_name', 'server_node'}, ...).

Conclusion: dynamic nodes don’t seem to sync with the global registry. (I tried global:sync() without any change: nodes() is still [] and the service cannot be found.)

I am running Erlang/OTP 25 on a Chromebook and version 26 on a MacBook Pro. Same behavior.

Am I missing something? Is there a way to get dynamic nodes to participate in the global registry? Or do I have to plumb the registered name and node name through everything?

Help is appreciated!

Dynamic node is also a hidden node, so global doesn’t keep track of them. I don’t know if one can override that. One workaround would be to execute that gen_server call on the node you’re connecting to, e.g. via erpc.

1 Like

I am just guessing here but isn’t the problem that you have given the node the name undefined which is the same as if it was undefined. What do you get when you call node() in that node?

Also try nodes(hidden) and nodes(connected) and nodes(known)?

2 Likes

Thank you! I forgot hidden nodes exist! Dynamic nodes (nodes started with the name undefined) when they connect, do so as hidden nodes, which makes sense:

(3MEFLP0EW3HOO@192.168.1.98)23> nodes(hidden).
['do@192.168.1.98']
(3MEFLP0EW3HOO@192.168.1.98)24> nodes(known).
['do@192.168.1.98','3MEFLP0EW3HOO@192.168.1.98']
(3MEFLP0EW3HOO@192.168.1.98)25> nodes().
[]
(3MEFLP0EW3HOO@192.168.1.98)26>

And the documentation does say that hidden nodes don’t participate in the global registry, which also makes sense.

Am I right that there is no way for a non-participating node to query the global registry so `gen_server:call({global, service}, Message) works?

If I’m right, I can think of two obvious solutions:

  1. Don’t use the global registry. Register the server process locally on the server node, and have the client functions specify {server_name, server_node}' in the gen_server:callandgen_server:cast` calls.
  2. Leave the server globally registered, but have dynamic clients run the operation on the server node using rpc:call. This is gross, but for this particular case, it’s a kind of low-volume, administrative node I’m popping up.

In a related application, I expect nearly all interactions to arise from dynamic nodes, and I would stick with option 1.

If I’m missing something, please let me know, and thank you for the help!

@mmin
Indeed — I hadn’t realized dynamic nodes were hidden, but of course they are!

I saw Robert’s answer first, because it was most recent in my email inbox, but you both got it.

Thank you!