1ZGOSSIP(3)                        CZMQ Manual                       ZGOSSIP(3)
2
3
4

NAME

6       zgossip - Class for decentralized configuration management
7

SYNOPSIS

9       //  To work with zgossip, use the CZMQ zactor API:
10       //
11       //  Create new zgossip instance, passing logging prefix:
12       //
13       //      zactor_t *zgossip = zactor_new (zgossip, "myname");
14       //
15       //  Destroy zgossip instance
16       //
17       //      zactor_destroy (&zgossip);
18       //
19       //  Enable verbose logging of commands and activity:
20       //
21       //      zstr_send (zgossip, "VERBOSE");
22       //
23       //  Bind zgossip to specified endpoint. TCP endpoints may specify
24       //  the port number as "*" to aquire an ephemeral port:
25       //
26       //      zstr_sendx (zgossip, "BIND", endpoint, NULL);
27       //
28       //  Return assigned port number, specifically when BIND was done using an
29       //  an ephemeral port:
30       //
31       //      zstr_sendx (zgossip, "PORT", NULL);
32       //      char *command, *port_str;
33       //      zstr_recvx (zgossip, &command, &port_str, NULL);
34       //      assert (streq (command, "PORT"));
35       //
36       //  Specify configuration file to load, overwriting any previous loaded
37       //  configuration file or options:
38       //
39       //      zstr_sendx (zgossip, "LOAD", filename, NULL);
40       //
41       //  Set configuration path value:
42       //
43       //      zstr_sendx (zgossip, "SET", path, value, NULL);
44       //
45       //  Save configuration data to config file on disk:
46       //
47       //      zstr_sendx (zgossip, "SAVE", filename, NULL);
48       //
49       //  Send zmsg_t instance to zgossip:
50       //
51       //      zactor_send (zgossip, &msg);
52       //
53       //  Receive zmsg_t instance from zgossip:
54       //
55       //      zmsg_t *msg = zactor_recv (zgossip);
56       //
57       //  This is the zgossip constructor as a zactor_fn:
58       //
59       CZMQ_EXPORT void
60           zgossip (zsock_t *pipe, void *args);
61
62       //  Self test of this class
63       CZMQ_EXPORT void
64           zgossip_test (bool verbose);
65       Please add '@interface' section in './../src/zgossip.c'.
66

DESCRIPTION

68       Implements a gossip protocol for decentralized configuration
69       management. Your applications nodes form a loosely connected network
70       (which can have cycles), and publish name/value tuples. Each node
71       re-distributes the new tuples it receives, so that the entire network
72       eventually achieves a consistent state. The current design does not
73       expire tuples.
74
75       Provides these commands (sent as multipart strings to the actor):
76
77       ·   BIND endpoint — binds the gossip service to specified endpoint
78
79       ·   PORT — returns the last TCP port, if any, used for binding
80
81       ·   LOAD configfile — load configuration from specified file
82
83       ·   SET configpath value — set configuration path = value
84
85       ·   SAVE configfile — save configuration to specified file
86
87       ·   CONNECT endpoint — connect the gossip service to the specified peer
88
89       ·   PUBLISH key value — publish a key/value pair to the gossip cluster
90
91       ·   STATUS — return number of key/value pairs held by gossip service
92
93       ·   ZAP DOMAIN domain — set the ZAP DOMAIN domain = value
94
95       Returns these messages:
96
97       ·   PORT number — reply to PORT command
98
99       ·   STATUS number — reply to STATUS command
100
101       ·   DELIVER key value — new tuple delivered from network
102
103       The gossip protocol distributes information around a loosely-connected
104       network of gossip services. The information consists of name/value
105       pairs published by applications at any point in the network. The goal
106       of the gossip protocol is to create eventual consistency between all
107       the using applications.
108
109       The name/value pairs (tuples) can be used for configuration data, for
110       status updates, for presence, or for discovery. When used for
111       discovery, the gossip protocol works as an alternative to e.g. UDP
112       beaconing.
113
114       The gossip network consists of a set of loosely-coupled nodes that
115       exchange tuples. Nodes can be connected across arbitrary transports, so
116       the gossip network can have nodes that communicate over inproc, over
117       IPC, and/or over TCP, at the same time.
118
119       Each node runs the same stack, which is a server-client hybrid using a
120       modified Harmony pattern (from Chapter 8 of the Guide):
121       http://zguide.zeromq.org/page:all#True-Peer-Connectivity-Harmony-Pattern
122
123       Each node provides a ROUTER socket that accepts client connections on
124       an key defined by the application via a BIND command. The state machine
125       for these connections is in zgossip.xml, and the generated code is in
126       zgossip_engine.inc.
127
128       Each node additionally creates outbound connections via DEALER sockets
129       to a set of servers ("remotes"), and under control of the calling app,
130       which sends CONNECT commands for each configured remote.
131
132       The messages between client and server are defined in zgossip_msg.xml.
133       We built this stack using the zeromq/zproto toolkit.
134
135       To join the gossip network, a node connects to one or more peers. Each
136       peer acts as a forwarder. This loosely-coupled network can scale to
137       thousands of nodes. However the gossip protocol is NOT designed to be
138       efficient, and should not be used for application data, as the same
139       tuples may be sent many times across the network.
140
141       The basic logic of the gossip service is to accept PUBLISH messages
142       from its owning application, and to forward these to every remote, and
143       every client it talks to. When a node gets a duplicate tuple, it throws
144       it away. When a node gets a new tuple, it stores it, and forwards it as
145       just described.
146
147       At present there is no way to expire tuples from the network.
148
149       The assumptions in this design are:
150
151       ·   The data set is slow-changing. Thus, the cost of the gossip
152           protocol is irrelevant with respect to other traffic.
153

