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 acquire 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
197           if (verbose)
198               zstr_send (alpha, "VERBOSE");
199
200           zstr_sendx (alpha, "CONNECT", "inproc://base", NULL);
201
202           zstr_sendx (alpha, "PUBLISH", "inproc://alpha-1", "service1", NULL);
203           zstr_sendx (alpha, "PUBLISH", "inproc://alpha-2", "service2", NULL);
204
205           zactor_t *beta = zactor_new (zgossip, "beta");
206           assert (beta);
207
208           if (verbose)
209               zstr_send (beta, "VERBOSE");
210
211           zstr_sendx (beta, "CONNECT", "inproc://base", NULL);
212
213           zstr_sendx (beta, "PUBLISH", "inproc://beta-1", "service1", NULL);
214           zstr_sendx (beta, "PUBLISH", "inproc://beta-2", "service2", NULL);
215
216           //  got nothing
217           zclock_sleep (200);
218
219           zstr_send (alpha, "STATUS");
220           char *command, *status, *key, *value;
221
222           zstr_recvx (alpha, &command, &key, &value, NULL);
223
224           assert (streq (command, "DELIVER"));
225           assert (streq (key, "inproc://alpha-1"));
226           assert (streq (value, "service1"));
227
228           zstr_free (&command);
229           zstr_free (&key);
230           zstr_free (&value);
231
232           zstr_recvx (alpha, &command, &key, &value, NULL);
233           assert (streq (command, "DELIVER"));
234           assert (streq (key, "inproc://alpha-2"));
235           assert (streq (value, "service2"));
236           zstr_free (&command);
237           zstr_free (&key);
238           zstr_free (&value);
239
240           zstr_recvx (alpha, &command, &key, &value, NULL);
241           assert (streq (command, "DELIVER"));
242           assert (streq (key, "inproc://beta-1"));
243           assert (streq (value, "service1"));
244           zstr_free (&command);
245           zstr_free (&key);
246           zstr_free (&value);
247
248           zstr_recvx (alpha, &command, &key, &value, NULL);
249           assert (streq (command, "DELIVER"));
250           assert (streq (key, "inproc://beta-2"));
251           assert (streq (value, "service2"));
252           zstr_free (&command);
253           zstr_free (&key);
254           zstr_free (&value);
255
256           zstr_recvx (alpha, &command, &status, NULL);
257           assert (streq (command, "STATUS"));
258           assert (atoi (status) == 4);
259           zstr_free (&command);
260           zstr_free (&status);
261
262           zactor_destroy (&base);
263           zactor_destroy (&alpha);
264           zactor_destroy (&beta);
265
266           #ifdef CZMQ_BUILD_DRAFT_API
267           //  DRAFT-API: Security
268           // curve
269           if (zsys_has_curve()) {
270               if (verbose)
271                   printf("testing CURVE support");
272               zclock_sleep (2000);
273               zactor_t *auth = zactor_new(zauth, NULL);
274               assert (auth);
275               if (verbose) {
276                   zstr_sendx (auth, "VERBOSE", NULL);
277                   zsock_wait (auth);
278               }
279               zstr_sendx(auth,"ALLOW","127.0.0.1",NULL);
280               zsock_wait(auth);
281               zstr_sendx (auth, "CURVE", CURVE_ALLOW_ANY, NULL);
282               zsock_wait (auth);
283
284               server = zactor_new (zgossip, "server");
285               if (verbose)
286                   zstr_send (server, "VERBOSE");
287               assert (server);
288
289               zcert_t *client1_cert = zcert_new ();
290               zcert_t *server_cert = zcert_new ();
291
292               zstr_sendx (server, "SET PUBLICKEY", zcert_public_txt (server_cert), NULL);
293               zstr_sendx (server, "SET SECRETKEY", zcert_secret_txt (server_cert), NULL);
294               zstr_sendx (server, "ZAP DOMAIN", "TEST", NULL);
295
296               zstr_sendx (server, "BIND", "tcp://127.0.0.1:*", NULL);
297               zstr_sendx (server, "PORT", NULL);
298               zstr_recvx (server, &command, &value, NULL);
299               assert (streq (command, "PORT"));
300               int port = atoi (value);
301               zstr_free (&command);
302               zstr_free (&value);
303               char endpoint [32];
304               sprintf (endpoint, "tcp://127.0.0.1:%d", port);
305
306               zactor_t *client1 = zactor_new (zgossip, "client");
307               if (verbose)
308                   zstr_send (client1, "VERBOSE");
309               assert (client1);
310
311               zstr_sendx (client1, "SET PUBLICKEY", zcert_public_txt (client1_cert), NULL);
312               zstr_sendx (client1, "SET SECRETKEY", zcert_secret_txt (client1_cert), NULL);
313               zstr_sendx (client1, "ZAP DOMAIN", "TEST", NULL);
314
315               const char *public_txt = zcert_public_txt (server_cert);
316               zstr_sendx (client1, "CONNECT", endpoint, public_txt, NULL);
317               zstr_sendx (client1, "PUBLISH", "tcp://127.0.0.1:9001", "service1", NULL);
318
319               zclock_sleep (500);
320
321               zstr_send (server, "STATUS");
322               zclock_sleep (500);
323
324               zstr_recvx (server, &command, &key, &value, NULL);
325               assert (streq (command, "DELIVER"));
326               assert (streq (value, "service1"));
327
328               zstr_free (&command);
329               zstr_free (&key);
330               zstr_free (&value);
331
332               zstr_sendx (client1, "$TERM", NULL);
333               zstr_sendx (server, "$TERM", NULL);
334
335               zclock_sleep(500);
336
337               zcert_destroy (&client1_cert);
338               zcert_destroy (&server_cert);
339
340               zactor_destroy (&client1);
341               zactor_destroy (&server);
342               zactor_destroy (&auth);
343           }
344           #endif
345
346           #if defined (__WINDOWS__)
347           zsys_shutdown();
348           #endif
349
350

AUTHORS

352       The czmq manual was written by the authors in the AUTHORS file.
353

RESOURCES

355       Main web site:
356
357       Report bugs to the email <zeromq-dev@lists.zeromq.org[1]>
358
360       Copyright (c) the Contributors as noted in the AUTHORS file. This file
361       is part of CZMQ, the high-level C binding for 0MQ:
362       http://czmq.zeromq.org. This Source Code Form is subject to the terms
363       of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
364       distributed with this file, You can obtain one at
365       http://mozilla.org/MPL/2.0/. LICENSE included with the czmq
366       distribution.
367

NOTES

369        1. zeromq-dev@lists.zeromq.org
370           mailto:zeromq-dev@lists.zeromq.org
371
372
373
374CZMQ 4.2.0                        01/28/2020                        ZGOSSIP(3)
Impressum