README.md 26.1 KB
Newer Older
Kevin Sapper's avatar
Kevin Sapper committed
1
2
3
4

<A name="toc1-3" title="Zlogger" />
# Zlogger

Kevin Sapper's avatar
Kevin Sapper committed
5
<A name="toc2-6" title="Contents" />
Kevin Sapper's avatar
Kevin Sapper committed
6
7
8
## Contents


Kevin Sapper's avatar
Kevin Sapper committed
9
**<a href="#toc2-11">Overview</a>**
Kevin Sapper's avatar
Kevin Sapper committed
10

Kevin Sapper's avatar
Kevin Sapper committed
11
**<a href="#toc3-14">Scope and Goals</a>**
Kevin Sapper's avatar
Kevin Sapper committed
12

Kevin Sapper's avatar
Kevin Sapper committed
13
**<a href="#toc3-17">Ownership and License</a>**
Kevin Sapper's avatar
Kevin Sapper committed
14

Kevin Sapper's avatar
Kevin Sapper committed
15
**<a href="#toc2-29">Using Zlogger</a>**
Kevin Sapper's avatar
Kevin Sapper committed
16

Kevin Sapper's avatar
Kevin Sapper committed
17
**<a href="#toc3-32">Building on Linux</a>**
Kevin Sapper's avatar
Kevin Sapper committed
18

Kevin Sapper's avatar
Kevin Sapper committed
19
**<a href="#toc3-104">Building on Windows</a>**
Kevin Sapper's avatar
Kevin Sapper committed
20

Kevin Sapper's avatar
Kevin Sapper committed
21
**<a href="#toc3-139">Linking with an Application</a>**
Kevin Sapper's avatar
Kevin Sapper committed
22

Kevin Sapper's avatar
Kevin Sapper committed
23
**<a href="#toc3-146">Demo</a>**
Kevin Sapper's avatar
Kevin Sapper committed
24

Kevin Sapper's avatar
Kevin Sapper committed
25
**<a href="#toc3-151">Bakery</a>**
Kevin Sapper's avatar
Kevin Sapper committed
26

Kevin Sapper's avatar
Kevin Sapper committed
27
28
29
30
31
**<a href="#toc3-180">API Summary</a>**
*  <a href="#toc4-185">zlog - zlog actor</a>
*  <a href="#toc4-290">zecho - Implements the echo algorithms</a>
*  <a href="#toc4-515">zvector - Implements a dynamic vector clock</a>
*  <a href="#toc4-727">bakery - Bakery with zlogger support</a>
Kevin Sapper's avatar
Kevin Sapper committed
32

Kevin Sapper's avatar
Kevin Sapper committed
33
**<a href="#toc3-743">Hints to Contributors</a>**
Kevin Sapper's avatar
Kevin Sapper committed
34

Kevin Sapper's avatar
Kevin Sapper committed
35
**<a href="#toc3-755">This Document</a>**
Kevin Sapper's avatar
Kevin Sapper committed
36

Kevin Sapper's avatar
Kevin Sapper committed
37
<A name="toc2-11" title="Overview" />
Kevin Sapper's avatar
Kevin Sapper committed
38
39
## Overview

Kevin Sapper's avatar
Kevin Sapper committed
40
<A name="toc3-14" title="Scope and Goals" />
Kevin Sapper's avatar
Kevin Sapper committed
41
42
### Scope and Goals

Kevin Sapper's avatar
Kevin Sapper committed
43
<A name="toc3-17" title="Ownership and License" />
Kevin Sapper's avatar
Kevin Sapper committed
44
45
46
47
48
49
50
51
### Ownership and License

The contributors are listed in AUTHORS. This project uses the MPL v2 license, see LICENSE.

