prepare dor async-friendly rpc

This commit is contained in:
Unbit
2013-02-07 17:23:59 +01:00
parent 7d84413038
commit 9f15345183
7 changed files with 64 additions and 152 deletions
+32 -134
View File
@@ -14,7 +14,7 @@ struct uwsgi_lua {
#define lca(L, n) ulua_check_args(L, __FUNCTION__, n)
struct uwsgi_option uwsgi_lua_options[] = {
static struct uwsgi_option uwsgi_lua_options[] = {
{"lua", required_argument, 0, "load lua wsapi app", uwsgi_opt_set_str, &ulua.filename, 0},
@@ -24,7 +24,7 @@ struct uwsgi_option uwsgi_lua_options[] = {
static void ulua_check_args(lua_State *L, const char *func, int n) {
int args = lua_gettop(L);
char error[4096];
char error[1024];
if (args != n) {
if (n == 1) {
snprintf(error, 4096, "uwsgi.%s takes 1 parameter", func+10);
@@ -82,53 +82,6 @@ static int uwsgi_api_register_rpc(lua_State *L) {
return 1;
}
static char *encode_lua_table(lua_State *L, int index, uint16_t *size) {
char *buf, *ptrbuf;
char *key;
char *value;
size_t keylen;
size_t vallen;
*size = 0;
lua_pushnil(L);
while (lua_next(L, index) != 0) {
if (lua_isstring(L, -2) && lua_isstring(L, -1)) {
key = (char *) lua_tolstring(L, -2, &keylen);
value = (char *) lua_tolstring(L, -1, &vallen);
if (keylen > 0xffff || vallen > 0xffff) continue;
*size += (2+keylen+2+vallen);
}
lua_pop(L, 1);
}
buf = uwsgi_malloc(*size);
ptrbuf = buf;
lua_pushnil(L);
while (lua_next(L, index) != 0) {
if (lua_isstring(L, -2) && lua_isstring(L, -1)) {
key = (char *) lua_tolstring(L, -2, &keylen);
value = (char *) lua_tolstring(L, -1, &vallen);
if (keylen > 0xffff || vallen > 0xffff) continue;
*ptrbuf++ = (uint8_t) (keylen & 0xff);
*ptrbuf++ = (uint8_t) ((keylen >>8) & 0xff);
memcpy(ptrbuf, key, keylen); ptrbuf += keylen;
*ptrbuf++ = (uint8_t) (vallen & 0xff);
*ptrbuf++ = (uint8_t) ((vallen >>8) & 0xff);
memcpy(ptrbuf, value, vallen); ptrbuf += vallen;
}
lua_pop(L, 1);
}
return buf;
}
static int uwsgi_api_cache_set(lua_State *L) {
int args = lua_gettop(L);
@@ -137,6 +90,8 @@ static int uwsgi_api_cache_set(lua_State *L) {
uint64_t expires = 0;
size_t vallen;
if (!uwsgi.caches) goto error;
if (args > 1) {
@@ -146,10 +101,13 @@ static int uwsgi_api_cache_set(lua_State *L) {
expires = lua_tonumber(L, 3);
}
uwsgi_wlock(uwsgi.caches->lock);
uwsgi_cache_set((char *)key, strlen(key), (char *)value, (uint16_t) vallen, expires, 0);
uwsgi_rwunlock(uwsgi.caches->lock);
}
error:
lua_pushnil(L);
return 1;
@@ -185,94 +143,30 @@ static int uwsgi_api_cache_get(lua_State *L) {
lca(L, 1);
if (!uwsgi.caches) goto error;
if (lua_isstring(L, 1)) {
// get the key
key = lua_tolstring(L, 1, NULL);
uwsgi_rlock(uwsgi.caches->lock);
value = uwsgi_cache_get((char *)key, strlen(key), &valsize);
if (value) {
lua_pushlstring(L, value, valsize);
uwsgi_rwunlock(uwsgi.caches->lock);
return 1;
}
uwsgi_rwunlock(uwsgi.caches->lock);
}
error:
lua_pushnil(L);
return 1;
}
static int uwsgi_api_send_message(lua_State *L) {
int args = lua_gettop(L);
const char *host;
int uwsgi_fd;
uint8_t modifier1, modifier2;
char *pkt = NULL;
uint16_t pktsize = 0 ;
char buf[4096];
int rlen;
int items = 0;
int input_fd = -1, timeout = -1, input_size = 0;
// is this an fd ?
if (lua_isnumber(L, 1)) {
args = 1;
}
else if (lua_isstring(L, 1)) {
host = lua_tolstring(L, 1, NULL);
uwsgi_fd = uwsgi_connect((char *)host, timeout, 0);
modifier1 = lua_tonumber(L, 2);
modifier2 = lua_tonumber(L, 3);
if (args > 4) {
timeout = lua_tonumber(L, 5);
if (args == 7) {
input_fd = lua_tonumber(L, 6);
input_size = lua_tonumber(L, 7);
}
}
if (lua_istable(L,4)) {
// passed a table
pkt = encode_lua_table(L, 4, &pktsize);
}
if (uwsgi_send_message(uwsgi_fd, modifier1, modifier2, pkt, pktsize, input_fd, input_size, timeout) == -1) {
free(pkt);
lua_pushnil(L);
return 1;
}
free(pkt);
for(;;) {
rlen = uwsgi_waitfd(uwsgi_fd, timeout);
if (rlen > 0) {
rlen = read(uwsgi_fd, buf, 4096);
if (rlen < 0) {
uwsgi_error("read()");
break;
}
else if (rlen > 0) {
lua_pushlstring(L, buf, rlen);
items++;
}
else {
break;
}
}
else if (rlen == 0) {
uwsgi_log("uwsgi request timed out waiting for response\n");
break;
}
}
close(uwsgi_fd);
}
return items;
}
static int uwsgi_api_cl(lua_State *L) {
struct wsgi_request *wsgi_req = current_wsgi_req();
@@ -338,9 +232,7 @@ static int uwsgi_api_unlock(lua_State *L) {
static const luaL_reg uwsgi_api[] = {
{"log", uwsgi_api_log},
{"cl", uwsgi_api_cl},
{"req_fd", uwsgi_api_req_fd},
{"send_message", uwsgi_api_send_message},
{"connection_fd", uwsgi_api_req_fd},
{"cache_get", uwsgi_api_cache_get},
{"cache_set", uwsgi_api_cache_set},
{"register_signal", uwsgi_api_register_signal},
@@ -374,9 +266,9 @@ static int uwsgi_lua_input(lua_State *L) {
return 0;
}
int uwsgi_lua_init(){
static int uwsgi_lua_init(){
uwsgi_log("Initializing Lua environment... (%d cores)\n", uwsgi.cores);
uwsgi_log("Initializing Lua environment... (%d lua_States)\n", uwsgi.cores);
ulua.L = uwsgi_malloc( sizeof(lua_State*) * uwsgi.cores );
@@ -386,7 +278,7 @@ int uwsgi_lua_init(){
}
void uwsgi_lua_app() {
static void uwsgi_lua_app() {
int i;
if (ulua.filename) {
@@ -423,7 +315,7 @@ void uwsgi_lua_app() {
}
}
int uwsgi_lua_request(struct wsgi_request *wsgi_req) {
static int uwsgi_lua_request(struct wsgi_request *wsgi_req) {
int i;
const char *http, *http2;
@@ -538,13 +430,13 @@ clear:
}
void uwsgi_lua_after_request(struct wsgi_request *wsgi_req) {
static void uwsgi_lua_after_request(struct wsgi_request *wsgi_req) {
log_request(wsgi_req);
}
int uwsgi_lua_magic(char *mountpoint, char *lazy) {
static int uwsgi_lua_magic(char *mountpoint, char *lazy) {
if (!strcmp(lazy+strlen(lazy)-4, ".lua")) {
ulua.filename = lazy;
@@ -559,7 +451,7 @@ int uwsgi_lua_magic(char *mountpoint, char *lazy) {
return 0;
}
char *uwsgi_lua_code_string(char *id, char *code, char *func, char *key, uint16_t keylen) {
static char *uwsgi_lua_code_string(char *id, char *code, char *func, char *key, uint16_t keylen) {
static struct lua_State *L = NULL;
@@ -607,13 +499,15 @@ char *uwsgi_lua_code_string(char *id, char *code, char *func, char *key, uint16_
return NULL;
}
int uwsgi_lua_signal_handler(uint8_t sig, void *handler) {
static int uwsgi_lua_signal_handler(uint8_t sig, void *handler) {
struct wsgi_request *wsgi_req = current_wsgi_req();
lua_State *L = ulua.L[wsgi_req->async_id];
#ifdef UWSGI_DEBUG
uwsgi_log("managing signal handler on core %d\n", wsgi_req->async_id);
#endif
lua_rawgeti(L, LUA_REGISTRYINDEX, (long) handler);
@@ -631,7 +525,7 @@ int uwsgi_lua_signal_handler(uint8_t sig, void *handler) {
}
uint16_t uwsgi_lua_rpc(void * func, uint8_t argc, char **argv, uint16_t argvs[], char *buffer) {
static uint16_t uwsgi_lua_rpc(void * func, uint8_t argc, char **argv, uint16_t argvs[], char *buffer) {
uint8_t i;
const char *sv;
@@ -643,7 +537,9 @@ uint16_t uwsgi_lua_rpc(void * func, uint8_t argc, char **argv, uint16_t argvs[],
lua_State *L = ulua.L[wsgi_req->async_id];
#ifdef UWSGI_DEBUG
uwsgi_log("get function %d\n", ifunc);
#endif
lua_rawgeti(L, LUA_REGISTRYINDEX, ifunc);
for(i=0;i<argc;i++) {
@@ -658,7 +554,9 @@ uint16_t uwsgi_lua_rpc(void * func, uint8_t argc, char **argv, uint16_t argvs[],
sv = lua_tolstring(L, -1, &sl);
#ifdef UWSGI_DEBUG
uwsgi_log("sv = %s sl = %lu\n", sv, (unsigned long) sl);
#endif
if (sl <= 0xffff) {
memcpy(buffer, sv, sl);
return sl;