Hello community, here is the log from the commit of package raft for openSUSE:Factory checked in at 2019-09-20 14:52:35 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/raft (Old) and /work/SRC/openSUSE:Factory/.raft.new.7948 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "raft" Fri Sep 20 14:52:35 2019 rev:2 rq:731823 version:0.9.6 Changes: -------- --- /work/SRC/openSUSE:Factory/raft/raft.changes 2019-09-05 12:44:29.895453685 +0200 +++ /work/SRC/openSUSE:Factory/.raft.new.7948/raft.changes 2019-09-20 14:52:45.770887790 +0200 @@ -1,0 +2,7 @@ +Thu Sep 19 02:06:51 UTC 2019 - Andreas Stieger <[email protected]> + +- raft 0.9.6: + * raft_watch API dropped + * don't stop half-way when deleting old segments + +------------------------------------------------------------------- Old: ---- raft-0.9.5.tar.gz New: ---- raft-0.9.6.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ raft.spec ++++++ --- /var/tmp/diff_new_pack.nD26Tp/_old 2019-09-20 14:52:47.194887507 +0200 +++ /var/tmp/diff_new_pack.nD26Tp/_new 2019-09-20 14:52:47.194887507 +0200 @@ -18,13 +18,13 @@ %bcond_without libuv Name: raft -Version: 0.9.5 +Version: 0.9.6 Release: 0 Summary: Fully asynchronous C implementation of the Raft consensus protocol License: Apache-2.0 Group: Development/Libraries/C and C++ URL: https://github.com/canonical/raft -Source: https://github.com/canonical/raft/archive/v0.9.5.tar.gz#/%{name}-%{version}.tar.gz +Source: https://github.com/canonical/raft/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz BuildRequires: autoconf BuildRequires: automake BuildRequires: libtool ++++++ raft-0.9.5.tar.gz -> raft-0.9.6.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/raft-0.9.5/.travis.yml new/raft-0.9.6/.travis.yml --- old/raft-0.9.5/.travis.yml 2019-08-14 14:41:11.000000000 +0200 +++ new/raft-0.9.6/.travis.yml 2019-09-16 12:03:25.000000000 +0200 @@ -13,7 +13,7 @@ - gcc script: - autoreconf -i - - ./configure --disable-uv --enable-debug --enable-code-coverage --enable-sanitize + - ./configure --enable-example --enable-debug --enable-code-coverage --enable-sanitize - ./test/lib/fs.sh setup - CFLAGS=-O0 - make diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/raft-0.9.5/README.md new/raft-0.9.6/README.md --- old/raft-0.9.5/README.md 2019-08-14 14:41:11.000000000 +0200 +++ new/raft-0.9.6/README.md 2019-09-16 12:03:25.000000000 +0200 @@ -1,20 +1,20 @@ -[](https://travis-ci.org/CanonicalLtd/raft) [](https://codecov.io/gh/CanonicalLtd/raft) +[](https://travis-ci.org/canonical/raft) [](https://codecov.io/gh/canonical/raft) Fully asynchronous C implementation of the Raft consensus protocol. The library has modular design: its core part implements only the core Raft algorithm logic, in a fully platform independent way. On top of that, a pluggable interface defines the I/O implementation for networking (send/receive -RPC messages) and disk persistence (store log entries). +RPC messages) and disk persistence (store log entries and snapshots). A stock implementation of the I/O interface is provided when building the library with default options. It is based on [libuv](http://libuv.org) and -should fit the fast majority of use cases. The only catch is that it requires -Linux, since it uses the Linux +should fit the vast majority of use cases. The only catch is that it currently +requires Linux, since it uses the Linux [AIO](http://man7.org/linux/man-pages/man2/io_submit.2.html) API for disk I/O. Patches are welcome to add support for more platforms. -See [raft.h](https://github.com/CanonicalLtd/raft/blob/master/include/raft.h) for full documentation. +See [raft.h](https://github.com/canonical/raft/blob/master/include/raft.h) for full documentation. Features -------- @@ -38,7 +38,7 @@ ```bash autoreconf -i -./configure +./configure --enable-example make ``` @@ -46,13 +46,13 @@ ------- The best way to understand how to use the library is probably reading the code -of the [example server](https://github.com/CanonicalLtd/raft/blob/master/example/server.c) +of the [example server](https://github.com/canonical/raft/blob/master/example/server.c) included in the source code. You can also see the example server in action by running: ```bash -./example-cluster +./example/cluster ``` which spawns a little cluster of 3 servers, runs a sample workload, and randomly @@ -62,10 +62,24 @@ ----------- It is recommended that you read -[raft.h](https://github.com/CanonicalLtd/raft/blob/master/include/raft.h) for +[raft.h](https://github.com/canonical/raft/blob/master/include/raft.h) for documentation details, but here's a quick high-level guide of what you'll need to do (error handling is omitted for brevity). +Create an instance of the stock ```raft_io``` interface implementation (or +implement your own one if the one that comes with the library really does not +fit): + +```C +const char *dir = "/your/raft/data"; +struct uv_loop_s loop; +struct raft_uv_transport transport; +struct raft_io io; +uv_loop_init(&loop); +raft_uv_tcp_init(&transport, &loop); +raft_uv_init(&io, &loop, dir, &transport); +``` + Define your application Raft FSM, implementing the ```raft_fsm``` interface: ```C @@ -78,17 +92,11 @@ } ``` -Create an instance of the stock ```raft_io``` interface (or implement your one -if really the one that comes with the library does not fit): +Create an instance of the stock ```raft_logger``` interface implementation: ```C -const char *dir = "/your/raft/data"; -struct uv_loop_s loop; -struct raft_uv_transport transport; -struct raft_io io; -uv_loop_init(&loop); -raft_uv_tcp_init(&transport, &loop); -raft_uv_init(&io, &loop, dir, &transport); +struct raft_logger logger; +raft_ring_logger_init(&logger, stdio); ``` Pick a unique ID and address for each server and initialize the raft object: @@ -97,7 +105,7 @@ unsigned id = 1; const char *address = "192.168.1.1:9999"; struct raft raft; -raft_init(&raft, &io, &fsm, id, address); +raft_init(&raft, &io, &fsm, &logger, id, address); ``` If it's the first time you start the cluster, create a configuration object @@ -132,11 +140,14 @@ buf.base = ...; /* Your FSM entry data */ raft_apply(&raft, &req, &buf, 1, apply_callback); ``` + +To add more servers to the cluster use the ```raft_add()``` and +```raft_promote``` APIs. Notable users ------------- -- [dqlite](https://github.com/CanonicalLtd/dqlite) +- [dqlite](https://github.com/canonical/dqlite) Credits ------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/raft-0.9.5/example/cluster.c new/raft-0.9.6/example/cluster.c --- old/raft-0.9.5/example/cluster.c 2019-08-14 14:41:11.000000000 +0200 +++ new/raft-0.9.6/example/cluster.c 2019-09-16 12:03:25.000000000 +0200 @@ -9,16 +9,16 @@ #define N_SERVERS 3 /* Number of servers in the example cluster */ -static void forkServer(const char *topLevelDir, int i, int *pid) +static void forkServer(const char *topLevelDir, unsigned i, pid_t *pid) { *pid = fork(); if (*pid == 0) { char *dir = malloc(strlen(topLevelDir) + strlen("/D") + 1); - char *id = malloc(2); + char *id = malloc(N_SERVERS/10+2); char *argv[] = {"./example/server", dir, id, NULL}; char *envp[] = {NULL}; - sprintf(dir, "%s/%d", topLevelDir, i + 1); - sprintf(id, "%d", i + 1); + sprintf(dir, "%s/%u", topLevelDir, i + 1); + sprintf(id, "%u", i + 1); execve("./example/server", argv, envp); } } @@ -28,8 +28,8 @@ const char *topLevelDir = "/tmp/raft"; struct timespec now; struct stat statBuf; - int pids[N_SERVERS]; - int i; + pid_t pids[N_SERVERS]; + unsigned i; int rv; if (argc > 2) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/raft-0.9.5/include/raft.h new/raft-0.9.6/include/raft.h --- old/raft-0.9.5/include/raft.h 2019-08-14 14:41:11.000000000 +0200 +++ new/raft-0.9.6/include/raft.h 2019-09-16 12:03:25.000000000 +0200 @@ -667,12 +667,6 @@ typedef void (*raft_close_cb)(struct raft *raft); /** - * State watch callback. Invoked after a raft server changes its state. It gets - * passed the old server state before the change. See @raft_watch. - */ -typedef void (*raft_watch_cb)(struct raft *raft, int old_state); - -/** * Hold and drive the state of a single raft server in a cluster. */ struct raft @@ -822,11 +816,6 @@ * Callback to invoke once a close request has completed. */ raft_close_cb close_cb; - - /* - * Callback to invoke whenever the state changes. - */ - raft_watch_cb watch_cb; }; /** @@ -913,11 +902,6 @@ RAFT_API int raft_state(struct raft *r); /** - * Invoke the given watch callback whenever the current raft state changes. - */ -RAFT_API void raft_watch(struct raft *r, raft_watch_cb cb); - -/** * Return the ID and address of the current known leader, if any. */ RAFT_API void raft_leader(struct raft *r, unsigned *id, const char **address); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/raft-0.9.5/src/convert.c new/raft-0.9.6/src/convert.c --- old/raft-0.9.5/src/convert.c 2019-08-14 14:41:11.000000000 +0200 +++ new/raft-0.9.6/src/convert.c 2019-09-16 12:03:25.000000000 +0200 @@ -8,8 +8,8 @@ #include "request.h" /* Convenience for setting a new state value and asserting that the transition - * is valid. Return the old state. */ -static int setState(struct raft *r, int new_state) + * is valid. */ +static void setState(struct raft *r, int new_state) { int old_state = r->state; @@ -25,8 +25,6 @@ (old_state == RAFT_CANDIDATE && new_state == RAFT_UNAVAILABLE) || (old_state == RAFT_LEADER && new_state == RAFT_UNAVAILABLE)); r->state = new_state; - - return old_state; } /* Clear follower state. */ @@ -125,38 +123,25 @@ } } -/* Possibly trigger the watch callback if set. */ -static void triggerWatchCb(struct raft *r, int old_state) -{ - if (r->watch_cb != NULL) { - r->watch_cb(r, old_state); - } -} - void convertToFollower(struct raft *r) { - int old_state; - clear(r); - old_state = setState(r, RAFT_FOLLOWER); + setState(r, RAFT_FOLLOWER); /* Reset election timer. */ electionResetTimer(r); r->follower_state.current_leader.id = 0; r->follower_state.current_leader.address = NULL; - - triggerWatchCb(r, old_state); } int convertToCandidate(struct raft *r) { size_t n_voting = configurationNumVoting(&r->configuration); - int old_state; int rv; clear(r); - old_state = setState(r, RAFT_CANDIDATE); + setState(r, RAFT_CANDIDATE); /* Allocate the votes array. */ r->candidate_state.votes = raft_malloc(n_voting * sizeof(bool)); @@ -172,18 +157,15 @@ return rv; } - triggerWatchCb(r, old_state); - return 0; } int convertToLeader(struct raft *r) { - int old_state; int rv; clear(r); - old_state = setState(r, RAFT_LEADER); + setState(r, RAFT_LEADER); /* Reset timers */ r->election_timer_start = r->io->time(r->io); @@ -205,15 +187,11 @@ r->leader_state.round_index = 0; r->leader_state.round_start = 0; - triggerWatchCb(r, old_state); - return 0; } void convertToUnavailable(struct raft *r) { - int old_state; clear(r); - old_state = setState(r, RAFT_UNAVAILABLE); - triggerWatchCb(r, old_state); + setState(r, RAFT_UNAVAILABLE); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/raft-0.9.5/src/raft.c new/raft-0.9.6/src/raft.c --- old/raft-0.9.5/src/raft.c 2019-08-14 14:41:11.000000000 +0200 +++ new/raft-0.9.6/src/raft.c 2019-09-16 12:03:25.000000000 +0200 @@ -60,7 +60,6 @@ r->snapshot.trailing = DEFAULT_SNAPSHOT_TRAILING; r->snapshot.put.data = NULL; r->close_cb = NULL; - r->watch_cb = NULL; rv = r->io->init(r->io, r->logger, r->id, r->address); if (rv != 0) { return rv; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/raft-0.9.5/src/state.c new/raft-0.9.6/src/state.c --- old/raft-0.9.5/src/state.c 2019-08-14 14:41:11.000000000 +0200 +++ new/raft-0.9.6/src/state.c 2019-09-16 12:03:25.000000000 +0200 @@ -42,8 +42,3 @@ { r->logger->level = level; } - -void raft_watch(struct raft *r, raft_watch_cb cb) -{ - r->watch_cb = cb; -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/raft-0.9.5/src/uv.c new/raft-0.9.6/src/uv.c --- old/raft-0.9.5/src/uv.c 2019-08-14 14:41:11.000000000 +0200 +++ new/raft-0.9.6/src/uv.c 2019-09-16 12:03:25.000000000 +0200 @@ -58,7 +58,7 @@ /* Detect the I/O capabilities of the underlying file system. */ rv = uvProbeIoCapabilities(uv->dir, &direct_io, &uv->async_io, errmsg); if (rv != 0) { - uvErrorf(uv, "probe I/O capabilities: %s", uv_strerror(rv)); + uvErrorf(uv, "probe I/O capabilities: %s", errmsg); rv = RAFT_IOERR; goto err; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/raft-0.9.5/src/uv_segment.c new/raft-0.9.6/src/uv_segment.c --- old/raft-0.9.5/src/uv_segment.c 2019-08-14 14:41:11.000000000 +0200 +++ new/raft-0.9.6/src/uv_segment.c 2019-09-16 12:03:25.000000000 +0200 @@ -116,7 +116,7 @@ size_t trailing, size_t *deleted) { - size_t retain_index; + raft_index retain_index; size_t i; uvErrMsg errmsg; int rv; @@ -146,8 +146,9 @@ return rv; } *deleted = i; - } - break; + } else { + break; + } } return 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/raft-0.9.5/test/integration/test_election.c new/raft-0.9.6/test/integration/test_election.c --- old/raft-0.9.5/test/integration/test_election.c 2019-08-14 14:41:11.000000000 +0200 +++ new/raft-0.9.6/test/integration/test_election.c 2019-09-16 12:03:25.000000000 +0200 @@ -14,34 +14,19 @@ struct fixture { FIXTURE_CLUSTER; - struct /* Capture information about last watch cb invokation */ - { - struct raft *raft; - int old_state; - } watch_cb; }; -static void watchCb(struct raft *r, int old_state) -{ - struct fixture *f = r->data; - f->watch_cb.raft = r; - f->watch_cb.old_state = old_state; -} - static void *setup(const MunitParameter params[], void *user_data) { struct fixture *f = munit_malloc(sizeof *f); unsigned i; (void)user_data; - f->watch_cb.raft = NULL; - f->watch_cb.old_state = 0; SETUP_CLUSTER(2); CLUSTER_BOOTSTRAP; for (i = 0; i < CLUSTER_N; i++) { struct raft *raft = CLUSTER_RAFT(i); raft->data = f; } - CLUSTER_WATCH(watchCb); return f; } @@ -118,14 +103,6 @@ /* Assert that the fixture time matches the given value */ #define ASSERT_TIME(TIME) munit_assert_int(CLUSTER_TIME, ==, TIME) -/* Assert that the last watch callback invokation was passed the given - * values. */ -#define ASSERT_WATCH(I, OLD_STATE) \ - { \ - munit_assert_ptr_equal(f->watch_cb.raft, CLUSTER_RAFT(I)); \ - munit_assert_int(f->watch_cb.old_state, ==, OLD_STATE); \ - } - /****************************************************************************** * * Successful election round @@ -160,7 +137,6 @@ CLUSTER_STEP; /* Server 1 receives RequestVote RPC result */ ASSERT_LEADER(0); ASSERT_TIME(1030); - ASSERT_WATCH(0, RAFT_CANDIDATE); return MUNIT_OK; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/raft-0.9.5/test/lib/cluster.h new/raft-0.9.6/test/lib/cluster.h --- old/raft-0.9.5/test/lib/cluster.h 2019-08-14 14:41:11.000000000 +0200 +++ new/raft-0.9.6/test/lib/cluster.h 2019-09-16 12:03:25.000000000 +0200 @@ -378,15 +378,6 @@ /* Return the number of messages sent by the given server. */ #define CLUSTER_N_RECV(I, TYPE) raft_fixture_n_recv(&f->cluster, I, TYPE) -/* Setup a watch callback across all raft instances of the cluster. */ -#define CLUSTER_WATCH(CB) \ - { \ - unsigned i_; \ - for (i_ = 0; i_ < CLUSTER_N; i_++) { \ - raft_watch(CLUSTER_RAFT(i_), CB); \ - } \ - } - /* Set a fixture hook that randomizes election timeouts, disk latency and * network latency. */ #define CLUSTER_RANDOMIZE \
