Commit 8d9fe9e3 authored by Marek Vavruša's avatar Marek Vavruša

daemon/engine: extensible registry of cache backends

the engine keeps an array of storage backends available
for caching, it is possible to switch the backend on
runtime with standard ‘proto://config' string

the default backend is ‘lmdb://<path>’
parent b1053f49
......@@ -304,6 +304,26 @@ static int cache_count(lua_State *L)
return 1;
}
static struct storage_api *cache_select_storage(struct engine *engine, const char **conf)
{
/* Return default backend */
storage_registry_t *registry = &engine->storage_registry;
if (!*conf || !strstr(*conf, "://")) {
return &registry->at[0];
}
/* Find storage backend from config prefix */
for (unsigned i = 0; i < registry->len; ++i) {
struct storage_api *storage = &registry->at[i];
if (strncmp(*conf, storage->prefix, strlen(storage->prefix)) == 0) {
*conf += strlen(storage->prefix);
return storage;
}
}
return NULL;
}
/** Open cache */
static int cache_open(lua_State *L)
{
......@@ -314,16 +334,26 @@ static int cache_open(lua_State *L)
lua_error(L);
}
/* Close if already open */
/* Select cache storage backend */
struct engine *engine = engine_luaget(L);
const char *conf = n > 1 ? lua_tostring(L, 2) : NULL;
struct storage_api *storage = cache_select_storage(engine, &conf);
if (!storage) {
format_error(L, "unsupported cache backend");
lua_error(L);
}
kr_cache_storage_set(storage->api);
/* Close if already open */
if (engine->resolver.cache != NULL) {
kr_cache_close(engine->resolver.cache);
}
/* Open resolution context cache */
engine->resolver.cache = kr_cache_open(".", engine->pool, lua_tointeger(L, 1));
/* Reopen cache */
void *storage_opts = storage->opts_create(conf, lua_tointeger(L, 1));
engine->resolver.cache = kr_cache_open(storage_opts, engine->pool);
free(storage_opts);
if (engine->resolver.cache == NULL) {
format_error(L, "can't open cache in rundir");
format_error(L, "can't open cache");
lua_error(L);
}
......
......@@ -17,6 +17,8 @@
#include <uv.h>
#include <unistd.h>
#include <libknot/internal/mempattern.h>
/* #include <libknot/internal/namedb/namedb_trie.h> @todo Not supported (doesn't keep value copy) */
#include <libknot/internal/namedb/namedb_lmdb.h>
#include "daemon/engine.h"
#include "daemon/bindings.h"
......@@ -97,6 +99,18 @@ static int l_trampoline(lua_State *L)
* Engine API.
*/
/** @internal Make lmdb options. */
void *namedb_lmdb_mkopts(const char *conf, size_t maxsize)
{
struct namedb_lmdb_opts *opts = malloc(sizeof(*opts));
if (opts) {
memset(opts, 0, sizeof(*opts));
opts->path = conf ? conf : ".";
opts->mapsize = maxsize;
}
return opts;
}
static int init_resolver(struct engine *engine)
{
/* Open resolution context */
......@@ -106,7 +120,12 @@ static int init_resolver(struct engine *engine)
engine_register(engine, "iterate");
engine_register(engine, "itercache");
return kr_ok();
/* Initialize storage backends */
struct storage_api lmdb = {
"lmdb://", namedb_lmdb_api, namedb_lmdb_mkopts
};
return array_push(engine->storage_registry, lmdb);
}
static int init_state(struct engine *engine)
......@@ -168,6 +187,7 @@ void engine_deinit(struct engine *engine)
kr_module_unload(&engine->modules.at[i]);
}
array_clear(engine->modules);
array_clear(engine->storage_registry);
if (engine->L) {
lua_close(engine->L);
......
......@@ -24,10 +24,21 @@ struct lua_State;
#include "lib/resolve.h"
#include "daemon/network.h"
/** Cache storage backend. */
struct storage_api {
const char *prefix; /**< Storage prefix, e.g. 'lmdb://' */
const namedb_api_t *(*api)(void); /**< Storage API implementation */
void *(*opts_create)(const char *, size_t); /**< Storage options factory */
};
/** @internal Array of cache backend options. */
typedef array_t(struct storage_api) storage_registry_t;
struct engine {
struct kr_context resolver;
struct network net;
module_array_t modules;
storage_registry_t storage_registry;
mm_ctx_t *pool;
struct lua_State *L;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment