Skip site navigation (1)Skip section navigation (2)

  
 
  

home | help
ZGOSSIP(3)			   CZMQ Manual			      ZGOSSIP(3)

NAME
     zgossip - Class for decentralized configuration management

SYNOPSIS
     //  To work with zgossip, use the CZMQ zactor API:
     //
     //  Create new zgossip instance, passing logging prefix:
     //
     //      zactor_t *zgossip = zactor_new (zgossip, "myname");
     //
     //  Destroy zgossip instance
     //
     //      zactor_destroy (&zgossip);
     //
     //  Enable verbose logging of commands and activity:
     //
     //      zstr_send (zgossip, "VERBOSE");
     //
     //  Bind zgossip to specified endpoint. TCP endpoints may specify
     //  the port number as "*" to acquire an ephemeral port:
     //
     //      zstr_sendx (zgossip, "BIND", endpoint, NULL);
     //
     //  Return assigned port number, specifically when BIND was done using an
     //  an ephemeral port:
     //
     //      zstr_sendx (zgossip, "PORT", NULL);
     //      char *command, *port_str;
     //      zstr_recvx (zgossip, &command, &port_str, NULL);
     //      assert (streq (command, "PORT"));
     //
     //  Specify configuration file to load, overwriting any previous loaded
     //  configuration file or options:
     //
     //      zstr_sendx (zgossip, "LOAD", filename, NULL);
     //
     //  Set configuration path value:
     //
     //      zstr_sendx (zgossip, "SET", path, value, NULL);
     //
     //  Save configuration data to config file on disk:
     //
     //      zstr_sendx (zgossip, "SAVE", filename, NULL);
     //
     //  Send zmsg_t instance to zgossip:
     //
     //      zactor_send (zgossip, &msg);
     //
     //  Receive zmsg_t instance from zgossip:
     //
     //      zmsg_t *msg = zactor_recv (zgossip);
     //
     //  This is the zgossip constructor as a zactor_fn:
     //
     CZMQ_EXPORT void
	 zgossip (zsock_t *pipe, void *args);

     //  Self test of this class
     CZMQ_EXPORT void
	 zgossip_test (bool verbose);
     Please add '@interface' section in './../src/zgossip.c'.

DESCRIPTION
     Implements  a  gossip  protocol for decentralized configuration management.
     Your applications nodes form a loosely connected network  (which  can  have
     cycles),  and  publish  name/value tuples. Each node re-distributes the new
     tuples it receives, so that the entire network eventually achieves  a  con-
     sistent state. The current design does not expire tuples.

     Provides these commands (sent as multipart strings to the actor):

     *	 BIND endpoint -- binds the gossip service to specified endpoint

     *	 PORT -- returns the last TCP port, if any, used for binding

     *	 LOAD configfile -- load configuration from specified file

     *	 SET configpath value -- set configuration path = value

     *	 SAVE configfile -- save configuration to specified file

     *	 CONNECT endpoint -- connect the gossip service to the specified peer

     *	 PUBLISH key value -- publish a key/value pair to the gossip cluster

     *	 STATUS -- return number of key/value pairs held by gossip service

     *	 ZAP DOMAIN domain -- set the ZAP DOMAIN domain = value

     Returns these messages:

     *	 PORT number -- reply to PORT command

     *	 STATUS number -- reply to STATUS command

     *	 DELIVER key value -- new tuple delivered from network

     The gossip protocol distributes information around a loosely-connected net-
     work  of gossip services. The information consists of name/value pairs pub-
     lished by applications at any point in the network. The goal of the  gossip
     protocol  is  to create eventual consistency between all the using applica-
     tions.

     The name/value pairs (tuples) can be used for configuration data, for  sta-
     tus  updates,  for presence, or for discovery. When used for discovery, the
     gossip protocol works as an alternative to e.g. UDP beaconing.

     The gossip network consists of a set of loosely-coupled nodes that exchange
     tuples. Nodes can be connected across arbitrary transports, so  the  gossip
     network  can have nodes that communicate over inproc, over IPC, and/or over
     TCP, at the same time.

     Each node runs the same stack, which is a server-client hybrid using a mod-
     ified Harmony pattern (from Chapter  8  of  the  Guide):  http://zguide.ze-
     romq.org/page:all#True-Peer-Connectivity-Harmony-Pattern

     Each  node  provides  a ROUTER socket that accepts client connections on an
     key defined by the application via a BIND command. The  state  machine  for
     these  connections  is  in  zgossip.xml, and the generated code is in zgos-
     sip_engine.inc.

     Each node additionally creates outbound connections via DEALER sockets to a
     set of servers ("remotes"), and under control of  the  calling  app,  which
     sends CONNECT commands for each configured remote.

     The  messages  between client and server are defined in zgossip_msg.xml. We
     built this stack using the zeromq/zproto toolkit.

     To join the gossip network, a node connects to one or more peers. Each peer
     acts as a forwarder. This loosely-coupled network can scale to thousands of
     nodes. However the gossip protocol is NOT designed  to  be  efficient,  and
     should  not  be  used  for application data, as the same tuples may be sent
     many times across the network.

     The basic logic of the gossip service is to accept  PUBLISH  messages  from
     its  owning  application,	and  to forward these to every remote, and every
     client it talks to. When a node gets a duplicate tuple, it throws it  away.
     When  a  node  gets  a new tuple, it stores it, and forwards it as just de-
     scribed.

     At present there is no way to expire tuples from the network.

     The assumptions in this design are:

     *	 The data set is slow-changing. Thus, the cost of the gossip protocol is
	 irrelevant with respect to other traffic.

