mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 20:23:06 +00:00
reload snlua service
This commit is contained in:
2
Makefile
2
Makefile
@@ -67,7 +67,7 @@ service/localcast.so : service-src/service_localcast.c
|
|||||||
gcc $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src
|
gcc $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src
|
||||||
|
|
||||||
luaclib/skynet.so : lualib-src/lua-skynet.c lualib-src/lua-seri.c lualib-src/lua-remoteobj.c lualib-src/trace_service.c | luaclib
|
luaclib/skynet.so : lualib-src/lua-skynet.c lualib-src/lua-seri.c lualib-src/lua-remoteobj.c lualib-src/trace_service.c | luaclib
|
||||||
gcc $(CFLAGS) $(SHARED) -Iluacompat $^ -o $@ -Iskynet-src -Ilualib-src
|
gcc $(CFLAGS) $(SHARED) -Iluacompat $^ -o $@ -Iskynet-src -Iservice-src -Ilualib-src
|
||||||
|
|
||||||
service/client.so : service-src/service_client.c
|
service/client.so : service-src/service_client.c
|
||||||
gcc $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src
|
gcc $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "skynet.h"
|
#include "skynet.h"
|
||||||
#include "trace_service.h"
|
#include "trace_service.h"
|
||||||
#include "lua-seri.h"
|
#include "lua-seri.h"
|
||||||
|
#include "service_lua.h"
|
||||||
|
|
||||||
#include "luacompat52.h"
|
#include "luacompat52.h"
|
||||||
|
|
||||||
@@ -20,6 +21,7 @@ struct stat {
|
|||||||
uint32_t ti_sec;
|
uint32_t ti_sec;
|
||||||
uint32_t ti_nsec;
|
uint32_t ti_nsec;
|
||||||
struct trace_pool *trace;
|
struct trace_pool *trace;
|
||||||
|
struct snlua *lua;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -81,8 +83,27 @@ _cb(struct skynet_context * context, void * ud, int type, int session, uint32_t
|
|||||||
int r = lua_pcall(L, 5, 0 , trace);
|
int r = lua_pcall(L, 5, 0 , trace);
|
||||||
|
|
||||||
_stat_end(S, &ti);
|
_stat_end(S, &ti);
|
||||||
if (r == LUA_OK)
|
if (r == LUA_OK) {
|
||||||
|
if (S->lua->reload) {
|
||||||
|
skynet_callback(context, NULL, 0);
|
||||||
|
struct snlua * lua = S->lua;
|
||||||
|
assert(lua->L == L);
|
||||||
|
const char * cmd = lua->reload;
|
||||||
|
lua->reload = NULL;
|
||||||
|
lua->L = luaL_newstate();
|
||||||
|
int err = lua->init(lua, context, cmd);
|
||||||
|
if (err) {
|
||||||
|
skynet_callback(context, S, _cb);
|
||||||
|
skynet_error(context, "lua reload failed : %s", cmd);
|
||||||
|
lua_close(lua->L);
|
||||||
|
lua->L = L;
|
||||||
|
} else {
|
||||||
|
skynet_error(context, "lua reload %s", cmd);
|
||||||
|
lua_close(L);
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
const char * self = skynet_command(context, "REG", NULL);
|
const char * self = skynet_command(context, "REG", NULL);
|
||||||
switch (r) {
|
switch (r) {
|
||||||
case LUA_ERRRUN:
|
case LUA_ERRRUN:
|
||||||
@@ -113,10 +134,11 @@ _delete_stat(lua_State *L) {
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
_callback(lua_State *L) {
|
_callback(lua_State *L) {
|
||||||
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
struct snlua *lua = lua_touserdata(L, lua_upvalueindex(1));
|
||||||
if (context == NULL) {
|
if (lua == NULL || lua->ctx == NULL) {
|
||||||
return luaL_error(L, "Init skynet context first");
|
return luaL_error(L, "Init skynet context first");
|
||||||
}
|
}
|
||||||
|
struct skynet_context * context = lua->ctx;
|
||||||
|
|
||||||
luaL_checktype(L,1,LUA_TFUNCTION);
|
luaL_checktype(L,1,LUA_TFUNCTION);
|
||||||
lua_settop(L,1);
|
lua_settop(L,1);
|
||||||
@@ -129,6 +151,7 @@ _callback(lua_State *L) {
|
|||||||
memset(S, 0, sizeof(*S));
|
memset(S, 0, sizeof(*S));
|
||||||
S->L = gL;
|
S->L = gL;
|
||||||
S->trace = trace_create();
|
S->trace = trace_create();
|
||||||
|
S->lua = lua;
|
||||||
|
|
||||||
lua_createtable(L,0,1);
|
lua_createtable(L,0,1);
|
||||||
lua_pushcfunction(L, _delete_stat);
|
lua_pushcfunction(L, _delete_stat);
|
||||||
@@ -398,6 +421,15 @@ _trace_register(lua_State *L) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_reload(lua_State *L) {
|
||||||
|
struct snlua *lua = lua_touserdata(L,lua_upvalueindex(1));
|
||||||
|
lua->reload = luaL_checkstring(L,1);
|
||||||
|
lua_settop(L,1);
|
||||||
|
lua_replace(L,lua_upvalueindex(2));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// define in lua-remoteobj.c
|
// define in lua-remoteobj.c
|
||||||
int remoteobj_init(lua_State *L);
|
int remoteobj_init(lua_State *L);
|
||||||
|
|
||||||
@@ -417,26 +449,12 @@ luaopen_skynet_c(lua_State *L) {
|
|||||||
{ "redirect", _redirect },
|
{ "redirect", _redirect },
|
||||||
{ "forward", _forward },
|
{ "forward", _forward },
|
||||||
{ "command" , _command },
|
{ "command" , _command },
|
||||||
{ "callback" , _callback },
|
|
||||||
{ "error", _error },
|
{ "error", _error },
|
||||||
{ "tostring", _tostring },
|
{ "tostring", _tostring },
|
||||||
{ "harbor", _harbor },
|
{ "harbor", _harbor },
|
||||||
{ NULL, NULL },
|
{ NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
lua_createtable(L, 0, (sizeof(pack) + sizeof(l))/sizeof(luaL_Reg)-2);
|
|
||||||
lua_newtable(L);
|
|
||||||
lua_pushstring(L,"__remote");
|
|
||||||
luaL_setfuncs(L,pack,2);
|
|
||||||
|
|
||||||
lua_getfield(L, LUA_REGISTRYINDEX, "skynet_context");
|
|
||||||
struct skynet_context * ctx = lua_touserdata(L,-1);
|
|
||||||
if (ctx == NULL) {
|
|
||||||
return luaL_error(L, "Init skynet context first");
|
|
||||||
}
|
|
||||||
|
|
||||||
luaL_setfuncs(L,l,1);
|
|
||||||
|
|
||||||
luaL_Reg l2[] = {
|
luaL_Reg l2[] = {
|
||||||
{ "stat", _stat },
|
{ "stat", _stat },
|
||||||
{ "remote_init", remoteobj_init },
|
{ "remote_init", remoteobj_init },
|
||||||
@@ -448,6 +466,29 @@ luaopen_skynet_c(lua_State *L) {
|
|||||||
{ NULL, NULL },
|
{ NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
lua_createtable(L, 0, (sizeof(pack) + sizeof(l) + sizeof(l2))/sizeof(luaL_Reg)-1);
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_pushstring(L,"__remote");
|
||||||
|
luaL_setfuncs(L,pack,2);
|
||||||
|
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, "skynet_lua");
|
||||||
|
struct snlua *lua = lua_touserdata(L,-1);
|
||||||
|
if (lua == NULL || lua->ctx == NULL) {
|
||||||
|
return luaL_error(L, "Init skynet context first");
|
||||||
|
}
|
||||||
|
assert(lua->L == L);
|
||||||
|
|
||||||
|
lua_pushvalue(L,-1);
|
||||||
|
lua_pushcclosure(L,_callback,1);
|
||||||
|
lua_setfield(L, -3, "callback");
|
||||||
|
|
||||||
|
lua_pushnil(L);
|
||||||
|
lua_pushcclosure(L,_reload,2);
|
||||||
|
lua_setfield(L, -2, "reload");
|
||||||
|
|
||||||
|
lua_pushlightuserdata(L, lua->ctx);
|
||||||
|
luaL_setfuncs(L,l,1);
|
||||||
|
|
||||||
luaL_setfuncs(L,l2,0);
|
luaL_setfuncs(L,l2,0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -465,6 +465,11 @@ function dbgcmd.INFO()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function dbgcmd.RELOAD(...)
|
||||||
|
local cmd = table.concat({...}, " ")
|
||||||
|
c.reload(cmd)
|
||||||
|
end
|
||||||
|
|
||||||
local function _debug_dispatch(session, address, cmd, ...)
|
local function _debug_dispatch(session, address, cmd, ...)
|
||||||
local f = dbgcmd[cmd]
|
local f = dbgcmd[cmd]
|
||||||
assert(f, cmd)
|
assert(f, cmd)
|
||||||
|
|||||||
@@ -4,17 +4,13 @@
|
|||||||
#include <lualib.h>
|
#include <lualib.h>
|
||||||
#include <lauxlib.h>
|
#include <lauxlib.h>
|
||||||
#include "luacompat52.h"
|
#include "luacompat52.h"
|
||||||
|
#include "service_lua.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
lua_State *
|
|
||||||
snlua_create(void) {
|
|
||||||
return luaL_newstate();
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_try_load(lua_State *L, const char * path, int pathlen, const char * name) {
|
_try_load(lua_State *L, const char * path, int pathlen, const char * name) {
|
||||||
int namelen = strlen(name);
|
int namelen = strlen(name);
|
||||||
@@ -102,12 +98,14 @@ traceback (lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
snlua_init(lua_State *L, struct skynet_context *ctx, const char * args) {
|
snlua_init(struct snlua *l, struct skynet_context *ctx, const char * args) {
|
||||||
|
lua_State *L = l->L;
|
||||||
|
l->ctx = ctx;
|
||||||
luaL_init(L);
|
luaL_init(L);
|
||||||
lua_gc(L, LUA_GCSTOP, 0);
|
lua_gc(L, LUA_GCSTOP, 0);
|
||||||
luaL_openlibs(L);
|
luaL_openlibs(L);
|
||||||
lua_pushlightuserdata(L, ctx);
|
lua_pushlightuserdata(L, l);
|
||||||
lua_setfield(L, LUA_REGISTRYINDEX, "skynet_context");
|
lua_setfield(L, LUA_REGISTRYINDEX, "skynet_lua");
|
||||||
lua_gc(L, LUA_GCRESTART, 0);
|
lua_gc(L, LUA_GCRESTART, 0);
|
||||||
|
|
||||||
char tmp[strlen(args)+1];
|
char tmp[strlen(args)+1];
|
||||||
@@ -159,7 +157,17 @@ snlua_init(lua_State *L, struct skynet_context *ctx, const char * args) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
struct snlua *
|
||||||
snlua_release(lua_State *L) {
|
snlua_create(void) {
|
||||||
lua_close(L);
|
struct snlua * l = malloc(sizeof(*l));
|
||||||
|
memset(l,0,sizeof(*l));
|
||||||
|
l->L = luaL_newstate();
|
||||||
|
l->init = snlua_init;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
snlua_release(struct snlua *l) {
|
||||||
|
lua_close(l->L);
|
||||||
|
free(l);
|
||||||
}
|
}
|
||||||
|
|||||||
11
service-src/service_lua.h
Normal file
11
service-src/service_lua.h
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#ifndef SKYNET_SERVICE_LUA_H
|
||||||
|
#define SKYNET_SERVICE_LUA_H
|
||||||
|
|
||||||
|
struct snlua {
|
||||||
|
lua_State * L;
|
||||||
|
const char * reload;
|
||||||
|
struct skynet_context * ctx;
|
||||||
|
int (*init)(struct snlua *l, struct skynet_context *ctx, const char * args);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -17,6 +17,18 @@ function command.LIST()
|
|||||||
skynet.ret(skynet.pack(list))
|
skynet.ret(skynet.pack(list))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function command.RELOAD(handle)
|
||||||
|
handle = handle_to_address(handle)
|
||||||
|
local cmd = string.match(services[handle], "snlua (.+)")
|
||||||
|
print(services[handle],cmd)
|
||||||
|
if cmd then
|
||||||
|
skynet.send(handle,"debug","RELOAD",cmd)
|
||||||
|
skynet.ret(skynet.pack({cmd}))
|
||||||
|
else
|
||||||
|
skynet.ret(skynet.pack({"Support only snlua"}))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function command.STAT()
|
function command.STAT()
|
||||||
local list = {}
|
local list = {}
|
||||||
for k,v in pairs(services) do
|
for k,v in pairs(services) do
|
||||||
|
|||||||
@@ -588,7 +588,6 @@ skynet_context_init(struct skynet_context *ctx, uint32_t handle) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
skynet_callback(struct skynet_context * context, void *ud, skynet_cb cb) {
|
skynet_callback(struct skynet_context * context, void *ud, skynet_cb cb) {
|
||||||
assert(context->cb == NULL);
|
|
||||||
context->cb = cb;
|
context->cb = cb;
|
||||||
context->cb_ud = ud;
|
context->cb_ud = ud;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user