first part of uwsgi_legion_scrolls() function api

This commit is contained in:
Unbit
2013-03-18 13:22:10 +01:00
parent c5412e1620
commit 35f47371ed
3 changed files with 92 additions and 0 deletions
+53
View File
@@ -81,6 +81,37 @@ void uwsgi_parse_legion(char *key, uint16_t keylen, char *value, uint16_t vallen
}
}
// this function is called when a node is added or removed (heavy locking is needed)
static void legion_rebuild_scrolls(struct uwsgi_legion *ul) {
uint64_t max_size = ul->scrolls_max_size;
// first, try to add myself
if (ul->scroll_len + (uint64_t) 2 > max_size) {
uwsgi_log("[DANGER] you have configured a too much tiny buffer for the scrolls list !!! tune it with --legion-scroll-list-max-size\n");
ul->scroll_len = 0;
return;
}
char *ptr = ul->scrolls;
*ptr ++= (uint8_t) (ul->scroll_len & 0xff);
*ptr ++= (uint8_t) ((ul->scroll_len >> 8) &0xff);
memcpy(ptr, ul->scroll, ul->scroll_len); ptr += ul->scroll_len;
ul->scrolls_len = 2 + ul->scroll_len;
// ok start adding nodes;
struct uwsgi_legion_node *uln = ul->nodes_head;
while(uln) {
if (ul->scrolls_len + 2 + uln->scroll_len > max_size) {
uwsgi_log("[DANGER] you have configured a too much tiny buffer for the scrolls list !!! tune it with --legion-scroll-list-max-size\n");
return;
}
*ptr ++= (uint8_t) (uln->scroll_len & 0xff);
*ptr ++= (uint8_t) ((uln->scroll_len >> 8) &0xff);
memcpy(ptr, uln->scroll, uln->scroll_len); ptr += uln->scroll_len;
ul->scrolls_len += 2 + uln->scroll_len;
uln = uln->next;
}
}
// critical section (remember to lock when you use it)
struct uwsgi_legion_node *uwsgi_legion_add_node(struct uwsgi_legion *ul, uint16_t valor, char *name, uint16_t name_len, char *uuid) {
@@ -104,6 +135,8 @@ struct uwsgi_legion_node *uwsgi_legion_add_node(struct uwsgi_legion *ul, uint16_
ul->nodes_head = node;
}
legion_rebuild_scrolls(ul);
return node;
@@ -141,6 +174,8 @@ void uwsgi_legion_remove_node(struct uwsgi_legion *ul, struct uwsgi_legion_node
}
free(node);
legion_rebuild_scrolls(ul);
}
struct uwsgi_legion_node *uwsgi_legion_get_node(struct uwsgi_legion *ul, uint64_t valor, char *name, uint16_t name_len, char *uuid) {
@@ -937,8 +972,14 @@ void uwsgi_opt_legion(char *opt, char *value, void *foobar) {
uwsgi.legion_scroll_max_size = 4096;
}
if (!uwsgi.legion_scroll_list_max_size) {
uwsgi.legion_scroll_list_max_size = 32768;
}
ul->lord_scroll_size = uwsgi.legion_scroll_max_size;
ul->lord_scroll = uwsgi_calloc_shared(ul->lord_scroll_size);
ul->scrolls_max_size = uwsgi.legion_scroll_list_max_size;
ul->scrolls = uwsgi_calloc_shared(ul->scrolls_max_size);
uwsgi_legion_add(ul);
}
@@ -1020,3 +1061,15 @@ char *uwsgi_legion_lord_scroll(char *name, uint16_t *rlen) {
uwsgi_rwunlock(legion->lock);
return buf;
}
char *uwsgi_legion_scrolls(char *name, uint64_t *rlen) {
char *buf = NULL;
struct uwsgi_legion *legion = uwsgi_legion_get_by_name(name);
if (!legion) return NULL;
uwsgi_rlock(legion->lock);
buf = uwsgi_malloc(legion->scrolls_len);
memcpy(buf, legion->scrolls, legion->scrolls_len);
*rlen = legion->scrolls_len;
uwsgi_rwunlock(legion->lock);
return buf;
}
+32
View File
@@ -474,6 +474,37 @@ PyObject *py_uwsgi_lord_scroll(PyObject * self, PyObject * args) {
return ret;
}
static void scrolls_items(uint16_t pos, char *key, uint16_t keylen, void *data) {
PyObject *list = (PyObject *) data;
PyObject *zero = PyString_FromStringAndSize(key, keylen);
PyList_Append(list, zero);
Py_DECREF(zero);
}
PyObject *py_uwsgi_scrolls(PyObject * self, PyObject * args) {
char *legion_name = NULL;
if (!PyArg_ParseTuple(args, "s:scrolls", &legion_name)) {
return NULL;
}
uint64_t rlen = 0;
char *buf = uwsgi_legion_scrolls(legion_name, &rlen);
if (!buf) goto end;
PyObject *list = PyList_New(0);
if (uwsgi_hooked_parse_array(buf, rlen, scrolls_items, list)) {
goto error;
}
free(buf);
return list;
error:
free(buf);
end:
Py_INCREF(Py_None);
return Py_None;
}
#endif
PyObject *py_uwsgi_register_signal(PyObject * self, PyObject * args) {
@@ -2434,6 +2465,7 @@ static PyMethodDef uwsgi_advanced_methods[] = {
#ifdef UWSGI_SSL
{"i_am_the_lord", py_uwsgi_i_am_the_lord, METH_VARARGS, ""},
{"lord_scroll", py_uwsgi_lord_scroll, METH_VARARGS, ""},
{"scrolls", py_uwsgi_scrolls, METH_VARARGS, ""},
#endif
{"async_sleep", py_uwsgi_async_sleep, METH_VARARGS, ""},
{"async_connect", py_uwsgi_async_connect, METH_VARARGS, ""},
+7
View File
@@ -624,6 +624,10 @@ union uwsgi_sockaddr_ptr {
EVP_CIPHER_CTX *encrypt_ctx;
EVP_CIPHER_CTX *decrypt_ctx;
char *scrolls;
uint64_t scrolls_len;
uint64_t scrolls_max_size;
// found nodes dynamic lists
struct uwsgi_legion_node *nodes_head;
struct uwsgi_legion_node *nodes_tail;
@@ -2239,6 +2243,7 @@ struct uwsgi_server {
int legion_tolerance;
int legion_skew_tolerance;
uint16_t legion_scroll_max_size;
uint64_t legion_scroll_list_max_size;
#endif
#ifdef __linux__
@@ -3921,6 +3926,8 @@ int uwsgi_cache_magic_exists(char *, uint16_t, char *);
int uwsgi_cache_magic_clear(char *);
void uwsgi_cache_magic_context_hook(char *, uint16_t, char *, uint16_t, void *);
char *uwsgi_legion_scrolls(char *, uint64_t *);
#ifdef UWSGI_ZLIB
#include <zlib.h>
int uwsgi_deflate_init(z_stream *, char *, size_t);