Skip to content

Commit 8fd3396

Browse files
committed
First skeleton for the wsrep node example
1 parent ee9ab2c commit 8fd3396

26 files changed

+2584
-7
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
*~
12
*.o
23
*.a
34
*.diff
@@ -6,3 +7,4 @@ CMakeFiles
67
CMakeCache.txt
78
cmake_install.cmake
89
Makefile
10+
examples/node/node

CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ INCLUDE_DIRECTORIES(".")
1919

2020
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror -Wconversion")
2121

22+
IF (NOT CMAKE_BUILD_TYPE)
23+
SET(CMAKE_BUILD_TYPE Release)
24+
ENDIF()
25+
2226
SET(WSREP_SOURCES wsrep_gtid.c wsrep_uuid.c wsrep_loader.c wsrep_dummy.c)
2327

2428
ADD_LIBRARY(wsrep ${WSREP_SOURCES})

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22

33
Building:
44
```
5-
cmake . && make
5+
cmake [-DCMAKE_BUILD_TYPE=Debug|Release] . && make [VERBOSE=1]
66
```
7+
in top directory.

examples/CMakeLists.txt

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2018, Codership Oy. All rights reserved.
1+
# Copyright (c) 2019, Codership Oy. All rights reserved.
22
#
33
# This program is free software; you can redistribute it and/or modify
44
# it under the terms of the GNU General Public License as published by
@@ -15,3 +15,5 @@
1515

1616
ADD_EXECUTABLE(listener listener.c)
1717
TARGET_LINK_LIBRARIES(listener wsrep dl pthread)
18+
19+
ADD_SUBDIRECTORY(node)

examples/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@
33
### 1. Listener
44
Is a simple program that connects and listens to replication events in
55
an existing cluster.
6+
7+
### 2. Node
8+
Is a more complex program which implements most of wsrep node functionality
9+
and can form clusters in itself.

examples/node/CMakeLists.txt

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Copyright (c) 2019, Codership Oy. All rights reserved.
2+
#
3+
# This program is free software; you can redistribute it and/or modify
4+
# it under the terms of the GNU General Public License as published by
5+
# the Free Software Foundation; version 2 of the License.
6+
#
7+
# This program is distributed in the hope that it will be useful,
8+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
# GNU General Public License for more details.
11+
#
12+
# You should have received a copy of the GNU General Public License
13+
# along with this program; if not, write to the Free Software
14+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15+
16+
FILE(GLOB SRC
17+
"*.h"
18+
"*.c"
19+
)
20+
21+
ADD_EXECUTABLE(node ${SRC})
22+
23+
TARGET_LINK_LIBRARIES(node wsrep dl pthread)

examples/node/README.md

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# wsrep API node application
2+
3+
## Overview
4+
5+
This is a simple application to demonstrate the usage of wsrep API. It
6+
deliberately does nothing useful in order to present as concentrated and
7+
concise API usage as possible.
8+
9+
The program is deliberately written in C to demonstrate the naked API usage.
10+
For C++ example see a much more advanced integration library at
11+
https://github.com/codership/wsrep-lib
12+
13+
## High level architecture
14+
15+
Process-wise the program consists of an endless main loop that periodically
16+
samples and prints performance stats and a configurable number of "master" and
17+
"slave" threads, with master threads loop processing "transactions" and
18+
replicating resulting "write sets" and slave threads receiving and processing
19+
the write sets from other nodes.
20+
21+
Object-wise the program is composed of two main objects: `store` and `wsrep`.
22+
'store' object contains application "state" and generates and commits changes
23+
to the state. `wsrep` object contains cluster context and provides interface
24+
to it. Changes generated by `store` are replicated and certified through
25+
`wsrep` and then committed to `store`.
26+
27+
## Unit descriptions (in alphabetical order)
28+
29+
#### ctx.h
30+
A small header to declare the application context structure.
31+
32+
#### log.*
33+
Implements logging functionality for the application AND
34+
**a logging callback** for the wsrep provider.
35+
36+
#### main.c
37+
Defines `main()` routine that initializes storage and wsrep provider, starts
38+
the worker threads and loops in a statistics collection loop. Even though it is
39+
not designed to return it still shows the deinitialization order.
40+
41+
#### options.*
42+
Implements reading configuration options from the command line, does not have
43+
anything related to wsrep API, but shows which additional parameters must be
44+
configured for the program to make use of wsrep clustering.
45+
46+
#### sst.*
47+
Defines **SST callbacks** for the wsrep provider and shows how to asynchronously
48+
implement state snapshot transfer (yes, you don't want to spend eternity in
49+
callbacks).
50+
51+
#### stats.*
52+
Implements performance stats collecting function for the main loop. While it is
53+
an absolutely optional provider functionality, still it shows how to use that.
54+
55+
#### store.*
56+
Defines the `store` object that pretends to store and modify some data in a
57+
"transactional" manner. It provides the caller that intends to do a change with
58+
a *change data* and a *key* for replication and certification.
59+
60+
#### trx.*
61+
Defines routines to process local and replicated transactions.
62+
63+
#### worker.*
64+
Implements worker thread pool functinality. Worker threads run routines defined
65+
in 'trx.*'. Also implements **apply callback** for the wsrep provider.
66+
67+
#### wsrep.*
68+
Maintains wsrep cluster context: provider instance and cluster membership view.
69+
While there is little use for the latter in this primitive application, still
70+
it shows **connected and view callbacks** usage. But mostly, for this
71+
application its purpose is to initialize the provider, connect to the cluster
72+
and offer access to initialized provider for other parts of the program.
73+
74+
## Example usage
75+
```
76+
./node -f /tmp/galera/0 -v /tmp/galera/0/galera/lib/libgalera_smm.so -o 'pc.weight=2;evs.send_window=2;evs.user_send_window=1;gcache.recover=no' -s 8 -m 16
77+
```

