Skip to content

Commit 83858b4

Browse files
committed
Introduce namespace reload on runtime (related to #38)
Introduce new 'RELOAD <namespace>' admin command. This command clean the namespace and reload it from disk, like a fresh boot. During the reload time, the daemon won't take any new commands.
1 parent afb95eb commit 83858b4

5 files changed

+69
-5
lines changed

src/commands.c

+1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ static command_t commands_handlers[] = {
9090
{.command = "NSSET", .handler = command_nsset}, // custom command to edit namespace settings
9191
{.command = "NSINFO", .handler = command_nsinfo}, // custom command to get namespace information
9292
{.command = "SELECT", .handler = command_select}, // default SELECT (with pwd) namespace switch
93+
{.command = "RELOAD", .handler = command_reload}, // custom command to reload a namespace
9394
};
9495

9596
int redis_dispatcher(redis_client_t *client) {

src/commands_namespace.c

+35
Original file line numberDiff line numberDiff line change
@@ -362,3 +362,38 @@ int command_dbsize(redis_client_t *client) {
362362
return 0;
363363
}
364364

365+
int command_reload(redis_client_t *client) {
366+
char target[COMMAND_MAXLEN];
367+
namespace_t *namespace = NULL;
368+
resp_request_t *request = client->request;
369+
370+
// command restricted to admin only
371+
if(!command_admin_authorized(client))
372+
return 1;
373+
374+
if(!command_args_validate(client, 2))
375+
return 1;
376+
377+
if(request->argv[1]->length > 128) {
378+
redis_hardsend(client, "-Namespace too long");
379+
return 1;
380+
}
381+
382+
// get name as usable string
383+
sprintf(target, "%.*s", request->argv[1]->length, (char *) request->argv[1]->buffer);
384+
385+
// checking for existing namespace
386+
if(!(namespace = namespace_get(target))) {
387+
debug("[-] command: nsset: namespace not found\n");
388+
redis_hardsend(client, "-Namespace not found");
389+
return 1;
390+
}
391+
392+
// reload that namespace
393+
namespace_reload(client->ns);
394+
395+
redis_hardsend(client, "+OK");
396+
397+
return 0;
398+
}
399+

src/commands_namespace.h

+1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@
88
int command_nsinfo(redis_client_t *client);
99
int command_nsset(redis_client_t *client);
1010
int command_dbsize(redis_client_t *client);
11+
int command_reload(redis_client_t *client);
1112
#endif

src/namespace.c

+31-5
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,19 @@ namespace_t *namespace_ensure(namespace_t *namespace) {
190190
return namespace;
191191
}
192192

193+
// lazy load a namespace
194+
// this just populate data and index from disk
195+
// based on an existing namespace object
196+
// this can be used to load and reload a namespace
197+
static int namespace_load_lazy(ns_root_t *nsroot, namespace_t *namespace) {
198+
// now, we are sure the namespace exists, but it's maybe empty
199+
// let's call index and data initializer, they will take care about that
200+
namespace->index = index_init(nsroot->settings, namespace->indexpath, namespace, nsroot->branches);
201+
namespace->data = data_init(nsroot->settings, namespace->datapath, namespace->index->indexid);
202+
203+
return 0;
204+
}
205+
193206
// load (or create if it doesn't exists) a namespace
194207
static namespace_t *namespace_load(ns_root_t *nsroot, char *name) {
195208
namespace_t *namespace;
@@ -212,12 +225,9 @@ static namespace_t *namespace_load(ns_root_t *nsroot, char *name) {
212225
if(!namespace_ensure(namespace))
213226
return NULL;
214227

228+
// load data from disk
215229
namespace_descriptor_load(namespace);
216-
217-
// now, we are sure the namespace exists, but it's maybe empty
218-
// let's call index and data initializer, they will take care about that
219-
namespace->index = index_init(nsroot->settings, namespace->indexpath, namespace, nsroot->branches);
220-
namespace->data = data_init(nsroot->settings, namespace->datapath, namespace->index->indexid);
230+
namespace_load_lazy(nsroot, namespace);
221231

222232
return namespace;
223233
}
@@ -448,6 +458,22 @@ static void namespace_kick_slot(namespace_t *namespace) {
448458
}
449459
}
450460

461+
int namespace_reload(namespace_t *namespace) {
462+
debug("[+] namespace: reloading: %s\n", namespace->name);
463+
464+
debug("[+] namespace: reload: cleaning index\n");
465+
index_clean_namespace(namespace->index, namespace);
466+
467+
debug("[+] namespace: reload: destroying objects\n")
468+
index_destroy(namespace->index);
469+
data_destroy(namespace->data);
470+
471+
debug("[+] namespace: reload: reloading data\n");
472+
namespace_load_lazy(nsroot, namespace);
473+
474+
return 0;
475+
}
476+
451477
//
452478
// delete (clean and remove files) a namespace
453479
//

src/namespace.h

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
int namespace_create(char *name);
5858
int namespace_delete(namespace_t *namespace);
5959
namespace_t *namespace_get(char *name);
60+
int namespace_reload(namespace_t *namespace);
6061

6162
void namespace_commit(namespace_t *namespace);
6263

0 commit comments

Comments
 (0)