Skip to content

Commit 795b967

Browse files
authored
Auto rebuild (#435)
* Auto rebuild * Upd changelog
1 parent 8a6c6f0 commit 795b967

11 files changed

Lines changed: 116 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# v1.8.4-alpha0
2+
3+
* Added `--auto-rebuild` flag, pr #435.
4+
15
# v1.8.3
26

37
* Added the `America/Coyhaique` time zone, pr #432.

inc/ti/args.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ struct ti_args_s
2020
int32_t init;
2121
int32_t log_colorized;
2222
int32_t rebuild;
23+
int32_t auto_rebuild;
2324
int32_t forget_nodes;
2425
int32_t yes;
2526
int32_t version;

inc/ti/version.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
#define TI_VERSION_MAJOR 1
88
#define TI_VERSION_MINOR 8
9-
#define TI_VERSION_PATCH 3
9+
#define TI_VERSION_PATCH 4
1010

1111
/* The syntax version is used to test compatibility with functions
1212
* using the `ti_nodes_check_syntax()` function */
@@ -25,7 +25,7 @@
2525
* "-rc0"
2626
* ""
2727
*/
28-
#define TI_VERSION_PRE_RELEASE ""
28+
#define TI_VERSION_PRE_RELEASE "-alpha0"
2929

3030
#define TI_MAINTAINER \
3131
"Jeroen van der Heijden <jeroen@cesbit.com>"

itest/lib/node.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ async def wait_join(self, secret: str, timeout: int = 5):
9898
await self.expect(
9999
'start listening for node connections', timeout=timeout)
100100

101-
async def run(self, timeout: int = 5):
102-
self.start()
101+
async def run(self, timeout: int = 5, auto_rebuild: bool = False):
102+
self.start(auto_rebuild=auto_rebuild)
103103
await self.expect(
104104
'start listening for node connections', timeout=timeout)
105105

@@ -245,7 +245,7 @@ def version(self):
245245
self.n == THINGSDB_NODE_OUTPUT):
246246
print(Color.node(self.n, m.group(1)))
247247

248-
def start(self, init=None, secret=None):
248+
def start(self, init=None, secret=None, auto_rebuild=False):
249249
self.queue = asyncio.Queue()
250250

251251
command = THINGSDB_MEMCHECK + [
@@ -260,6 +260,9 @@ def start(self, init=None, secret=None):
260260
elif secret:
261261
command.extend(['--secret', secret])
262262

263+
if auto_rebuild:
264+
command.append('--auto-rebuild')
265+
263266
r, w = os.pipe()
264267
w = os.fdopen(w, 'w')
265268

itest/run_all_tests.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from test_nodes import TestNodes
2727
from test_operators import TestOperators
2828
from test_procedures import TestProcedures
29+
from test_recovery import TestRecovery
2930
from test_relations import TestRelations
3031
from test_restriction import TestRestriction
3132
from test_room import TestRoom
@@ -101,6 +102,7 @@ def no_mem_test(test_class):
101102
run_test(TestNodes(), hide_version=hide_version())
102103
run_test(TestOperators(), hide_version=hide_version())
103104
run_test(TestProcedures(), hide_version=hide_version())
105+
run_test(TestRecovery(), hide_version=hide_version())
104106
run_test(TestRelations(), hide_version=hide_version())
105107
run_test(TestRestriction(), hide_version=hide_version())
106108
run_test(TestRoom(), hide_version=hide_version())

itest/test_recovery.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#!/usr/bin/env python
2+
import asyncio
3+
import os
4+
from lib import run_test
5+
from lib import default_test_setup
6+
from lib.testbase import TestBase
7+
from lib.client import get_client
8+
from thingsdb.exceptions import OperationError
9+
10+
11+
script_dir = os.path.dirname(__file__)
12+
13+
14+
class TestRecovery(TestBase):
15+
16+
title = 'Test auto recovery'
17+
18+
@default_test_setup(num_nodes=3, seed=2)
19+
async def async_run(self):
20+
await self.node0.init_and_run()
21+
22+
cl0 = await get_client(self.node0)
23+
cl0.set_default_scope('//stuff')
24+
25+
await self.node1.join_until_ready(cl0)
26+
await self.node2.join_until_ready(cl0)
27+
28+
cl1 = await get_client(self.node1)
29+
cl2 = await get_client(self.node2)
30+
31+
for i, c in enumerate('abcdefghijklmnop'):
32+
await cl0.query("""//ti
33+
.set(c, i);
34+
""", i=i, c=c)
35+
36+
await asyncio.sleep(1.0)
37+
38+
await self.node0.shutdown()
39+
fn = os.path.join(script_dir,
40+
'testdir',
41+
'tdb0',
42+
'store',
43+
'00000000002',
44+
'gcprops.mp')
45+
with open(fn, 'wb') as fp:
46+
fp.write(b'<<>>') # force corruption
47+
48+
await self.node0.run(auto_rebuild=True)
49+
50+
cl0 = await get_client(self.node0)
51+
52+
for cl in (cl0, cl1, cl2):
53+
res = await cl.query('.d;', scope='//stuff')
54+
self.assertEqual(res, 3)
55+
56+
await cl0.close_and_wait()
57+
await cl1.close_and_wait()
58+
await cl2.close_and_wait()
59+
60+
61+
if __name__ == '__main__':
62+
run_test(TestRecovery())

main.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,26 @@ int main(int argc, char * argv[])
254254
}
255255
else if ((rc = ti_store_restore()))
256256
{
257-
printf("error loading ThingsDB\n");
258-
goto stop;
257+
if (ti.args->auto_rebuild && ti.nodes->vec->n >= 2)
258+
{
259+
printf(
260+
"*********************************\n"
261+
" Failed to load ThingsDB\n"
262+
" Starting Auto Rebuild ...\n"
263+
"*********************************\n");
264+
if ((rc = ti_rebuild()))
265+
{
266+
printf("error initiating auto rebuild\n");
267+
goto stop;
268+
}
269+
}
270+
else
271+
{
272+
printf(
273+
"error loading ThingsDB; "
274+
"you might want to try --rebuild or --auto-rebuild\n");
275+
goto stop;
276+
}
259277
}
260278
}
261279
else