EXAMPLE

155       From zgossip_test method.
156
157           //  Test basic client-to-server operation of the protocol
158           zactor_t *server = zactor_new (zgossip, "server");
159           assert (server);
160           if (verbose)
161               zstr_send (server, "VERBOSE");
162           zstr_sendx (server, "BIND", "inproc://zgossip", NULL);
163
164           zsock_t *client = zsock_new (ZMQ_DEALER);
165           assert (client);
166           zsock_set_rcvtimeo (client, 2000);
167           int rc = zsock_connect (client, "inproc://zgossip");
168           assert (rc == 0);
169
170           //  Send HELLO, which gets no message
171           zgossip_msg_t *message = zgossip_msg_new ();
172           zgossip_msg_set_id (message, ZGOSSIP_MSG_HELLO);
173           zgossip_msg_send (message, client);
174
175           //  Send PING, expect PONG back
176           zgossip_msg_set_id (message, ZGOSSIP_MSG_PING);
177           zgossip_msg_send (message, client);
178           zgossip_msg_recv (message, client);
179           assert (zgossip_msg_id (message) == ZGOSSIP_MSG_PONG);
180           zgossip_msg_destroy (&message);
181
182           zactor_destroy (&server);
183           zsock_destroy (&client);
184
185           //  Test peer-to-peer operations
186           zactor_t *base = zactor_new (zgossip, "base");
187           assert (base);
188           if (verbose)
189               zstr_send (base, "VERBOSE");
190           //  Set a 100msec timeout on clients so we can test expiry
191           zstr_sendx (base, "SET", "server/timeout", "100", NULL);
192           zstr_sendx (base, "BIND", "inproc://base", NULL);
193
194           zactor_t *alpha = zactor_new (zgossip, "alpha");
195           assert (alpha);
196           zstr_sendx (alpha, "CONNECT", "inproc://base", NULL);
197           zstr_sendx (alpha, "PUBLISH", "inproc://alpha-1", "service1", NULL);
198           zstr_sendx (alpha, "PUBLISH", "inproc://alpha-2", "service2", NULL);
199
200           zactor_t *beta = zactor_new (zgossip, "beta");
201           assert (beta);
202           zstr_sendx (beta, "CONNECT", "inproc://base", NULL);
203           zstr_sendx (beta, "PUBLISH", "inproc://beta-1", "service1", NULL);
204           zstr_sendx (beta, "PUBLISH", "inproc://beta-2", "service2", NULL);
205
206           //  got nothing
207           zclock_sleep (200);
208
209           zstr_send (alpha, "STATUS");
210           char *command, *status, *key, *value;
211
212           zstr_recvx (alpha, &command, &key, &value, NULL);
213           assert (streq (command, "DELIVER"));
214           assert (streq (key, "inproc://alpha-1"));
215           assert (streq (value, "service1"));
216           zstr_free (&command);
217           zstr_free (&key);
218           zstr_free (&value);
219
220           zstr_recvx (alpha, &command, &key, &value, NULL);
221           assert (streq (command, "DELIVER"));
222           assert (streq (key, "inproc://alpha-2"));
223           assert (streq (value, "service2"));
224           zstr_free (&command);
225           zstr_free (&key);
226           zstr_free (&value);
227
228           zstr_recvx (alpha, &command, &key, &value, NULL);
229           assert (streq (command, "DELIVER"));
230           assert (streq (key, "inproc://beta-1"));
231           assert (streq (value, "service1"));
232           zstr_free (&command);
233           zstr_free (&key);
234           zstr_free (&value);
235
236           zstr_recvx (alpha, &command, &key, &value, NULL);
237           assert (streq (command, "DELIVER"));
238           assert (streq (key, "inproc://beta-2"));
239           assert (streq (value, "service2"));
240           zstr_free (&command);
241           zstr_free (&key);
242           zstr_free (&value);
243
244           zstr_recvx (alpha, &command, &status, NULL);
245           assert (streq (command, "STATUS"));
246           assert (atoi (status) == 4);
247           zstr_free (&command);
248           zstr_free (&status);
249
250           zactor_destroy (&base);
251           zactor_destroy (&alpha);
252           zactor_destroy (&beta);
253
254           #ifdef CZMQ_BUILD_DRAFT_API
255           // curve
256           if (zsys_has_curve()) {
257               if (verbose)
258                   printf("testing CURVE support");
259               zclock_sleep (2000);
260               zactor_t *auth = zactor_new(zauth, NULL);
261               assert (auth);
262               if (verbose) {
263                   zstr_sendx (auth, "VERBOSE", NULL);
264                   zsock_wait (auth);
265               }
266               zstr_sendx(auth,"ALLOW","127.0.0.1",NULL);
267               zsock_wait(auth);
268               zstr_sendx (auth, "CURVE", CURVE_ALLOW_ANY, NULL);
269               zsock_wait (auth);
270
271               server = zactor_new (zgossip, "server");
272               if (verbose)
273                   zstr_send (server, "VERBOSE");
274               assert (server);
275
276               zcert_t *client1_cert = zcert_new ();
277               zcert_t *server_cert = zcert_new ();
278
279               zstr_sendx (server, "SET PUBLICKEY", zcert_public_txt (server_cert), NULL);
280               zstr_sendx (server, "SET SECRETKEY", zcert_secret_txt (server_cert), NULL);
281               zstr_sendx (server, "ZAP DOMAIN", "TEST", NULL);
282
283               zstr_sendx (server, "BIND", "tcp://127.0.0.1:*", NULL);
284               zstr_sendx (server, "PORT", NULL);
285               zstr_recvx (server, &command, &value, NULL);
286               assert (streq (command, "PORT"));
287               int port = atoi (value);
288               zstr_free (&command);
289               zstr_free (&value);
290               char endpoint [32];
291               sprintf (endpoint, "tcp://127.0.0.1:%d", port);
292
293               zactor_t *client1 = zactor_new (zgossip, "client");
294               if (verbose)
295                   zstr_send (client1, "VERBOSE");
296               assert (client1);
297
298               zstr_sendx (client1, "SET PUBLICKEY", zcert_public_txt (client1_cert), NULL);
299               zstr_sendx (client1, "SET SECRETKEY", zcert_secret_txt (client1_cert), NULL);
300               zstr_sendx (client1, "ZAP DOMAIN", "TEST", NULL);
301
302               const char *public_txt = zcert_public_txt (server_cert);
303               zstr_sendx (client1, "CONNECT", endpoint, public_txt, NULL);
304               zstr_sendx (client1, "PUBLISH", "tcp://127.0.0.1:9001", "service1", NULL);
305
306               zclock_sleep (500);
307
308               zstr_send (server, "STATUS");
309               zclock_sleep (500);
310
311               zstr_recvx (server, &command, &key, &value, NULL);
312               assert (streq (command, "DELIVER"));
313               assert (streq (value, "service1"));
314
315               zstr_free (&command);
316               zstr_free (&key);
317               zstr_free (&value);
318
319               zstr_sendx (client1, "$TERM", NULL);
320               zstr_sendx (server, "$TERM", NULL);
321
322               zclock_sleep(500);
323
324               zcert_destroy (&client1_cert);
325               zcert_destroy (&server_cert);
326
327               zactor_destroy (&client1);
328               zactor_destroy (&server);
329               zactor_destroy (&auth);
330           }
331           #endif
332
333           #if defined (__WINDOWS__)
334           zsys_shutdown();
335           #endif
336
337

AUTHORS

339       The czmq manual was written by the authors in the AUTHORS file.
340

RESOURCES

342       Main web site:
343
344       Report bugs to the email <zeromq-dev@lists.zeromq.org[1]>
345
347       Copyright (c) the Contributors as noted in the AUTHORS file. This file
348       is part of CZMQ, the high-level C binding for 0MQ:
349       http://czmq.zeromq.org. This Source Code Form is subject to the terms
350       of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
351       distributed with this file, You can obtain one at
352       http://mozilla.org/MPL/2.0/. LICENSE included with the czmq
353       distribution.
354

NOTES

356        1. zeromq-dev@lists.zeromq.org
357           mailto:zeromq-dev@lists.zeromq.org
358
359
360
361CZMQ 4.1.1                        07/24/2019                        ZGOSSIP(3)
Impressum