examples/node/ctx.h

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/* Copyright (c) 2019, Codership Oy. All rights reserved.
2+
*
3+
* This program is free software; you can redistribute it and/or modify
4+
* it under the terms of the GNU General Public License as published by
5+
* the Free Software Foundation; version 2 of the License.
6+
*
7+
* This program is distributed in the hope that it will be useful,
8+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
* GNU General Public License for more details.
11+
*
12+
* You should have received a copy of the GNU General Public License
13+
* along with this program; if not, write to the Free Software
14+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15+
*/
16+
17+
/**
18+
* @file This unit defines application context for wsrep provider
19+
*/
20+
21+
#ifndef NODE_CTX_H
22+
#define NODE_CTX_H
23+
24+
#include "store.h"
25+
#include "wsrep.h"
26+
27+
struct node_ctx
28+
{
29+
struct node_wsrep* wsrep;
30+
struct node_store* store;
31+
const struct node_options* opts;
32+
};
33+
34+
#endif /* NODE_CTX_H */

examples/node/log.c

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/* Copyright (c) 2019, Codership Oy. All rights reserved.
2+
*
3+
* This program is free software; you can redistribute it and/or modify
4+
* it under the terms of the GNU General Public License as published by
5+
* the Free Software Foundation; version 2 of the License.
6+
*
7+
* This program is distributed in the hope that it will be useful,
8+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
* GNU General Public License for more details.
11+
*
12+
* You should have received a copy of the GNU General Public License
13+
* along with this program; if not, write to the Free Software
14+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15+
*/
16+
17+
#include "log.h"
18+
19+
#include <stdio.h> // fprintf(), fflush()
20+
#include <sys/time.h> // gettimeofday()
21+
#include <time.h> // localtime_r()
22+
#include <stdarg.h> // va_start(), va_end()
23+
24+
wsrep_log_level_t node_log_max_level = WSREP_LOG_INFO;
25+
26+
static const char* log_level_str[WSREP_LOG_DEBUG + 2] =
27+
{
28+
"FATAL: ",
29+
"ERROR: ",
30+
" WARN: ",
31+
" INFO: ",
32+
"DEBUG: ",
33+
"XXXXX: "
34+
};
35+
36+
static inline void
37+
log_timestamp_and_log(const char* const prefix, // source of msg
38+
int const severity,
39+
const char* const msg)
40+
{
41+
struct tm date;
42+
struct timeval time;
43+
44+
gettimeofday(&time, NULL);
45+
localtime_r (&time.tv_sec, &date);
46+
47+
FILE* log_file = stderr;
48+
fprintf(log_file,
49+
"%04d-%02d-%02d %02d:%02d:%02d.%03d " /* timestamp fmt */
50+
"[%s] %s%s\n", /* [prefix] severity msg */
51+
date.tm_year + 1900, date.tm_mon + 1, date.tm_mday,
52+
date.tm_hour, date.tm_min, date.tm_sec,
53+
(int)time.tv_usec / 1000,
54+
prefix, log_level_str[severity], msg
55+
);
56+
57+
fflush (log_file);
58+
}
59+
60+
void
61+
node_log_cb(wsrep_log_level_t const severity, const char* const msg)
62+
{
63+
/* REPLICATION: let provider log messages be prefixed with 'wsrep'*/
64+
log_timestamp_and_log("wsrep", severity, msg);
65+
}
66+
67+
void
68+
node_log(wsrep_log_level_t const severity,
69+
const char* const file,
70+
const char* const function,
71+
int const line,
72+
...)
73+
{
74+
va_list ap;
75+
76+
char string[2048];
77+
int max_string = sizeof(string);
78+
char* str = string;
79+
80+
/* provide file:func():line info only if debug logging is on */
81+
if (NODE_DO_LOG_DEBUG) {
82+
int const len = snprintf(str, (size_t)max_string, "%s:%s():%d: ",
83+
file, function, line);
84+
str += len;
85+
max_string -= len;
86+
}
87+
88+
va_start(ap, line);
89+
{
90+
const char* format = va_arg (ap, const char*);
91+
92+
if (max_string > 0 && NULL != format) {
93+
vsnprintf (str, (size_t)max_string, format, ap);
94+
}
95+
}
96+
va_end(ap);
97+
98+
/* actual logging */
99+
log_timestamp_and_log(" node", severity, string);
100+
}

examples/node/log.h

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/* Copyright (c) 2019, Codership Oy. All rights reserved.
2+
*
3+
* This program is free software; you can redistribute it and/or modify
4+
* it under the terms of the GNU General Public License as published by
5+
* the Free Software Foundation; version 2 of the License.
6+
*
7+
* This program is distributed in the hope that it will be useful,
8+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
* GNU General Public License for more details.
11+
*
12+
* You should have received a copy of the GNU General Public License
13+
* along with this program; if not, write to the Free Software
14+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15+
*/
16+
17+
/**
18+
* @file This unit defines logging macros for the application and
19+
* a logger callback for the wsrep provider.
20+
*/
21+
22+
#ifndef NODE_LOG_H
23+
#define NODE_LOG_H
24+
25+
#include "../../wsrep_api.h"
26+
27+
/**
28+
* REPLICATION: a logger callback for wsrep provider
29+
*/
30+
extern void
31+
node_log_cb(wsrep_log_level_t severity, const char* message);
32+
33+
/**
34+
* Applicaton log function intended to be used through the macros defined below.
35+
* For simplicity it uses log levels defined by wsrep API, but it does not have
36+
* to. */
37+
extern void
38+
node_log (wsrep_log_level_t level,
39+
const char* file,
40+
const char* function,
41+
const int line,
42+
...);
43+
44+
/**
45+
* This variable made global to avoid calling node_log() when debug logging
46+
* is disabled. */
47+
extern wsrep_log_level_t node_log_max_level;
48+
#define NODE_DO_LOG_DEBUG (WSREP_LOG_DEBUG <= node_log_max_level)
49+
50+
/**
51+
* Base logging macro that records current file, function and line number */
52+
#define NODE_LOG(level, ...)\
53+
node_log(level, __FILE__, __func__, __LINE__, __VA_ARGS__, NULL)
54+
55+
/**
56+
* @name Logging macros.
57+
* Must be implemented as macros to report the location of the code where
58+
* they are called.
59+
*/
60+
/*@{*/
61+
#define NODE_FATAL(...) NODE_LOG(WSREP_LOG_FATAL, __VA_ARGS__, NULL)
62+
#define NODE_ERROR(...) NODE_LOG(WSREP_LOG_ERROR, __VA_ARGS__, NULL)
63+
#define NODE_WARN(...) NODE_LOG(WSREP_LOG_WARN, __VA_ARGS__, NULL)
64+
#define NODE_INFO(...) NODE_LOG(WSREP_LOG_INFO, __VA_ARGS__, NULL)
65+
#define NODE_DEBUG(...) if (NODE_DO_LOG_DEBUG) \
66+
{ NODE_LOG(WSREP_LOG_DEBUG, __VA_ARGS__, NULL); }
67+
/*@}*/
68+
69+
#endif /* NODE_LOG_H */

0 commit comments

Comments
 (0)