[zeromq-dev] ZRE/Zbeacon improvement proposal

Arnaud Loonstra arnaud at sphaero.org
Sat Oct 26 10:53:00 CEST 2013

Hi all,

Last few weeks I have been investigating the Zyre/ZRE codebase. I have 
some suggestion which could improve things I would like to discuss. I've 
been working with Zbeacon mostly so my proposes are for ZBeacon only 
currently. Here are the issues I've found:

1 - Only one node can run on a host (or one per interface)
2 - Network segments can't be covered
3 - Nodes are trying to connect to dead peers (peers that are gone)

I've been working on some solutions to overcome this and I would propose 
these changes. As I'm not a frequent C programmer and thus find it hard 
to be a bit creative with it I ported Zbeacon to Python. In the Python 
code I've implemented solutions to these issues. I've only been testing 
these solutions on Linux platforms, currently:

1 - The issue is caused by using a broadcast socket. It's possible to 
bind multiple programs to the same address and port but packets are then 
load balanced between the sockets. This results in missing beacons. The 
solution is to use multicast instead. I've talked with Pieter about it 
and he said broadcast was chosen because of multicast issues with 
Android. I'm not sure what the current state is of multicast in Android 
so I left broadcast as an option determined by the address.
2 - Broadcast is limited to one network segment unless you do some 
broadcast forwarding on a router device. Multicast is again a solution 
(if you have the right network equipment/configuration). In most cases 
where multicast is not really multicast it's usually handled as 
broadcast traffic anyways.
3 - What I observed was nodes not knowing when a peer node was gone 
trying to connect to the peer node. This is obviously to no success. It 
also results in unnecessary traffic and handling. I would propose to 
embody a node state identifier inside the beacon. This way when a node 
exits it can send its exit state before terminating and other nodes have 
the possibility to pick this up. This would also be a welcome feature to 
inform nodes of each other state. For example when a node is overloaded 
it could inform about this using its state. A broker can leave him alone 
for a while. I think this could be useful in general.

To facilitate the extra state identifier it could be simply appended to 
the body:
+---+---+---+------+  +------+------+
| Z | R | E | %x01 |  | UUID | port |
+---+---+---+------+  +------+------+
        Header               Body

+---+---+---+------+  +------+------+-------+
| Z | R | E | %x01 |  | UUID | port | state |
+---+---+---+------+  +------+------+-------+
        Header               Body

These extra statements would apply:
* The state identifier uses the following 1 octet values; 0: INIT, 
* A node shall send a beacon with a state value of EXIT(2) just before 
it shuts down

The python code is available at http://github.com/sphaero/pyzyre

Would these proposals be of use for ZRE?

More ideas?

- For passing multiple network segments multicast is often not possible. 
Crossing internet using multicast is nowhere available, to my knowledge. 
In order to overcome this I think the only solution would be to use DNS. 
What I'm thinking of is the following sequence for node discovery:
   1 - multicast/broadcast as it is now
   2 - DNS SRV records
   3 - static/manual config (by passing a config parameter)

- When a node receives a beacon from it's own ipaddress but from a 
different uuid than it's own it should start open ipc/inproc sockets and 
use those to communicate to each other. This is more efficient in the 
case when multiple nodes run on one machine.


Arnaud Loonstra
w: http://www.sphaero.org
t: http://twitter.com/sphaero
g: http://github.com/sphaero
i: freenode: sphaero_z25

More information about the zeromq-dev mailing list