feat(lander): integrate persistent insert & get lsm store
parent
226873219b
commit
535b92a6b6
|
@ -6,3 +6,4 @@ lander.data*
|
|||
pastes/
|
||||
.cache/
|
||||
vgcore.*
|
||||
data/
|
||||
|
|
|
@ -49,4 +49,8 @@ bool lander_stream_body_to_client(event_loop_conn *conn);
|
|||
|
||||
bool lander_get_entry_lsm(event_loop_conn *conn);
|
||||
|
||||
bool lander_post_redirect_body_to_attr(event_loop_conn *conn);
|
||||
|
||||
bool lander_entry_sync(event_loop_conn *conn);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
*/
|
||||
typedef enum lsm_attr_type : uint64_t {
|
||||
lsm_attr_type_entry_type = 1 << 0,
|
||||
lsm_attr_type_content_type = 1 << 1
|
||||
lsm_attr_type_content_type = 1 << 1,
|
||||
lsm_attr_type_url = 1 << 2,
|
||||
} lsm_attr_type;
|
||||
|
||||
/**
|
||||
|
|
|
@ -100,6 +100,9 @@ lsm_error lsm_entry_sync(lsm_store *store, lsm_entry_handle *handle) {
|
|||
res = lsm_entry_write_uint64_t(store->idx_file, new_block_count);
|
||||
|
||||
if (res == lsm_error_ok) {
|
||||
// Only if we successfully updated the on-disk counter do we make the code
|
||||
// aware that the file's size has increased. This way, if a write to the
|
||||
// counter fails, the code will simply reuse the already written content.
|
||||
store->idx_file_size += entry_size;
|
||||
store->idx_file_block_count = new_block_count;
|
||||
}
|
||||
|
|
|
@ -23,8 +23,9 @@ http_route lander_routes[] = {
|
|||
.type = http_route_regex,
|
||||
.method = http_post,
|
||||
.path = "^/s(l?)/([^/]*)$",
|
||||
.steps = {http_loop_step_auth, http_loop_step_parse_content_length,
|
||||
lander_post_redirect_lsm, lander_stream_body_to_entry, NULL},
|
||||
.steps = {http_loop_step_auth, lander_post_redirect_lsm,
|
||||
http_loop_step_body_to_buf, lander_post_redirect_body_to_attr,
|
||||
lander_entry_sync, NULL},
|
||||
.steps_res = {http_loop_step_write_header, http_loop_step_write_body,
|
||||
NULL},
|
||||
},
|
||||
|
@ -32,7 +33,8 @@ http_route lander_routes[] = {
|
|||
.method = http_post,
|
||||
.path = "^/p(l?)/([^/]*)$",
|
||||
.steps = {http_loop_step_auth, http_loop_step_parse_content_length,
|
||||
lander_post_paste_lsm, lander_stream_body_to_entry, NULL},
|
||||
lander_post_paste_lsm, lander_stream_body_to_entry,
|
||||
lander_entry_sync, NULL},
|
||||
.steps_res = {http_loop_step_write_header, http_loop_step_write_body,
|
||||
NULL}},
|
||||
};
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "event_loop.h"
|
||||
#include "http/types.h"
|
||||
#include "lander.h"
|
||||
#include "log.h"
|
||||
#include "lsm/store.h"
|
||||
|
||||
static const char index_page[] =
|
||||
|
@ -82,19 +83,25 @@ bool lander_get_entry_lsm(event_loop_conn *conn) {
|
|||
lsm_attr_type_entry_type);
|
||||
|
||||
if (t == lander_entry_type_redirect) {
|
||||
// Stream entire redirect data into buffer to set as header
|
||||
uint64_t data_len = lsm_entry_data_len(c_ctx->entry);
|
||||
char *buf = malloc(data_len + 1);
|
||||
uint64_t read = 0;
|
||||
uint64_t total_read = 0;
|
||||
// For redirects, the URL is stored as an in-memory attribute
|
||||
lsm_str *url_attr_val;
|
||||
|
||||
while (total_read < data_len) {
|
||||
lsm_entry_data_read(&read, &buf[total_read], c_ctx->entry,
|
||||
data_len - total_read);
|
||||
total_read += read;
|
||||
// This shouldn't be able to happen
|
||||
if (lsm_entry_attr_get(&url_attr_val, c_ctx->entry, lsm_attr_type_url) !=
|
||||
lsm_error_ok) {
|
||||
error("Entry of type redirect detected without URL attribute");
|
||||
|
||||
ctx->res.status = http_internal_server_error;
|
||||
lsm_entry_close(c_ctx->entry);
|
||||
c_ctx->entry = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
buf[data_len] = '\0';
|
||||
char *buf = malloc(lsm_str_len(url_attr_val) + 1);
|
||||
memcpy(buf, lsm_str_ptr(url_attr_val), lsm_str_len(url_attr_val));
|
||||
|
||||
buf[lsm_str_len(url_attr_val)] = '\0';
|
||||
|
||||
ctx->res.status = http_moved_permanently;
|
||||
http_res_add_header(&ctx->res, http_header_location, buf, true);
|
||||
|
|
|
@ -138,6 +138,30 @@ bool lander_post_redirect_lsm(event_loop_conn *conn) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool lander_post_redirect_body_to_attr(event_loop_conn *conn) {
|
||||
http_loop_ctx *ctx = conn->ctx;
|
||||
lander_ctx *c_ctx = ctx->c;
|
||||
|
||||
lsm_str *attr_value;
|
||||
lsm_str_init_copy_n(&attr_value, ctx->req.body.buf, ctx->req.body.len);
|
||||
lsm_entry_attr_insert(c_ctx->entry, lsm_attr_type_url, attr_value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lander_entry_sync(event_loop_conn *conn) {
|
||||
http_loop_ctx *ctx = conn->ctx;
|
||||
http_loop_gctx *gctx = ctx->g;
|
||||
lander_gctx *c_gctx = gctx->c;
|
||||
lander_ctx *c_ctx = ctx->c;
|
||||
|
||||
if (lsm_entry_sync(c_gctx->store, c_ctx->entry) != lsm_error_ok) {
|
||||
ctx->res.status = http_internal_server_error;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lander_post_paste_lsm(event_loop_conn *conn) {
|
||||
http_loop_ctx *ctx = conn->ctx;
|
||||
lander_ctx *c_ctx = ctx->c;
|
||||
|
|
12
src/main.c
12
src/main.c
|
@ -23,7 +23,7 @@ int main() {
|
|||
|
||||
ENV(api_key, "LANDER_API_KEY");
|
||||
ENV_OPT(port_str, "LANDER_PORT", "18080");
|
||||
ENV_OPT(data_dir, "LANDER_DATA_DIR", ".");
|
||||
ENV_OPT(data_dir_s, "LANDER_DATA_DIR", ".");
|
||||
|
||||
int port = atoi(port_str);
|
||||
|
||||
|
@ -46,12 +46,14 @@ int main() {
|
|||
/* info("Trie initialized and populated with %i entries", trie_size(trie)); */
|
||||
|
||||
lander_gctx *c_gctx = lander_gctx_init();
|
||||
c_gctx->data_dir = data_dir;
|
||||
c_gctx->data_dir = data_dir_s;
|
||||
/* c_gctx->trie = trie; */
|
||||
|
||||
lsm_str *data_dir2;
|
||||
lsm_str_init_copy(&data_dir2, "data");
|
||||
lsm_store_load(&c_gctx->store, data_dir2);
|
||||
lsm_str *data_dir;
|
||||
lsm_str_init_copy(&data_dir, (char *)data_dir_s);
|
||||
if (lsm_store_load(&c_gctx->store, data_dir) != lsm_error_ok) {
|
||||
critical(2, "Failed to load existing store.");
|
||||
}
|
||||
|
||||
http_loop *hl = http_loop_init(
|
||||
lander_routes, sizeof(lander_routes) / sizeof(lander_routes[0]), c_gctx,
|
||||
|
|
Loading…
Reference in New Issue