src/ti/archive.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/*
22
* ti/archive.c
33
*/
4+
#define _GNU_SOURCE
5+
#include <dirent.h>
46
#include <assert.h>
57
#include <ctype.h>
68
#include <stdlib.h>

src/ti/args.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ int ti_args_create(void)
2929
args->init = 0;
3030
args->log_colorized = 0;
3131
args->rebuild = 0;
32+
args->auto_rebuild = 0;
3233
args->forget_nodes = 0;
3334
args->version = 0;
3435

@@ -128,6 +129,18 @@ int ti_args_parse(int argc, char *argv[])
128129
.choices = NULL,
129130
};
130131

132+
argparse_argument_t auto_rebuild_ = {
133+
.name = "auto-rebuild",
134+
.shortcut = 0,
135+
.help = "auto rebuild this node on failed (can only be used when having >1 nodes)",
136+
.action = ARGPARSE_STORE_TRUE,
137+
.default_int32_t = 0,
138+
.pt_value_int32_t = &args->auto_rebuild,
139+
.str_default = NULL,
140+
.str_value = NULL,
141+
.choices = NULL,
142+
};
143+
131144
argparse_argument_t forget_nodes_ = {
132145
.name = "forget-nodes",
133146
.shortcut = 0,
@@ -194,6 +207,7 @@ int ti_args_parse(int argc, char *argv[])
194207
argparse_add_argument(parser, &force_) ||
195208
argparse_add_argument(parser, &secret_) ||
196209
argparse_add_argument(parser, &rebuild_) ||
210+
argparse_add_argument(parser, &auto_rebuild_) ||
197211
argparse_add_argument(parser, &forget_nodes_) ||
198212
argparse_add_argument(parser, &yes_) ||
199213
argparse_add_argument(parser, &version_) ||
@@ -283,7 +297,6 @@ int ti_args_parse(int argc, char *argv[])
283297
rc = -1;
284298
}
285299
}
286-
287300
}
288301

289302
if (parser->show_help)

src/ti/evars.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ void ti_evars_arg_parse(void)
9393
evars__bool_arg(
9494
"THINGSDB_DEPLOY",
9595
&ti.args->deploy);
96+
evars__bool_arg(
97+
"THINGSDB_AUTO_REBUILD",
98+
&ti.args->auto_rebuild);
9699
evars__str_arg(
97100
"THINGSDB_SECRET",
98101
ti.args->secret);

0 commit comments

Comments
 (0)