Zlogger uses the [C4.1 (Collective Code Construction Contract)](http://rfc.zeromq.org/spec:22) process for contributions.

Zlogger uses the [CLASS (C Language Style for Scalabilty)](http://rfc.zeromq.org/spec:21) guide for code style.

Kevin Sapper's avatar
Kevin Sapper committed
52
53
To report an issue, use the [Zlogger issue tracker](https://zenon.cs.hs-rm.de/causality-logger/zlogger/issues) at
gitlab.com.
Kevin Sapper's avatar
Kevin Sapper committed
54

Kevin Sapper's avatar
Kevin Sapper committed
55
<A name="toc2-29" title="Using Zlogger" />
Kevin Sapper's avatar
Kevin Sapper committed
56
57
## Using Zlogger

Kevin Sapper's avatar
Kevin Sapper committed
58
<A name="toc3-32" title="Building on Linux" />
Kevin Sapper's avatar
Kevin Sapper committed
59
60
61
62
### Building on Linux

To start with, you need at least these packages:

Kevin Sapper's avatar
Kevin Sapper committed
63
* {{git-all}} -- git is how we share code with other people.
Kevin Sapper's avatar
Kevin Sapper committed
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

* {{build-essential}}, {{libtool}}, {{pkg-config}} - the C compiler and related tools.

* {{autotools-dev}}, {{autoconf}}, {{automake}} - the GNU autoconf makefile generators.

* {{cmake}} - the CMake makefile generators (an alternative to autoconf).

Plus some others:

* {{uuid-dev}}, {{libpcre3-dev}} - utility libraries.

* {{valgrind}} - a useful tool for checking your code.

Which we install like this (using the Debian-style apt-get package manager):

```
    sudo apt-get update
    sudo apt-get install -y \
Kevin Sapper's avatar
Kevin Sapper committed
82
    git-all build-essential libtool \
Kevin Sapper's avatar
Kevin Sapper committed
83
84
85
86
87
88
89
    pkg-config autotools-dev autoconf automake cmake \
    uuid-dev libpcre3-dev valgrind

    # only execute this next line if interested in updating the man pages as
    # well (adds to build time):
    sudo apt-get install -y asciidoc
```
Kevin Sapper's avatar
Kevin Sapper committed
90

Kevin Sapper's avatar
Kevin Sapper committed
91
92
93
Here's how to build Zlogger from GitHub/Gitlab (building from packages is very
similar, you don't clone a repo but unpack a tarball), including the libsodium
(for security) and libzmq (ZeroMQ core) libraries:
Kevin Sapper's avatar
Kevin Sapper committed
94
95
96
97
98
99
100

```
    git clone git://github.com/zeromq/libzmq.git
    cd libzmq
    ./autogen.sh
    # do not specify "--with-libsodium" if you prefer to use internal tweetnacl
    # security implementation (recommended for development)
Kevin Sapper's avatar
Kevin Sapper committed
101
    ./configure
Kevin Sapper's avatar
Kevin Sapper committed
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
    make check
    sudo make install
    sudo ldconfig
    cd ..

    git clone git://github.com/zeromq/czmq.git
    cd czmq
    ./autogen.sh && ./configure && make check
    sudo make install
    sudo ldconfig
    cd ..

    git clone git://github.com/zeromq/zyre.git
    cd zyre
    ./autogen.sh && ./configure && make check
    sudo make install
    sudo ldconfig
    cd ..

121
    git clone https://zenon.cs.hs-rm.de/causality-logger/zlogger.git
Kevin Sapper's avatar
Kevin Sapper committed
122
    cd zlogger
Kevin Sapper's avatar
Kevin Sapper committed
123
124
    ./autogen.sh && ./configure && make check
    sudo make install
Kevin Sapper's avatar
Kevin Sapper committed
125
126
    sudo ldconfig
    cd ..
Kevin Sapper's avatar
Kevin Sapper committed
127

Kevin Sapper's avatar
Kevin Sapper committed
128
129
```

Kevin Sapper's avatar
Kevin Sapper committed
130
<A name="toc3-104" title="Building on Windows" />
Kevin Sapper's avatar
Kevin Sapper committed
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
### Building on Windows

To start with, you need MS Visual Studio (C/C++). The free community edition works well.

Then, install git, and make sure it works from a DevStudio command prompt:

```
git
```

Now let's build Zlogger from GitHub:

```
    git clone --depth 1 -b stable https://github.com/jedisct1/libsodium.git
    git clone git://github.com/zeromq/libzmq.git
    git clone git://github.com/zeromq/czmq.git
    git clone git://github.com/zeromq/zyre.git
148
    git clone https://zenon.cs.hs-rm.de/causality-logger/zlogger.git
Kevin Sapper's avatar
Kevin Sapper committed
149
150
    cd zlogger\builds\msvc configure.bat
    cd build buildall.bat
Kevin Sapper's avatar
Kevin Sapper committed
151
    cd ..\..\..\..
Kevin Sapper's avatar
Kevin Sapper committed
152

Kevin Sapper's avatar
Kevin Sapper committed
153
154
```

155
Test by running the `zlogger_selftest` command:
Kevin Sapper's avatar
Kevin Sapper committed
156
157
158
159
160
161
162
163
164
```
    dir/s/b zlogger_selftest.exe
    zlogger\builds\msvc\vs2013\DebugDEXE\zlogger_selftest.exe
    zlogger\builds\msvc\vs2013\ReleaseDEXE\zlogger_selftest.exe

    :: select your choice and run it
    zlogger\builds\msvc\vs2013\DebugDEXE\zlogger_selftest.exe
```

Kevin Sapper's avatar
Kevin Sapper committed
165
<A name="toc3-139" title="Linking with an Application" />
Kevin Sapper's avatar
Kevin Sapper committed
166
167
168
169
170
171
### Linking with an Application

Include `zlogger.h` in your application and link with libzlogger. Here is a typical gcc link command:

    gcc -lzlogger -lzyre -lczmq -lzmq myapp.c -o myapp

Kevin Sapper's avatar
Kevin Sapper committed
172
<A name="toc3-146" title="Demo" />
Kevin Sapper's avatar
Kevin Sapper committed
173
174
### Demo

Kevin Sapper's avatar
Kevin Sapper committed
175
176
177
178
179
180
181
182
183
The demo scripts are available in demo/ folder. Please refer to demo/README.md.

<A name="toc3-151" title="Bakery" />
### Bakery

At first you need to copy the rsyslog configuration file 1337-logger.conf into
the directory /etc/rsyslog.d/ and restart your rsyslog daemon

    cp 1337-logger.conf /etc/rsyslog.d/1337-logger.conf
Kevin Sapper's avatar
Kevin Sapper committed
184
    sudo service rsyslog restart
Kevin Sapper's avatar
Kevin Sapper committed
185

Kevin Sapper's avatar
Kevin Sapper committed
186
To run the bakery with 3 apprentices locally
Kevin Sapper's avatar
Kevin Sapper committed
187
188
189

    ./src/bakery & ./src/bakery & ./src/bakery & wait

Kevin Sapper's avatar
Kevin Sapper committed
190
191
192
Each bakery will have its own log file at /tmp/vc_*.log. The leader will write
the causal ordered log to ./ordered.log. If this file is empty, rsyslog did not
yet write any log entries or the collection algorithm has not yet been
Kevin Sapper's avatar
Kevin Sapper committed
193
triggered. To provide the bakery with more time to get all log files use the
Kevin Sapper's avatar
Kevin Sapper committed
194
option -w [n]s. To dump the Space-Time diagrams use -d parameter.
Kevin Sapper's avatar
Kevin Sapper committed
195
196
197
198
199
200

    ./src/bakery -d -w 15 & ./src/bakery -d -w 15 & ./src/bakery -d -w 15 & wait

The global syslog log is written to /tmp/global.log

To generate the final space time diagram use the ./generate_space_time.sh
Kevin Sapper's avatar
Kevin Sapper committed
201
202
script. This will generate the SVG ./dia_space_time.svg. Make sure you have
graphviz installed on your system i.e.
Kevin Sapper's avatar
Kevin Sapper committed
203

Kevin Sapper's avatar
Kevin Sapper committed
204
205
206
    sudo apt-get install graphviz

<A name="toc3-180" title="API Summary" />
Kevin Sapper's avatar
Kevin Sapper committed
207
208
### API Summary

209
This is the API provided by Zlogger 0.x, in alphabetical order.
Kevin Sapper's avatar
Kevin Sapper committed
210

Kevin Sapper's avatar
Kevin Sapper committed
211
<A name="toc4-185" title="zlog - zlog actor" />
Kevin Sapper's avatar
Kevin Sapper committed
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
#### zlog - zlog actor

zlog - zlog actor

Please add @discuss section in ../src/zlog.c.

This is the class interface:

```h
    //  Create new zlog actor instance.
    //  @TODO: Describe the purpose of this actor!
    //
    //      zactor_t *zlog = zactor_new (zlog, NULL);
    //
    //  Destroy zlog instance.
    //
    //      zactor_destroy (&zlog);
    //
    //  Enable verbose logging of commands and activity:
    //
    //      zstr_send (zlog, "VERBOSE");
    //
    //  Start zlog actor.
    //
    //      zstr_sendx (zlog, "START", NULL);
    //
    //  Stop zlog actor.
    //
    //      zstr_sendx (zlog, "STOP", NULL);
    //
    //  This is the zlog constructor as a zactor_fn;
    ZLOG_EXPORT void
        zlog_actor (zsock_t *pipe, void *args);
Kevin Sapper's avatar
Kevin Sapper committed
245
    
Kevin Sapper's avatar
Kevin Sapper committed
246
247
248
249
    //  Compares the zvector_t's of given logMsg a to logMsg b.
    //  Returns -1 if a < b, otherwiese 1
    ZLOG_EXPORT int
        zlog_compare_log_msg_vc (const char *logMsg_a, const char *logMsg_b);
Kevin Sapper's avatar
Kevin Sapper committed
250
    
Kevin Sapper's avatar
Kevin Sapper committed
251
252
253
254
    //  Compares the timestamps's of given logMsg a to logMsg b.
    //  Returns -1 if a < b, otherwiese 1
    ZLOG_EXPORT int
        zlog_compare_log_msg_ts (const char *logMsg_a, const char *logMsg_b);
Kevin Sapper's avatar
Kevin Sapper committed
255
    
Kevin Sapper's avatar
Kevin Sapper committed
256
257
    //  Reads log of source filepath and orders it with given
    //  pointer to compare_function into destination filepath.
Kevin Sapper's avatar
Kevin Sapper committed
258
    
Kevin Sapper's avatar
Kevin Sapper committed
259
260
    ZLOG_EXPORT void
        zlog_order_log (const char *path_src, const char *path_dst, zlistx_comparator_fn *compare_function);
Kevin Sapper's avatar
Kevin Sapper committed
261
    
Kevin Sapper's avatar
Kevin Sapper committed
262
263
264
265
266
267
268
269
    //  Self test of this actor
    ZLOG_EXPORT void
        zlog_test (bool verbose);
```

This is the class self test code:

```c
Kevin Sapper's avatar
Kevin Sapper committed
270
    char *params1[2] = {"inproc://logger1", "GOSSIP MASTER"};
Kevin Sapper's avatar
Kevin Sapper committed
271
    zactor_t *zlog = zactor_new (zlog_actor, params1);
Kevin Sapper's avatar
Kevin Sapper committed
272
    
Kevin Sapper's avatar
Kevin Sapper committed
273
    char *params2[2] = {"inproc://logger2", "GOSSIP SLAVE"};
Kevin Sapper's avatar
Kevin Sapper committed
274
    zactor_t *zlog2 = zactor_new (zlog_actor, params2);
Kevin Sapper's avatar
Kevin Sapper committed
275
    
Kevin Sapper's avatar
Kevin Sapper committed
276
    char *params3[2] = {"inproc://logger3", "GOSSIP SLAVE"};
Kevin Sapper's avatar
Kevin Sapper committed
277
    zactor_t *zlog3 = zactor_new (zlog_actor, params3);
Kevin Sapper's avatar
Kevin Sapper committed
278
    
Kevin Sapper's avatar
Kevin Sapper committed
279
280
    /*char *params4[3] = {"inproc://logger4", "logger4", "GOSSIP SLAVE"};*/
    /*zactor_t *zlog4 = zactor_new (zlog_actor, params4);*/
Kevin Sapper's avatar
Kevin Sapper committed
281
    
Kevin Sapper's avatar
Kevin Sapper committed
282
283
284
285
    if (verbose) {
        zstr_send (zlog, "VERBOSE");
        zstr_send (zlog2, "VERBOSE");
        zstr_send (zlog3, "VERBOSE");
Kevin Sapper's avatar
Kevin Sapper committed
286
        /*zstr_send (zlog4, "VERBOSE");*/
Kevin Sapper's avatar
Kevin Sapper committed
287
    }
Kevin Sapper's avatar
Kevin Sapper committed
288
    
Kevin Sapper's avatar
Kevin Sapper committed
289
290
291
    zstr_send (zlog, "START");
    zstr_send (zlog2, "START");
    zstr_send (zlog3, "START");
Kevin Sapper's avatar
Kevin Sapper committed
292
    /*zstr_send (zlog4, "START");*/
Kevin Sapper's avatar
Kevin Sapper committed
293
    
Kevin Sapper's avatar
Kevin Sapper committed
294
295
    //  Give time to interconnect and elect
    zclock_sleep (750);
Kevin Sapper's avatar
Kevin Sapper committed
296
    
Kevin Sapper's avatar
Kevin Sapper committed
297
298
    //  Give time for log collect to happen
    zclock_sleep (12000);
Kevin Sapper's avatar
Kevin Sapper committed
299
    
Kevin Sapper's avatar
Kevin Sapper committed
300
301
302
    zstr_send (zlog, "STOP");
    zstr_send (zlog2, "STOP");
    zstr_send (zlog3, "STOP");
Kevin Sapper's avatar
Kevin Sapper committed
303
    /*zstr_send (zlog4, "STOP");*/
Kevin Sapper's avatar
Kevin Sapper committed
304
    
Kevin Sapper's avatar
Kevin Sapper committed
305
306
    //  Give time to disconnect
    zclock_sleep (250);
Kevin Sapper's avatar
Kevin Sapper committed
307
    
Kevin Sapper's avatar
Kevin Sapper committed
308
309
310
    zactor_destroy (&zlog);
    zactor_destroy (&zlog2);
    zactor_destroy (&zlog3);
Kevin Sapper's avatar
Kevin Sapper committed
311
    /*zactor_destroy (&zlog4);*/
Kevin Sapper's avatar
Kevin Sapper committed
312
    
Kevin Sapper's avatar
Kevin Sapper committed
313
    /*zlog_order_log ("/var/log/vc.log", "ordered_vc1.log");*/
Kevin Sapper's avatar
Kevin Sapper committed
314
315
```

Kevin Sapper's avatar
Kevin Sapper committed
316
<A name="toc4-290" title="zecho - Implements the echo algorithms" />
317
#### zecho - Implements the echo algorithms
Kevin Sapper's avatar
Kevin Sapper committed
318

Kevin Sapper's avatar
Kevin Sapper committed
319
320
321
322
323
324
zecho - Implements the echo algorithms which consist of two distinct waves.
        The first wave is to flood the network and build a spanning tree. It
        can be used to inform peers thus it's also called inform wave. The
        second wave is flows from the leaves of the spanning tree back to the
        initiator. It it used to collect things from peers. Collectables are
        e.g. ACKs or arbitrary data.
Kevin Sapper's avatar
Kevin Sapper committed
325
326
327
328
329

Please add @discuss section in ../src/zecho.c.

This is the class interface:

330
```h
Kevin Sapper's avatar
Kevin Sapper committed
331
    
Kevin Sapper's avatar
Kevin Sapper committed
332
333
334
335
336
337
    //  Process INFORM or COLLECT messages
    typedef void (zecho_process_fn) (
        zecho_t *self, zmsg_t *msg,  void *handler);
    //  Create custom INFORM or COLLECT messages content
    typedef zmsg_t * (zecho_create_fn) (
        zecho_t *self, void *handler);
Kevin Sapper's avatar
Kevin Sapper committed
338
    
Kevin Sapper's avatar
Kevin Sapper committed
339
340
341
    //  Create a new zecho
    ZLOG_EXPORT zecho_t *
        zecho_new (zyre_t *node);
Kevin Sapper's avatar
Kevin Sapper committed
342
    
Kevin Sapper's avatar
Kevin Sapper committed
343
344
345
    //  Destroy the zecho
    ZLOG_EXPORT void
        zecho_destroy (zecho_t **self_p);
Kevin Sapper's avatar
Kevin Sapper committed
346
    
347
348
349
    //  Initiate the echo algorithm
    ZLOG_EXPORT void
        zecho_init (zecho_t *self);
Kevin Sapper's avatar
Kevin Sapper committed
350
    
351
    //  Handle a received echo token
352
    ZLOG_EXPORT int
353
        zecho_recv (zecho_t *self, zyre_event_t *token);
Kevin Sapper's avatar
Kevin Sapper committed
354
    
Kevin Sapper's avatar
Kevin Sapper committed
355
356
357
    //  Sets a handler which is passed to custom collect functions.
    ZLOG_EXPORT void
        zecho_set_collect_handler (zecho_t *self, void *handler);
Kevin Sapper's avatar
Kevin Sapper committed
358
    
Kevin Sapper's avatar
Kevin Sapper committed
359
360
361
362
    //  Set a user-defined function to process collect messages from peers; This
    //  function is invoked during the second (incoming) wave.
    ZLOG_EXPORT void
        zecho_set_collect_process (zecho_t *self, zecho_process_fn *process_fn);
Kevin Sapper's avatar
Kevin Sapper committed
363
    
Kevin Sapper's avatar
Kevin Sapper committed
364
365
366
367
368
    //  Set a user-defined function to create a custom message part for the collect
    //  message; This function is invoked during the second (incoming) wave. The
    //  returned message's content is appended to the wave message.
    ZLOG_EXPORT void
        zecho_set_collect_create (zecho_t *self, zecho_create_fn *collect_fn);
Kevin Sapper's avatar
Kevin Sapper committed
369
    
Kevin Sapper's avatar
Kevin Sapper committed
370
371
372
    //  Sets a handler which is passed to custom inform functions.
    ZLOG_EXPORT void
        zecho_set_inform_handler (zecho_t *self, void *handler);
Kevin Sapper's avatar
Kevin Sapper committed
373
    
Kevin Sapper's avatar
Kevin Sapper committed
374
375
376
377
    //  Set a user-defined function to process inform messages from peers; This
    //  function is invoked during the first (outgoing) wave.
    ZLOG_EXPORT void
        zecho_set_inform_process (zecho_t *self, zecho_process_fn *process_fn);
Kevin Sapper's avatar
Kevin Sapper committed
378
    
Kevin Sapper's avatar
Kevin Sapper committed
379
380
381
382
383
    //  Set a user-defined function to create a custom message part for the inform
    //  message; This function is invoked during the first (outgoing) wave. The
    //  returned message's content is appended to the wave message.
    ZLOG_EXPORT void
        zecho_set_inform_create (zecho_t *self, zecho_create_fn *collect_fn);
Kevin Sapper's avatar
Kevin Sapper committed
384
    
Kevin Sapper's avatar
Kevin Sapper committed
385
386
387
388
    //  Set a vector clock handle. Echo messages will be prepended with the
    //  vector if not NULL.
    ZLOG_EXPORT void
        zecho_set_clock (zecho_t *self, zvector_t *clock);
Kevin Sapper's avatar
Kevin Sapper committed
389
    
Kevin Sapper's avatar
Kevin Sapper committed
390
391
392
    //  Enable/disable verbose logging.
    ZLOG_EXPORT void
        zecho_set_verbose (zecho_t *self, bool verbose);
Kevin Sapper's avatar
Kevin Sapper committed
393
    
Kevin Sapper's avatar
Kevin Sapper committed
394
395
396
    //  Self test of this class
    ZLOG_EXPORT void
        zecho_test (bool verbose);
Kevin Sapper's avatar
Kevin Sapper committed
397
    
398
```
Kevin Sapper's avatar
Kevin Sapper committed
399
400
401

This is the class self test code:

402
```c
Kevin Sapper's avatar
Kevin Sapper committed
403
404
405
406
407
408
409
410
411
412
413
    int rc;
    //  Init zyre nodes
    zyre_t *node1 = zyre_new ("node1");
    assert (node1);
    //  Set inproc endpoint for this node
    rc = zyre_set_endpoint (node1, "inproc://zyre-node1");
    assert (rc == 0);
    //  Set up gossip network for this node
    zyre_gossip_bind (node1, "inproc://gossip-hub");
    rc = zyre_start (node1);
    assert (rc == 0);
Kevin Sapper's avatar
Kevin Sapper committed
414
    
Kevin Sapper's avatar
Kevin Sapper committed
415
416
417
418
419
420
421
422
423
    zyre_t *node2 = zyre_new ("node2");
    assert (node2);
    //  Set inproc endpoint for this node
    rc = zyre_set_endpoint (node2, "inproc://zyre-node2");
    assert (rc == 0);
    //  Set up gossip network for this node
    zyre_gossip_connect (node2, "inproc://gossip-hub");
    rc = zyre_start (node2);
    assert (rc == 0);
Kevin Sapper's avatar
Kevin Sapper committed
424
    
Kevin Sapper's avatar
Kevin Sapper committed
425
426
427
428
429
430
431
432
433
    zyre_t *node3 = zyre_new ("node3");
    assert (node3);
    //  Set inproc endpoint for this node
    rc = zyre_set_endpoint (node3, "inproc://zyre-node3");
    assert (rc == 0);
    //  Set up gossip network for this node
    zyre_gossip_connect (node3, "inproc://gossip-hub");
    rc = zyre_start (node3);
    assert (rc == 0);
Kevin Sapper's avatar
Kevin Sapper committed
434
    
Kevin Sapper's avatar
Kevin Sapper committed
435
436
437
438
    //  Setup echo
    zecho_t *echo1 = zecho_new (node1);
    zecho_t *echo2 = zecho_new (node2);
    zecho_t *echo3 = zecho_new (node3);
Kevin Sapper's avatar
Kevin Sapper committed
439
440
441
    zecho_set_verbose (echo1, verbose);
    zecho_set_verbose (echo2, verbose);
    zecho_set_verbose (echo3, verbose);
Kevin Sapper's avatar
Kevin Sapper committed
442
443
444
445
446
447
    zecho_set_collect_process (echo1, s_test_zecho_process);
    zecho_set_collect_process (echo2, s_test_zecho_process);
    zecho_set_collect_process (echo3, s_test_zecho_process);
    zecho_set_collect_create (echo1, s_test_zecho_create);
    zecho_set_collect_create (echo2, s_test_zecho_create);
    zecho_set_collect_create (echo3, s_test_zecho_create);
Kevin Sapper's avatar
Kevin Sapper committed
448
    
Kevin Sapper's avatar
Kevin Sapper committed
449
450
451
452
453
    //  Join topology
    zyre_join (node1, "GLOBAL");
    zyre_join (node2, "GLOBAL");
    zyre_join (node2, "LOCAL");
    zyre_join (node3, "LOCAL");
Kevin Sapper's avatar
Kevin Sapper committed
454
    
Kevin Sapper's avatar
Kevin Sapper committed
455
456
    //  Give time for them to interconnect
    zclock_sleep (500);
Kevin Sapper's avatar
Kevin Sapper committed
457
    
Kevin Sapper's avatar
Kevin Sapper committed
458
459
460
461
462
463
464
465
    if (verbose) {
        zyre_dump (node1);
        zclock_sleep (50);
        zyre_dump (node2);
        zclock_sleep (50);
        zyre_dump (node3);
        zclock_sleep (50);
    }
Kevin Sapper's avatar
Kevin Sapper committed
466
    
Kevin Sapper's avatar
Kevin Sapper committed
467
    zecho_init (echo1);
Kevin Sapper's avatar
Kevin Sapper committed
468
    
469
    zyre_event_t *event = NULL;
Kevin Sapper's avatar
Kevin Sapper committed
470
    
Kevin Sapper's avatar
Kevin Sapper committed
471
472
    do {
        event = zyre_event_new (node2);
473
474
475
476
477
        if (!streq (zyre_event_type (event), "WHISPER"))
            zyre_event_destroy (&event);
        else
            break;
    } while (1);
478
    char *type = zmsg_popstr (zyre_event_msg (event));
Kevin Sapper's avatar
Kevin Sapper committed
479
    assert (streq (type, "ZECHO"));
480
    zstr_free (&type);
Kevin Sapper's avatar
Kevin Sapper committed
481
    zecho_recv (echo2, event);
Kevin Sapper's avatar
Kevin Sapper committed
482
    
Kevin Sapper's avatar
Kevin Sapper committed
483
484
    do {
        event = zyre_event_new (node3);
485
486
487
488
489
        if (!streq (zyre_event_type (event), "WHISPER"))
            zyre_event_destroy (&event);
        else
            break;
    } while (1);
490
    type = zmsg_popstr (zyre_event_msg (event));
Kevin Sapper's avatar
Kevin Sapper committed
491
    assert (streq (type, "ZECHO"));
492
    zstr_free (&type);
Kevin Sapper's avatar
Kevin Sapper committed
493
    zecho_recv (echo3, event);
Kevin Sapper's avatar
Kevin Sapper committed
494
    
Kevin Sapper's avatar
Kevin Sapper committed
495
496
    do {
        event = zyre_event_new (node2);
497
498
499
500
501
        if (!streq (zyre_event_type (event), "WHISPER"))
            zyre_event_destroy (&event);
        else
            break;
    } while (1);
502
    type = zmsg_popstr (zyre_event_msg (event));
Kevin Sapper's avatar
Kevin Sapper committed
503
    assert (streq (type, "ZECHO"));
504
    zstr_free (&type);
Kevin Sapper's avatar
Kevin Sapper committed
505
    zecho_recv (echo2, event);
Kevin Sapper's avatar
Kevin Sapper committed
506
    
Kevin Sapper's avatar
Kevin Sapper committed
507
508
    do {
        event = zyre_event_new (node1);
509
510
511
512
513
        if (!streq (zyre_event_type (event), "WHISPER"))
            zyre_event_destroy (&event);
        else
            break;
    } while (1);
514
    type = zmsg_popstr (zyre_event_msg (event));
Kevin Sapper's avatar
Kevin Sapper committed
515
    assert (streq (type, "ZECHO"));
516
    zstr_free (&type);
Kevin Sapper's avatar
Kevin Sapper committed
517
    zecho_recv (echo1, event);
Kevin Sapper's avatar
Kevin Sapper committed
518
    
Kevin Sapper's avatar
Kevin Sapper committed
519
520
521
522
523
524
    if (verbose) {
        // Print result
        zecho_print (echo1);
        zecho_print (echo2);
        zecho_print (echo3);
    }
Kevin Sapper's avatar
Kevin Sapper committed
525
    
Kevin Sapper's avatar
Kevin Sapper committed
526
527
528
529
    //  Cleanup
    zecho_destroy (&echo1);
    zecho_destroy (&echo2);
    zecho_destroy (&echo3);
Kevin Sapper's avatar
Kevin Sapper committed
530
    
531
532
533
    zyre_stop (node1);
    zyre_stop (node2);
    zyre_stop (node3);
Kevin Sapper's avatar
Kevin Sapper committed
534
    
535
536
537
    zyre_destroy (&node1);
    zyre_destroy (&node2);
    zyre_destroy (&node3);
Kevin Sapper's avatar
Kevin Sapper committed
538
    
539
```
540

Kevin Sapper's avatar
Kevin Sapper committed
541
<A name="toc4-515" title="zvector - Implements a dynamic vector clock" />
542
543
544
545
546
547
548
549
#### zvector - Implements a dynamic vector clock

zvector - Implements a dynamic vector clock

Please add @discuss section in ../src/zvector.c.

This is the class interface:

550
```h
551
552
553
    //  Create a new zvector
    ZLOG_EXPORT zvector_t *
        zvector_new (const char* pid);
Kevin Sapper's avatar
Kevin Sapper committed
554
    
555
556
557
    //  Destroy the zvector
    ZLOG_EXPORT void
        zvector_destroy (zvector_t **self_p);
Kevin Sapper's avatar
Kevin Sapper committed
558
    
Kevin Sapper's avatar
Kevin Sapper committed
559
560
561
    //  Eventing own clock & packing vectorclock with given msg
    ZLOG_EXPORT zmsg_t *
        zvector_send_prepare (zvector_t *self, zmsg_t *msg);
Kevin Sapper's avatar
Kevin Sapper committed
562
    
Kevin Sapper's avatar
Kevin Sapper committed
563
564
565
    //  Recv the zvector & updates own vectorclock
    ZLOG_EXPORT void
        zvector_recv (zvector_t *self, zmsg_t *msg);
Kevin Sapper's avatar
Kevin Sapper committed
566
    
Kevin Sapper's avatar
Kevin Sapper committed
567
568
569
    //  Converts the zvector into string representation
    ZLOG_EXPORT char *
        zvector_to_string (zvector_t *self);
Kevin Sapper's avatar
Kevin Sapper committed
570
    
Kevin Sapper's avatar
Kevin Sapper committed
571
572
573
    //  Converts the zvector into string representation with pid_length
    ZLOG_EXPORT char *
        zvector_to_string_short (zvector_t *self, uint8_t pid_length);
Kevin Sapper's avatar
Kevin Sapper committed
574
    
Kevin Sapper's avatar
Kevin Sapper committed
575
576
577
    //  Creates a zvector from a given string representation
    ZLOG_EXPORT zvector_t *
        zvector_from_string (char *clock_string);
Kevin Sapper's avatar
Kevin Sapper committed
578
    
Kevin Sapper's avatar
Kevin Sapper committed
579
580
    ZLOG_EXPORT void
        zvector_dump_time_space (zvector_t *self);
Kevin Sapper's avatar
Kevin Sapper committed
581
    
Kevin Sapper's avatar
Kevin Sapper committed
582
583
584
585
586
    //  Compares zvector self to zvector other.
    //  Returns -1 at happened before self, 0 at parallel, 1 at happened after
    //  and 2 when clocks are the same
    ZLOG_EXPORT int
        zvector_compare_to (zvector_t *zv_self, zvector_t *zv_other);
Kevin Sapper's avatar
Kevin Sapper committed
587
    
Kevin Sapper's avatar
Kevin Sapper committed
588
589
590
    //  Log informational message - low priority. Prepends the current VC.
    ZLOG_EXPORT void
        zvector_info (zvector_t *self, char *format, ...);
Kevin Sapper's avatar
Kevin Sapper committed
591
    
Kevin Sapper's avatar
Kevin Sapper committed
592
593
594
    //  Duplicates the given zvector, returns a freshly allocated dulpicate.
    ZLOG_EXPORT  zvector_t *
        zvector_dup (zvector_t *self);
Kevin Sapper's avatar
Kevin Sapper committed
595
    
Kevin Sapper's avatar
Kevin Sapper committed
596
597
598
    //  Prints the zvector for debug purposes
    ZLOG_EXPORT void
        zvector_print (zvector_t *self);
Kevin Sapper's avatar
Kevin Sapper committed
599
    
600
601
602
    //  Self test of this class
    ZLOG_EXPORT void
        zvector_test (bool verbose);
Kevin Sapper's avatar
Kevin Sapper committed
603
    
604
```
605
606
607

This is the class self test code:

608
```c
Kevin Sapper's avatar
Kevin Sapper committed
609
    //  TEST: create/destroy zvector_t
Kevin Sapper's avatar
Kevin Sapper committed
610
611
    zvector_t *test1_self = zvector_new ("1000");
    assert (test1_self);
612
    zvector_destroy (&test1_self);
Kevin Sapper's avatar
Kevin Sapper committed
613
    
Kevin Sapper's avatar
Kevin Sapper committed
614
615
    //  TEST: for converting a zvector to stringrepresentation and from
    //        string represenstation to zvector.
Kevin Sapper's avatar
Kevin Sapper committed
616
    zvector_t *test2_self = zvector_new ("1000");
617
    assert (test2_self);
Kevin Sapper's avatar
Kevin Sapper committed
618
    
Kevin Sapper's avatar
Kevin Sapper committed
619
    //  Inserting some clocks & values
Kevin Sapper's avatar
Kevin Sapper committed
620
621
622
623
624
625
626
    zvector_event (test2_self);
    unsigned long *test2_inserted_value1 = (unsigned long *) zmalloc (sizeof (unsigned long));
    *test2_inserted_value1 = 7;
    zhashx_insert (test2_self->clock, "1001", test2_inserted_value1);
    unsigned long *test2_inserted_value2 = (unsigned long *) zmalloc (sizeof (unsigned long));
    *test2_inserted_value2 = 11;
    zhashx_insert (test2_self->clock, "1002", test2_inserted_value2);
Kevin Sapper's avatar
Kevin Sapper committed
627
    
Kevin Sapper's avatar
Kevin Sapper committed
628
    char *test2_string = zvector_to_string (test2_self);
Kevin Sapper's avatar
Kevin Sapper committed
629
    assert (streq (test2_string, "VC:3;own:1000;1001,7;1000,1;1002,11;"));
Kevin Sapper's avatar
Kevin Sapper committed
630
    
Kevin Sapper's avatar
Kevin Sapper committed
631
632
633
634
    zvector_t *test2_generated = zvector_from_string (test2_string);
    assert ( *(unsigned long *) zhashx_lookup (test2_generated->clock, "1000") == 1 );
    assert ( *(unsigned long *) zhashx_lookup (test2_generated->clock, "1001") == 7 );
    assert ( *(unsigned long *) zhashx_lookup (test2_generated->clock, "1002") == 11 );
Kevin Sapper's avatar
Kevin Sapper committed
635
    
Kevin Sapper's avatar
Kevin Sapper committed
636
637
638
    zstr_free (&test2_string);
    zvector_destroy (&test2_self);
    zvector_destroy (&test2_generated);
Kevin Sapper's avatar
Kevin Sapper committed
639
    
Kevin Sapper's avatar
Kevin Sapper committed
640
    //  TEST: events
Kevin Sapper's avatar
Kevin Sapper committed
641
642
    zvector_t *test3_self = zvector_new ("1000");
    assert (test3_self);
Kevin Sapper's avatar
Kevin Sapper committed
643
    
Kevin Sapper's avatar
Kevin Sapper committed
644
645
646
647
    unsigned long *test3_value1 = (unsigned long *) zmalloc (sizeof (unsigned long));
    *test3_value1 = 5;
    zhashx_insert (test3_self->clock, "1001", test3_value1);
    assert ( *(unsigned long *) zhashx_lookup (test3_self->clock, "1000") == 0 );
Kevin Sapper's avatar
Kevin Sapper committed
648
    
Kevin Sapper's avatar
Kevin Sapper committed
649
650
651
652
    zvector_event (test3_self);
    assert ( *(unsigned long *) zhashx_lookup (test3_self->clock, "1000") == 1 );
    assert ( *(unsigned long *) zhashx_lookup (test3_self->clock, "1001") == 5 );
    zvector_destroy (&test3_self);
Kevin Sapper's avatar
Kevin Sapper committed
653
    
Kevin Sapper's avatar
Kevin Sapper committed
654
    //  TEST: recv test
Kevin Sapper's avatar
Kevin Sapper committed
655
    zvector_t *test4_self_clock = zvector_new ("1000");
Kevin Sapper's avatar
Kevin Sapper committed
656
657
    char *test4_sender_clock1_stringRep = zsys_sprintf ("%s", "VC:2;own:1001;1000,5;1001,10;");
    char *test4_sender_clock2_stringRep = zsys_sprintf ("%s", "VC:2;own:1002;1000,20;1002,30;");
Kevin Sapper's avatar
Kevin Sapper committed
658
    assert (test4_self_clock);
Kevin Sapper's avatar
Kevin Sapper committed
659
    
Kevin Sapper's avatar
Kevin Sapper committed
660
    //  Receive sender clock 1 and add key-value pairs to own clock
Kevin Sapper's avatar
Kevin Sapper committed
661
    zmsg_t *test4_msg1 = zmsg_new ();
Kevin Sapper's avatar
Kevin Sapper committed
662
    zmsg_pushstr (test4_msg1, test4_sender_clock1_stringRep);
Kevin Sapper's avatar
Kevin Sapper committed
663
664
665
666
    zvector_recv (test4_self_clock, test4_msg1);
    zmsg_destroy (&test4_msg1);
    assert ( *(unsigned long *) zhashx_lookup (test4_self_clock->clock, "1000") == 5 );
    assert ( *(unsigned long *) zhashx_lookup (test4_self_clock->clock, "1001") == 10 );
Kevin Sapper's avatar
Kevin Sapper committed
667
    
Kevin Sapper's avatar
Kevin Sapper committed
668
    //  Receive sender clock 2 and add key-value pairs to own clock
Kevin Sapper's avatar
Kevin Sapper committed
669
    test4_msg1 = zmsg_new ();
Kevin Sapper's avatar
Kevin Sapper committed
670
    zmsg_pushstr (test4_msg1, test4_sender_clock2_stringRep);
Kevin Sapper's avatar
Kevin Sapper committed
671
672
673
674
675
    zvector_recv (test4_self_clock, test4_msg1);
    zmsg_destroy (&test4_msg1);
    assert ( *(unsigned long *) zhashx_lookup (test4_self_clock->clock, "1000") == 20 );
    assert ( *(unsigned long *) zhashx_lookup (test4_self_clock->clock, "1001") == 10 );
    assert ( *(unsigned long *) zhashx_lookup (test4_self_clock->clock, "1002") == 30 );
Kevin Sapper's avatar
Kevin Sapper committed
676
    
Kevin Sapper's avatar
Kevin Sapper committed
677
678
679
    zstr_free (&test4_sender_clock1_stringRep);
    zstr_free (&test4_sender_clock2_stringRep);
    zvector_destroy (&test4_self_clock);
Kevin Sapper's avatar
Kevin Sapper committed
680
    
Kevin Sapper's avatar
Kevin Sapper committed
681
    // TEST: send prepare
682
683
684
    zvector_t *test5_self = zvector_new ("1000");
    assert (test5_self);
    zvector_event (test5_self);
Kevin Sapper's avatar
Kevin Sapper committed
685
686
    zmsg_t *test5_zmsg = zmsg_new ();
    zmsg_pushstr (test5_zmsg, "test");
Kevin Sapper's avatar
Kevin Sapper committed
687
    
Kevin Sapper's avatar
Kevin Sapper committed
688
    zvector_send_prepare (test5_self, test5_zmsg);
Kevin Sapper's avatar
Kevin Sapper committed
689
690
    char *test5_clock_string = zmsg_popstr (test5_zmsg);
    zvector_t *test5_unpacked_clock = zvector_from_string (test5_clock_string);
Kevin Sapper's avatar
Kevin Sapper committed
691
692
    char *test5_unpacked_string = zmsg_popstr (test5_zmsg);
    assert (streq (test5_unpacked_string, "test"));
Kevin Sapper's avatar
Kevin Sapper committed
693
    assert ( *(unsigned long *) zhashx_lookup (test5_unpacked_clock->clock, "1000") == 2 );
Kevin Sapper's avatar
Kevin Sapper committed
694
    
Kevin Sapper's avatar
Kevin Sapper committed
695
    zstr_free (&test5_clock_string);
Kevin Sapper's avatar
Kevin Sapper committed
696
697
    zstr_free (&test5_unpacked_string);
    zmsg_destroy (&test5_zmsg);
698
    zvector_destroy (&test5_self);
Kevin Sapper's avatar
Kevin Sapper committed
699
    zvector_destroy (&test5_unpacked_clock);
Kevin Sapper's avatar
Kevin Sapper committed
700
    
Kevin Sapper's avatar
Kevin Sapper committed
701
702
703
704
705
706
707
708
709
710
    // TEST: compare
    char *test6_self_stringrep = zsys_sprintf ("%s", "VC:3;own:p2;p1,2;p2,2;p3,2;");
    char *test6_before_stringrep1 = zsys_sprintf ("%s", "VC:2;own:p3;p1,1;p3,2;");
    char *test6_before_stringrep2 = zsys_sprintf ("%s", "VC:2;own:p2;p1,2;p2,1;");
    char *test6_before_stringrep3 = zsys_sprintf ("%s", "VC:1;own:p1;p1,1;");
    char *test6_parallel_stringrep1 = zsys_sprintf ("%s", "VC:1;own:p1;p1,3;");
    char *test6_parallel_stringrep2 = zsys_sprintf ("%s", "VC:2;own:p3;p1,1;p3,3;");
    char *test6_parallel_stringrep3 = zsys_sprintf ("%s", "VC:2;own:p1;p1,4;p3,3;");
    char *test6_after_stringrep1 = zsys_sprintf ("%s", "VC:3;own:p2;p1,2;p2,3;p3,2;");
    char *test6_after_stringrep2 = zsys_sprintf ("%s", "VC:3;own:p3;p1,2;p2,3;p3,4;");
Kevin Sapper's avatar
Kevin Sapper committed
711
712
713
714
715
716
717
718
719
    zvector_t *test6_self = zvector_from_string (test6_self_stringrep);
    zvector_t *test6_before1 = zvector_from_string (test6_before_stringrep1);
    zvector_t *test6_before2 = zvector_from_string (test6_before_stringrep2);
    zvector_t *test6_before3 = zvector_from_string (test6_before_stringrep3);
    zvector_t *test6_parallel1 = zvector_from_string (test6_parallel_stringrep1);
    zvector_t *test6_parallel2 = zvector_from_string (test6_parallel_stringrep2);
    zvector_t *test6_parallel3 = zvector_from_string (test6_parallel_stringrep3);
    zvector_t *test6_after1 = zvector_from_string (test6_after_stringrep1);
    zvector_t *test6_after2 = zvector_from_string (test6_after_stringrep2);
Kevin Sapper's avatar
Kevin Sapper committed
720
    
Kevin Sapper's avatar
Kevin Sapper committed
721
722
723
724
725
726
727
728
    assert (zvector_compare_to (test6_self, test6_before1) == 1);
    assert (zvector_compare_to (test6_self, test6_before2) == 1);
    assert (zvector_compare_to (test6_self, test6_before3) == 1);
    assert (zvector_compare_to (test6_self, test6_parallel1) == 0);
    assert (zvector_compare_to (test6_self, test6_parallel2) == 0);
    assert (zvector_compare_to (test6_self, test6_parallel3) == 0);
    assert (zvector_compare_to (test6_self, test6_after1) == -1);
    assert (zvector_compare_to (test6_self, test6_after2) == -1);
Kevin Sapper's avatar
Kevin Sapper committed
729
    
Kevin Sapper's avatar
Kevin Sapper committed
730
731
732
733
734
735
736
737
738
    zstr_free (&test6_self_stringrep);
    zstr_free (&test6_before_stringrep1);
    zstr_free (&test6_before_stringrep2);
    zstr_free (&test6_before_stringrep3);
    zstr_free (&test6_parallel_stringrep1);
    zstr_free (&test6_parallel_stringrep2);
    zstr_free (&test6_parallel_stringrep3);
    zstr_free (&test6_after_stringrep1);
    zstr_free (&test6_after_stringrep2);
Kevin Sapper's avatar
Kevin Sapper committed
739
    
Kevin Sapper's avatar
Kevin Sapper committed
740
741
742
743
744
745
746
747
748
    zvector_destroy (&test6_self);
    zvector_destroy (&test6_before1);
    zvector_destroy (&test6_before2);
    zvector_destroy (&test6_before3);
    zvector_destroy (&test6_parallel1);
    zvector_destroy (&test6_parallel2);
    zvector_destroy (&test6_parallel3);
    zvector_destroy (&test6_after1);
    zvector_destroy (&test6_after2);
Kevin Sapper's avatar
Kevin Sapper committed
749
750
    
    
751
```
Kevin Sapper's avatar
Kevin Sapper committed
752

Kevin Sapper's avatar
Kevin Sapper committed
753
<A name="toc4-727" title="bakery - Bakery with zlogger support" />
Kevin Sapper's avatar
Kevin Sapper committed
754
755
756
757
758
759
760
761
762
763
764
765
766
767
#### bakery - Bakery with zlogger support

bakery - Bakery with zlogger support

Please add @discuss section in ../src/bakery.c.

This is the class interface:

Please add @interface section in ../src/bakery.c.

This is the class self test code:

Please add @selftest section in ../src/bakery.c.

Kevin Sapper's avatar
Kevin Sapper committed
768

Kevin Sapper's avatar
Kevin Sapper committed
769
<A name="toc3-743" title="Hints to Contributors" />
Kevin Sapper's avatar
Kevin Sapper committed
770
771
772
773
774
775
776
777
### Hints to Contributors

Zlogger is a nice, neat library, and you may not immediately appreciate why. Read the CLASS style guide please, and write your code to make it indistinguishable from the rest of the code in the library. That is the only real criteria for good style: it's invisible.

Don't include system headers in source files. The right place for these is CZMQ.

Do read your code after you write it and ask, "Can I make this simpler?" We do use a nice minimalist and yet readable style. Learn it, adopt it, use it.

Kevin Sapper's avatar
Kevin Sapper committed
778
779
Before opening a pull request read our [contribution guidelines](https://zenon.cs.hs-rm.de/causality-logger/zlogger/blob/master/README.md).
Thanks!
Kevin Sapper's avatar
Kevin Sapper committed
780

Kevin Sapper's avatar
Kevin Sapper committed
781
<A name="toc3-755" title="This Document" />
Kevin Sapper's avatar
Kevin Sapper committed
782
783
784
### This Document

_This documentation was generated from zlogger/README.txt using [Gitdown](https://github.com/zeromq/gitdown)_