EXAMPLE
     From zgossip_test method.

	 //  Test basic client-to-server operation of the protocol
	 zactor_t *server = zactor_new (zgossip, "server");
	 assert (server);
	 if (verbose)
	     zstr_send (server, "VERBOSE");
	 zstr_sendx (server, "BIND", "inproc://zgossip", NULL);

	 zsock_t *client = zsock_new (ZMQ_DEALER);
	 assert (client);
	 zsock_set_rcvtimeo (client, 2000);
	 int rc = zsock_connect (client, "inproc://zgossip");
	 assert (rc == 0);

	 //  Send HELLO, which gets no message
	 zgossip_msg_t *message = zgossip_msg_new ();
	 zgossip_msg_set_id (message, ZGOSSIP_MSG_HELLO);
	 zgossip_msg_send (message, client);

	 //  Send PING, expect PONG back
	 zgossip_msg_set_id (message, ZGOSSIP_MSG_PING);
	 zgossip_msg_send (message, client);
	 zgossip_msg_recv (message, client);
	 assert (zgossip_msg_id (message) == ZGOSSIP_MSG_PONG);
	 zgossip_msg_destroy (&message);

	 zactor_destroy (&server);
	 zsock_destroy (&client);

	 //  Test peer-to-peer operations
	 zactor_t *base = zactor_new (zgossip, "base");
	 assert (base);
	 if (verbose)
	     zstr_send (base, "VERBOSE");
	 //  Set a 100msec timeout on clients so we can test expiry
	 zstr_sendx (base, "SET", "server/timeout", "100", NULL);
	 zstr_sendx (base, "BIND", "inproc://base", NULL);

	 zactor_t *alpha = zactor_new (zgossip, "alpha");
	 assert (alpha);

	 if (verbose)
	     zstr_send (alpha, "VERBOSE");

	 zstr_sendx (alpha, "CONNECT", "inproc://base", NULL);

	 zstr_sendx (alpha, "PUBLISH", "inproc://alpha-1", "service1", NULL);
	 zstr_sendx (alpha, "PUBLISH", "inproc://alpha-2", "service2", NULL);

	 zactor_t *beta = zactor_new (zgossip, "beta");
	 assert (beta);

	 if (verbose)
	     zstr_send (beta, "VERBOSE");

	 zstr_sendx (beta, "CONNECT", "inproc://base", NULL);

	 zstr_sendx (beta, "PUBLISH", "inproc://beta-1", "service1", NULL);
	 zstr_sendx (beta, "PUBLISH", "inproc://beta-2", "service2", NULL);

	 //  got nothing
	 zclock_sleep (200);

	 zstr_send (alpha, "STATUS");
	 char *command, *status, *key, *value;

	 zstr_recvx (alpha, &command, &key, &value, NULL);

	 assert (streq (command, "DELIVER"));
	 assert (streq (key, "inproc://alpha-1"));
	 assert (streq (value, "service1"));

	 zstr_free (&command);
	 zstr_free (&key);
	 zstr_free (&value);

	 zstr_recvx (alpha, &command, &key, &value, NULL);
	 assert (streq (command, "DELIVER"));
	 assert (streq (key, "inproc://alpha-2"));
	 assert (streq (value, "service2"));
	 zstr_free (&command);
	 zstr_free (&key);
	 zstr_free (&value);

	 zstr_recvx (alpha, &command, &key, &value, NULL);
	 assert (streq (command, "DELIVER"));
	 assert (streq (key, "inproc://beta-1"));
	 assert (streq (value, "service1"));
	 zstr_free (&command);
	 zstr_free (&key);
	 zstr_free (&value);

	 zstr_recvx (alpha, &command, &key, &value, NULL);
	 assert (streq (command, "DELIVER"));
	 assert (streq (key, "inproc://beta-2"));
	 assert (streq (value, "service2"));
	 zstr_free (&command);
	 zstr_free (&key);
	 zstr_free (&value);

	 zstr_recvx (alpha, &command, &status, NULL);
	 assert (streq (command, "STATUS"));
	 assert (atoi (status) == 4);
	 zstr_free (&command);
	 zstr_free (&status);

	 zactor_destroy (&base);
	 zactor_destroy (&alpha);
	 zactor_destroy (&beta);

	 #ifdef CZMQ_BUILD_DRAFT_API
	 //  DRAFT-API: Security
	 // curve
	 if (zsys_has_curve()) {
	     if (verbose)
		 printf("testing CURVE support");
	     zclock_sleep (2000);
	     zactor_t *auth = zactor_new(zauth, NULL);
	     assert (auth);
	     if (verbose) {
		 zstr_sendx (auth, "VERBOSE", NULL);
		 zsock_wait (auth);
	     }
	     zstr_sendx(auth,"ALLOW","127.0.0.1",NULL);
	     zsock_wait(auth);
	     zstr_sendx (auth, "CURVE", CURVE_ALLOW_ANY, NULL);
	     zsock_wait (auth);

	     server = zactor_new (zgossip, "server");
	     if (verbose)
		 zstr_send (server, "VERBOSE");
	     assert (server);

	     zcert_t *client1_cert = zcert_new ();
	     zcert_t *server_cert = zcert_new ();

	     zstr_sendx (server, "SET PUBLICKEY", zcert_public_txt (server_cert), NULL);
	     zstr_sendx (server, "SET SECRETKEY", zcert_secret_txt (server_cert), NULL);
	     zstr_sendx (server, "ZAP DOMAIN", "TEST", NULL);

	     zstr_sendx (server, "BIND", "tcp://127.0.0.1:*", NULL);
	     zstr_sendx (server, "PORT", NULL);
	     zstr_recvx (server, &command, &value, NULL);
	     assert (streq (command, "PORT"));
	     int port = atoi (value);
	     zstr_free (&command);
	     zstr_free (&value);
	     char endpoint [32];
	     sprintf (endpoint, "tcp://127.0.0.1:%d", port);

	     zactor_t *client1 = zactor_new (zgossip, "client");
	     if (verbose)
		 zstr_send (client1, "VERBOSE");
	     assert (client1);

	     zstr_sendx (client1, "SET PUBLICKEY", zcert_public_txt (client1_cert), NULL);
	     zstr_sendx (client1, "SET SECRETKEY", zcert_secret_txt (client1_cert), NULL);
	     zstr_sendx (client1, "ZAP DOMAIN", "TEST", NULL);

	     const char *public_txt = zcert_public_txt (server_cert);
	     zstr_sendx (client1, "CONNECT", endpoint, public_txt, NULL);
	     zstr_sendx (client1, "PUBLISH", "tcp://127.0.0.1:9001", "service1", NULL);

	     zclock_sleep (500);

	     zstr_send (server, "STATUS");
	     zclock_sleep (500);

	     zstr_recvx (server, &command, &key, &value, NULL);
	     assert (streq (command, "DELIVER"));
	     assert (streq (value, "service1"));

	     zstr_free (&command);
	     zstr_free (&key);
	     zstr_free (&value);

	     zstr_sendx (client1, "$TERM", NULL);
	     zstr_sendx (server, "$TERM", NULL);

	     zclock_sleep(500);

	     zcert_destroy (&client1_cert);
	     zcert_destroy (&server_cert);

	     zactor_destroy (&client1);
	     zactor_destroy (&server);
	     zactor_destroy (&auth);
	 }
	 #endif

	 #if defined (__WINDOWS__)
	 zsys_shutdown();
	 #endif

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

RESOURCES
     Main web site:

     Report bugs to the email <zeromq-dev@lists.zeromq.org[1]>

COPYRIGHT
     Copyright (c) the Contributors as noted in the AUTHORS file. This	file  is
     part  of  CZMQ,  the  high-level C binding for 0MQ: http://czmq.zeromq.org.
     This Source Code Form is subject to the terms of  the  Mozilla  Public  Li-
     cense, v. 2.0. If a copy of the MPL was not distributed with this file, You
     can  obtain  one  at http://mozilla.org/MPL/2.0/. LICENSE included with the
     czmq distribution.

NOTES
      1. zeromq-dev@lists.zeromq.org
	 mailto:zeromq-dev@lists.zeromq.org

CZMQ 4.2.1			   08/27/2026			      ZGOSSIP(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=zgossip&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help