修改目录结构, 添加文档
This commit is contained in:
@@ -17,4 +17,4 @@ if (CMAKE_BUILD_TYPE STREQUAL Debug)
|
||||
endif()
|
||||
|
||||
add_subdirectory(vendor)
|
||||
add_subdirectory(test)
|
||||
add_subdirectory(adapter)
|
||||
38
README.md
Normal file
38
README.md
Normal file
@@ -0,0 +1,38 @@
|
||||
* 简介
|
||||
* lua_sapp框架可以看成是lua和sapp平台的一个Adapter。可以使sapp的业务层插件使用lua语言编写。这样做有以下优点:
|
||||
* lua是高级语言,语法简单,有自动垃圾回收,对程序员要求低
|
||||
* 业务层逻辑由异步回调变成同步阻塞(利用lua的协程提供了一组同步api供业务层调用)
|
||||
* 平台内部的数据结构(如stream_info)对业务层透明
|
||||
* 增加了程序的健壮性,每个业务层插件运行在自己的lua虚拟机内,各个插件之间相互隔离。
|
||||
* 平台层次结构如下图所示
|
||||
* 
|
||||
|
||||
|
||||
* 设计思路
|
||||
* 基本思路
|
||||
* 在设计上,lua_sapp由多个adapter组成,如http_adapter, ssl_adapter,dns_adapter等。
|
||||
* 每个adapter都是一个业务层插件,从对应的解析层获取流量(如http_adapter从http解析层获取流量),然后调用注册了这个adapter的lua脚本。
|
||||
* lua脚本在./plug/lua下,通过配置文件中entry_type注册对应的adapter
|
||||
* 一个典型的插件组织如下:
|
||||
* 
|
||||
|
||||
|
||||
* 线程/协程模型
|
||||
* 每个流(如http stream)对应一个协程
|
||||
* m个线程,n个业务层插件,对应 m * n个lua虚拟机
|
||||
* 安装配置
|
||||
* 一键脚本
|
||||
|
||||
```bash
|
||||
git clone git@git.mesalab.cn:cuiyiming/lua_sapp.git
|
||||
cd lua_sapp && mkdir build && cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Debug ../ && make
|
||||
sh ../adapter/http_adapter/script/deploy.sh
|
||||
```
|
||||
* 测试环境
|
||||
* 目前192.168.11.137:/home/mesasoft/sapp_run1下面有一套配好的测试环境,直接运行sapp即可看到效果
|
||||
* 日志路径: ./log/lua_sapp
|
||||
* TODO
|
||||
* 目前只写了http协议的adapter, 其他如ssl, dns协议的adapter还未编写
|
||||
* 目前处于原型阶段,所以大量使用了C++的STL库,需要改成C语言
|
||||
* 代码缺少注释,但是可读性还不错,基本可以自解释
|
||||
3
adapter/CMakeLists.txt
Normal file
3
adapter/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
### http_adapter
|
||||
add_library(http_adapter SHARED http_adapter/src/adapter.cpp)
|
||||
target_link_libraries(http_adapter lua-static dl MESA_handle_logger MESA_htable MESA_prof_load)
|
||||
9
adapter/http_adapter/conf/http_adapter.inf
Normal file
9
adapter/http_adapter/conf/http_adapter.inf
Normal file
@@ -0,0 +1,9 @@
|
||||
[PLUGINFO]
|
||||
PLUGNAME = http_adapter
|
||||
SO_PATH = ./plug/business/http_adapter/libhttp_adapter.so
|
||||
INIT_FUNC = http_adapter_init
|
||||
DESTROY_FUNC = http_adapter_destroy
|
||||
|
||||
[HTTP]
|
||||
FUNC_FLAG = ALL
|
||||
FUNC_NAME = http_adapter_http_entry
|
||||
2
adapter/http_adapter/lua/conflist_lua.inf
Normal file
2
adapter/http_adapter/lua/conflist_lua.inf
Normal file
@@ -0,0 +1,2 @@
|
||||
./plug/lua/http_request/http_request.inf
|
||||
./plug/lua/http_response/http_response.inf
|
||||
3
adapter/http_adapter/lua/http_request/http_request.inf
Normal file
3
adapter/http_adapter/lua/http_request/http_request.inf
Normal file
@@ -0,0 +1,3 @@
|
||||
[main]
|
||||
file_path = ./plug/lua/http_request/http_request.lua
|
||||
entry_type = http
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
---http_request.lua: 结果打印出来
|
||||
function printf(s,...)
|
||||
io.write(s:format(...))
|
||||
io.flush()
|
||||
@@ -53,7 +53,7 @@ function process()
|
||||
end
|
||||
|
||||
--[[
|
||||
file = io.open("./log/lua/http_request.log", "a+")
|
||||
file = io.open("./log/lua_sapp/http_adapter/lua/http_request.log", "a+")
|
||||
format_write_file(file, "lua: call process\n")
|
||||
|
||||
format_write_file(file, "\nprint stream info: \n")
|
||||
3
adapter/http_adapter/lua/http_response/http_response.inf
Normal file
3
adapter/http_adapter/lua/http_response/http_response.inf
Normal file
@@ -0,0 +1,3 @@
|
||||
[main]
|
||||
file_path = ./plug/lua/http_response/http_response.lua
|
||||
entry_type = http
|
||||
@@ -1,4 +1,5 @@
|
||||
|
||||
---结果输出到文件中: ./log/lua_sapp/http_adapter/lua/http_response.log
|
||||
function printf(s,...)
|
||||
io.write(s:format(...))
|
||||
io.flush()
|
||||
@@ -28,9 +29,8 @@ function print_header(header)
|
||||
end
|
||||
|
||||
function process()
|
||||
file = io.open("./log/lua/http_response.log", "a+")
|
||||
file = io.open("./log/lua_sapp/http_adapter/lua/http_response.log", "a+")
|
||||
format_write_file(file, "lua: call process\n")
|
||||
|
||||
format_write_file(file, "\nprint stream info: \n")
|
||||
stream_info = get_stream_info()
|
||||
for k, v in pairs(stream_info) do
|
||||
11
adapter/http_adapter/script/deploy.sh
Normal file
11
adapter/http_adapter/script/deploy.sh
Normal file
@@ -0,0 +1,11 @@
|
||||
SAPP_RUN=$1
|
||||
if [ "${SAPP_RUN}" = "" ]; then
|
||||
echo "USAGE: sh build_rpm.sh sapp_path" && exit 0
|
||||
fi
|
||||
mkdir -p $SAPP_RUN/plug/business/http_adapter
|
||||
/bin/cp -f adapter/libhttp_adapter.so $SAPP_RUN/plug/business/http_adapter/libhttp_adapter.so
|
||||
/bin/cp -f ../adapter/http_adapter/conf/http_adapter.inf $SAPP_RUN/plug/business/http_adapter/http_adapter.inf
|
||||
/bin/cp -rf ../adapter/http_adapter/lua $SAPP_RUN/plug
|
||||
mkdir -p $SAPP_RUN/log/lua_sapp/http_adapter/lua/
|
||||
cat $SAPP_RUN/plug/business/conflist_business.inf | grep "http_adapter.inf" >/dev/null 2>&1 && exit
|
||||
echo ./plug/business/http_adapter/http_adapter.inf >> $SAPP_RUN/plug/business/conflist_business.inf
|
||||
@@ -6,20 +6,20 @@
|
||||
//压栈之前要check_stack done
|
||||
//流结束clear_ctx之外还要释放该协程,自动垃圾回收?做实验验证一下 done
|
||||
//destroy,释放lua_state done
|
||||
//多线程 m * n个虚拟机
|
||||
//dumpfile改成在线试一下
|
||||
//多线程 m * n个虚拟机(m是线程数量,n是lua插件数量) done
|
||||
//错误处理,日志, 工程化,日志完备
|
||||
|
||||
static void* g_logger = NULL;
|
||||
static std::vector<std::vector<lua_State*>> g_http_lua_states;
|
||||
extern int g_iThreadNum;
|
||||
|
||||
static void lua_traceback(const char *func_name, lua_State *lua_state, int ret){
|
||||
int n = lua_gettop(lua_state);
|
||||
printf("%s error: ret is %d, traceback is:\n", func_name, ret);
|
||||
MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "%s error: ret is %d, traceback is: ", func_name, ret);
|
||||
for(int i = -1; i >= 0 - n; i--){
|
||||
std::string type = std::string(lua_typename(lua_state, lua_type(lua_state, i)));
|
||||
if(type == "string"){
|
||||
printf("%s\n", lua_tostring(lua_state, i));
|
||||
MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "%s", lua_tostring(lua_state, i));
|
||||
}
|
||||
}
|
||||
lua_pop(lua_state, n);
|
||||
@@ -56,8 +56,7 @@ static int get_stream_tuple5(lua_State *lua_state){
|
||||
http_sess_ctx *sess_ctx = (http_sess_ctx *)lua_touserdata(lua_state, -1);
|
||||
lua_pop(lua_state, 1);
|
||||
if(sess_ctx == NULL){
|
||||
//do log
|
||||
std::cout<<"sess_ctx is null"<<std::endl;
|
||||
MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "sess_ctx is null");
|
||||
return -1;
|
||||
}
|
||||
stream_tuple5& tuple5 = sess_ctx->tuple5;
|
||||
@@ -95,7 +94,7 @@ static int _get_stream_info(lua_State *lua_state, int status, lua_KContext yield
|
||||
}
|
||||
|
||||
static int get_stream_info(lua_State* lua_state){
|
||||
//printf("call get_strem_info\n");
|
||||
MESA_handle_runtime_log(g_logger, RLOG_LV_DEBUG, LOG_MODULE_NAME, "call get_strem_info");
|
||||
return _get_stream_info(lua_state, 0, 0);
|
||||
}
|
||||
|
||||
@@ -104,8 +103,7 @@ static int get_http_header(lua_State *lua_state, int type){
|
||||
http_sess_ctx *sess_ctx = (http_sess_ctx *)lua_touserdata(lua_state, -1);
|
||||
lua_pop(lua_state, 1);
|
||||
if(sess_ctx == NULL){
|
||||
//do log
|
||||
std::cout<<"sess_ctx is null"<<std::endl;
|
||||
MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "sess_ctx is null");
|
||||
return -1;
|
||||
}
|
||||
std::unordered_set<std::string> required_regions;
|
||||
@@ -116,7 +114,7 @@ static int get_http_header(lua_State *lua_state, int type){
|
||||
}
|
||||
http_header& header = (type == HTTP_TYPE_REQUEST ? sess_ctx->req_header : sess_ctx->resp_header);
|
||||
if(header.parse_done == true){
|
||||
//printf("header parse done\n");
|
||||
MESA_handle_runtime_log(g_logger, RLOG_LV_DEBUG, LOG_MODULE_NAME, "header parse done");
|
||||
lua_newtable(lua_state);
|
||||
for(auto region : header.std_regions){
|
||||
if(required_regions.find("ALL") != required_regions.end() || required_regions.find(region.first) != required_regions.end()){
|
||||
@@ -143,7 +141,7 @@ static int get_http_header(lua_State *lua_state, int type){
|
||||
}
|
||||
|
||||
static int _get_http_request_header(lua_State *lua_state, int status, lua_KContext yieldk_ctx){
|
||||
//printf("call get_http_request_header\n");
|
||||
MESA_handle_runtime_log(g_logger, RLOG_LV_DEBUG, LOG_MODULE_NAME, "call get_http_request_header");
|
||||
int ret = get_http_header(lua_state, HTTP_TYPE_REQUEST);
|
||||
if(ret < 0){
|
||||
lua_yieldk(lua_state, 0, 0, _get_http_request_header);
|
||||
@@ -168,13 +166,12 @@ static int get_http_response_header(lua_State* lua_state){
|
||||
}
|
||||
|
||||
static int get_http_body(lua_State *lua_state, int type){
|
||||
//printf("call _get_http_response_body\n");
|
||||
MESA_handle_runtime_log(g_logger, RLOG_LV_DEBUG, LOG_MODULE_NAME, "call _get_http_response_body");
|
||||
lua_getglobal(lua_state, "cur_http_sess_ctx");
|
||||
http_sess_ctx *sess_ctx = (http_sess_ctx *)lua_touserdata(lua_state, -1);
|
||||
lua_pop(lua_state, 1);
|
||||
if(sess_ctx == NULL){
|
||||
//do log
|
||||
std::cout<<"sess_ctx is null"<<std::endl;
|
||||
MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "sess_ctx is null");
|
||||
return -1;
|
||||
}
|
||||
http_body& body = (type == HTTP_TYPE_REQUEST? sess_ctx->req_body : sess_ctx->resp_body);
|
||||
@@ -230,20 +227,19 @@ static int load_lua_http_plug(const char *profile, int thread_num){
|
||||
char entry_type[LUA_SAPP_SYMBOL_MAX] = "";
|
||||
MESA_load_profile_string_def(profile, section, "file_path", file_path, sizeof(file_path), "");
|
||||
MESA_load_profile_string_def(profile, section, "entry_type", entry_type, sizeof(entry_type), "");
|
||||
printf("MESA_prof_load: profile is %s, section is %s, file_path is %s, entry_type is %s\n",
|
||||
profile, section, file_path, entry_type);
|
||||
MESA_handle_runtime_log(g_logger, RLOG_LV_INFO, LOG_MODULE_NAME, "MESA_prof_load: profile is %s, section is %s,"
|
||||
"file_path is %s, entry_type is %s\n", profile, section, file_path, entry_type);
|
||||
if(strncmp(entry_type, "http", LUA_SAPP_SYMBOL_MAX) == 0){
|
||||
for(int i = 0; i < thread_num; i++){
|
||||
lua_State *lua_state = luaL_newstate();
|
||||
if(lua_state == NULL){
|
||||
printf("failed to LuaL_newstate\n");
|
||||
MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "failed to LuaL_newstate");
|
||||
return -1;
|
||||
}
|
||||
luaL_openlibs(lua_state);
|
||||
int ret = luaL_dofile(lua_state, file_path);
|
||||
if(ret){
|
||||
//log error
|
||||
printf("error: ret is %d, file_path is %s\n", ret, file_path);
|
||||
MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "error: ret is %d, file_path is %s\n", ret, file_path);
|
||||
return -1;
|
||||
}
|
||||
lua_register(lua_state, "get_stream_info", get_stream_info);
|
||||
@@ -278,7 +274,7 @@ static int process_lua_plug_conflist(const char* filename, int thread_num)
|
||||
lua_plug_conf_path[len - 1] = '\0';
|
||||
int ret = load_lua_http_plug(lua_plug_conf_path, thread_num);
|
||||
if(ret < 0){
|
||||
printf("failed to load_lua_plug: conf_path is %s\n", lua_plug_conf_path);
|
||||
MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "failed to load_lua_plug: conf_path is %s\n", lua_plug_conf_path);
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
@@ -292,8 +288,7 @@ static http_sess_ctx* init_http_sess_ctx(int thread_seq){
|
||||
lua_State* coroutine = lua_newthread(lua_state);
|
||||
int ret = lua_checkstack(lua_state, 1);
|
||||
if(ret != 1){
|
||||
//do log
|
||||
printf("do not have enough space, ret is %d\n", ret);
|
||||
MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "do not have enough space, ret is %d\n", ret);
|
||||
continue;
|
||||
}
|
||||
ctx->coroutines.push_back(coroutine);
|
||||
@@ -313,8 +308,7 @@ std::string utils_inet_ntoa(uint32_t ip)
|
||||
return std::string(_ip);
|
||||
}
|
||||
|
||||
uchar NEW_HTTP_SERVICE_ENTRY(stSessionInfo* session_info, void **param, int thread_seq, struct streaminfo *a_tcp, void *a_packet){
|
||||
//printf("thread_seq is %d\n", thread_seq);
|
||||
extern "C" uchar http_adapter_http_entry(stSessionInfo* session_info, void **param, int thread_seq, struct streaminfo *a_tcp, void *a_packet){
|
||||
uchar ret = PROT_STATE_GIVEME;
|
||||
http_sess_ctx *ctx = (http_sess_ctx*)*param;
|
||||
http_infor *a_http = (http_infor *)(session_info->app_info);
|
||||
@@ -382,7 +376,6 @@ uchar NEW_HTTP_SERVICE_ENTRY(stSessionInfo* session_info, void **param, int thre
|
||||
break;
|
||||
}
|
||||
uchar http_state = a_http->http_state;
|
||||
//printf("curdir is %d, http_state is %d\n", curdir, http_state);
|
||||
//header over
|
||||
if(http_state == HTTP_DATA_BEGIN){
|
||||
if(curdir == DIR_C2S){
|
||||
@@ -410,7 +403,7 @@ uchar NEW_HTTP_SERVICE_ENTRY(stSessionInfo* session_info, void **param, int thre
|
||||
int ret = lua_checkstack(coroutine, 1);
|
||||
if(ret != 1){
|
||||
//do log
|
||||
printf("do not have enough space, ret is %d\n", ret);
|
||||
MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "do not have enough space, ret is %d", ret);
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
@@ -430,26 +423,20 @@ uchar NEW_HTTP_SERVICE_ENTRY(stSessionInfo* session_info, void **param, int thre
|
||||
}
|
||||
}
|
||||
if(session_info->session_state & SESSION_STATE_CLOSE){
|
||||
//printf("close tcp stream\n");
|
||||
MESA_handle_runtime_log(g_logger, RLOG_LV_INFO, LOG_MODULE_NAME, "close tcp stream");
|
||||
clear_http_sess_ctx(ctx);
|
||||
*param = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int NEW_HTTP_SERVICE_INIT(void){
|
||||
/*
|
||||
g_logger = MESA_create_runtime_log_handle("./log/http/http_service", 10);
|
||||
extern "C" int http_adapter_init(void){
|
||||
g_logger = MESA_create_runtime_log_handle("./log/lua_sapp/http_adapter/http_adapter.log", 10);
|
||||
if(g_logger == NULL){
|
||||
printf("%s init : get log handle error!\n", HTTP_SERVICE_PLUGNAME);
|
||||
MESA_handle_runtime_log(g_logger, RLOG_LV_FATAL, LOG_MODULE_NAME, "%s init : get log handle error!", HTTP_SERVICE_PLUGNAME);
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
int thread_num = 1;
|
||||
const char *profile = "./conf/main.conf";
|
||||
const char *section = "Module";
|
||||
MESA_load_profile_int_def(profile, section, "threadnum", (int*)&thread_num, 0);
|
||||
printf("MESA_prof_load: profile is %s, section is %s, thread_num is %d\n", profile, section, thread_num);
|
||||
int thread_num = g_iThreadNum;;
|
||||
for(int i = 0; i < thread_num; i++){
|
||||
g_http_lua_states.push_back(std::vector<lua_State*>());
|
||||
}
|
||||
@@ -460,7 +447,7 @@ int NEW_HTTP_SERVICE_INIT(void){
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NEW_HTTP_SERVICE_DESTROY(void){
|
||||
extern "C" void http_adapter_destroy(void){
|
||||
for(auto states : g_http_lua_states){
|
||||
for(auto state : states){
|
||||
lua_close(state);
|
||||
BIN
picture/platform.png
Normal file
BIN
picture/platform.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
BIN
picture/plugin.png
Normal file
BIN
picture/plugin.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 170 KiB |
@@ -1,15 +0,0 @@
|
||||
### test_coroutine
|
||||
add_executable(test_coroutine test_coroutine/main.cpp)
|
||||
#target_include_directories(test_coroutine PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
|
||||
target_link_libraries(test_coroutine lua-static dl)
|
||||
|
||||
|
||||
### test_plugin
|
||||
add_library(http_service SHARED test_plugin/http_service.cpp)
|
||||
#target_include_directories(http_service PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
|
||||
target_link_libraries(http_service MESA_handle_logger MESA_htable MESA_prof_load)
|
||||
|
||||
### new_http_service
|
||||
add_library(new_http_service SHARED new_http_service/adapter.cpp)
|
||||
#target_include_directories(new_http_service PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
|
||||
target_link_libraries(new_http_service lua-static dl MESA_handle_logger MESA_htable MESA_prof_load)
|
||||
@@ -1,226 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
#include <unordered_set>
|
||||
#include <unistd.h>
|
||||
using namespace std;
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lualib.h"
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
|
||||
static void output_stack_size(lua_State *L, int line){
|
||||
int n = lua_gettop(L);
|
||||
printf("line %d: stack size is %d\n", line, n);
|
||||
for(int i = -1; i >= 0 - n; i--){
|
||||
string type = string(lua_typename(L, lua_type(L, i)));
|
||||
string value = "unknown";
|
||||
if(type == "string"){
|
||||
value = lua_tostring(L, i);
|
||||
}
|
||||
printf("index is %d, type is %s, value is %s\n", i, type.c_str(), value.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void lua_traceback(const char *func_name, lua_State *L){
|
||||
int n = lua_gettop(L);
|
||||
printf("%s error: stack size is %d, traceback is:\n", func_name, n);
|
||||
for(int i = -1; i >= 0 - n; i--){
|
||||
string type = string(lua_typename(L, lua_type(L, i)));
|
||||
if(type == "string"){
|
||||
printf("%s\n", lua_tostring(L, i));
|
||||
}
|
||||
}
|
||||
lua_pop(L, n);
|
||||
}
|
||||
|
||||
//copy from suricata
|
||||
static int lua_push_string_buffer(lua_State *lua_state, const char *input, size_t input_len)
|
||||
{
|
||||
if (input_len % 4 != 0) {
|
||||
/* we're using a buffer sized at a multiple of 4 as lua_pushlstring generates
|
||||
* invalid read errors in valgrind otherwise. Adding in a nul to be sure.
|
||||
* Buffer size = len + 1 (for nul) + whatever makes it a multiple of 4 */
|
||||
size_t buflen = input_len + 1 + ((input_len + 1) % 4);
|
||||
char buf[buflen];
|
||||
memset(buf, 0x00, buflen);
|
||||
memcpy(buf, input, input_len);
|
||||
buf[input_len] = '\0';
|
||||
/* return value through lua_state, as a luastring */
|
||||
lua_pushlstring(lua_state, buf, input_len);
|
||||
} else {
|
||||
lua_pushlstring(lua_state, input, input_len);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void test_coroutine(int argc, char *argv[]){
|
||||
int max_state_num = 10;
|
||||
int max_coroutine_num = 100;
|
||||
if(argc > 2){
|
||||
max_state_num = atoi(argv[1]);
|
||||
max_coroutine_num = atoi(argv[2]);
|
||||
}
|
||||
const char *filename = "../../test/test_coroutine/test.lua";
|
||||
vector<lua_State*> states;
|
||||
for(int i = 0; i < max_state_num; i++){
|
||||
lua_State *L = luaL_newstate();
|
||||
luaL_openlibs(L);
|
||||
luaL_dofile(L, filename);
|
||||
states.push_back(L);
|
||||
}
|
||||
vector<pair<lua_State*, lua_State*>> coroutines;
|
||||
for(auto state : states){
|
||||
int i = 0;
|
||||
for(; i < max_coroutine_num; i++){
|
||||
lua_State* l = lua_newthread(state);
|
||||
int ret = lua_checkstack(state, 1);
|
||||
if(ret != 1)
|
||||
printf("do not have enough space, ret is %d\n", ret);
|
||||
coroutines.push_back({l, state});
|
||||
lua_getglobal(l, "test");
|
||||
//cout<<"after getglobal, size = "<<lua_gettop(l)<<endl;
|
||||
lua_pushinteger(l, i);
|
||||
//cout<<"after pushinterger, size = "<<lua_gettop(l)<<endl;
|
||||
lua_resume(l, state, 1);
|
||||
//cout<<"after resume, size = "<<lua_gettop(L)<<endl;
|
||||
}
|
||||
}
|
||||
sleep(2);
|
||||
cout<<"coroutine size: "<<coroutines.size()<<endl;
|
||||
while(true){
|
||||
for(auto coroutine : coroutines){
|
||||
lua_resume(coroutine.first, coroutine.second, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int foo (lua_State *L) {
|
||||
cout<<"call foo"<<endl;
|
||||
output_stack_size(L, 84);
|
||||
lua_Number sum = 0.0;
|
||||
int n = lua_gettop(L);
|
||||
for (int i = 1; i <= n; i++) {
|
||||
if (!lua_isnumber(L, i)) {
|
||||
printf("index %d is not number\n", i);
|
||||
//lua_pushliteral(L, "incorrect argument");
|
||||
//lua_error(L);
|
||||
}
|
||||
sum += lua_tonumber(L, i);
|
||||
}
|
||||
printf("sum is %f\n", sum);
|
||||
lua_pop(L, n);
|
||||
output_stack_size(L, 97);
|
||||
lua_pushnumber(L, sum/n); //first result
|
||||
lua_pushnumber(L, sum); //second result
|
||||
output_stack_size(L, 100);
|
||||
return 2; //number of results
|
||||
}
|
||||
|
||||
static int foo2(lua_State *L, int n, long int m){
|
||||
cout<<"cpp: after lua_yield"<<endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int flag = 0;
|
||||
|
||||
static int _foo1(lua_State *L, int status, lua_KContext yieldk_ctx){
|
||||
printf("call foo1\n");
|
||||
output_stack_size(L, 121);
|
||||
/*
|
||||
unordered_set<string> regions;
|
||||
output_stack_size(L);
|
||||
lua_pushnil(L);
|
||||
while(lua_next(L, -2) != 0){
|
||||
printf("%s - %s\n", lua_typename(L, lua_type(L, -2)), lua_typename(L, lua_type(L, -1)));
|
||||
regions.insert(string(lua_tostring(L, -1)));
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
for(auto region : regions)
|
||||
cout<<region<<endl;
|
||||
output_stack_size(L);
|
||||
*/
|
||||
//lua_pop(L, 1);
|
||||
if(flag == 1){
|
||||
lua_newtable(L);
|
||||
lua_push_string_buffer(L, "name", 4);
|
||||
lua_newtable(L);
|
||||
lua_push_string_buffer(L, "leo", 3);
|
||||
lua_rawseti(L, -2, 1);
|
||||
lua_push_string_buffer(L, "cui", 3);
|
||||
lua_rawseti(L, -2, 2);
|
||||
lua_settable(L, -3);
|
||||
return 1;
|
||||
}
|
||||
lua_yieldk(L, 0, 0, _foo1);
|
||||
}
|
||||
|
||||
static int foo1(lua_State *L){
|
||||
return _foo1(L, 0, 0);
|
||||
/*
|
||||
lua_getglobal(L, "g_http_sess_ctx");
|
||||
output_stack_size(L);
|
||||
int *ctx = (int *)lua_touserdata(L, 1);
|
||||
if(ctx == NULL)
|
||||
cout<<"ctx is null"<<endl;
|
||||
else
|
||||
cout<<"ctx is "<<*ctx<<endl;
|
||||
cout<<"cpp: call foo1"<<endl;
|
||||
*/
|
||||
//lua_yieldk(L, 0, 0, foo2);
|
||||
}
|
||||
|
||||
static void test_lua_CFunction(){
|
||||
const char *filename = "../../test/test_coroutine/test.lua";
|
||||
lua_State *L = luaL_newstate();
|
||||
luaL_openlibs(L);
|
||||
int ret = luaL_dofile(L, filename);
|
||||
printf("luaL_dofile, ret is %d\n", ret);
|
||||
lua_register(L, "myfoo", foo1);
|
||||
lua_getglobal(L, "lua_call_c");
|
||||
/*
|
||||
output_stack_size(L);
|
||||
lua_getglobal(L, "lua_call_c");
|
||||
output_stack_size(L);
|
||||
int *ctx = (int *)malloc(sizeof(int));
|
||||
*ctx = 3;
|
||||
lua_pushlightuserdata(L, (void *)ctx);
|
||||
output_stack_size(L);
|
||||
lua_setglobal (L, "g_http_sess_ctx");
|
||||
output_stack_size(L);
|
||||
//output_stack_size(L);
|
||||
//lua_pushinteger(L, 2);
|
||||
//lua_pushinteger(L, 3);
|
||||
*/
|
||||
//output_stack_size(L);
|
||||
|
||||
ret = lua_resume(L, NULL, 0);
|
||||
if(ret != LUA_OK && ret != LUA_YIELD){
|
||||
lua_traceback("lua_resume", L);
|
||||
return;
|
||||
}
|
||||
printf("lua resume: ret is %d\n", ret);
|
||||
//output_stack_size(L, 190);
|
||||
//flag = 1;
|
||||
|
||||
ret = lua_resume(L, NULL, 0);
|
||||
printf("lua resume: ret is %d\n", ret);
|
||||
output_stack_size(L, 194);
|
||||
|
||||
|
||||
//printf("lua_resume: ret is %d\n", ret);
|
||||
//cout<<"cpp: atfer lua_call"<<endl;
|
||||
//lua_resume(L, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
//test_coroutine(argc, argv);
|
||||
test_lua_CFunction();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
|
||||
function printf(s,...)
|
||||
io.write(s:format(...))
|
||||
end
|
||||
|
||||
format_write = function(file, s, ...)
|
||||
return file:write(s:format(...))
|
||||
end
|
||||
|
||||
function test(id)
|
||||
i = 0
|
||||
local j = 1
|
||||
while true do
|
||||
if j % 10000 == 5 and id % 10000 == 5 then
|
||||
printf("call test, coroutine id: %d, local index: %d, global index: %d\n", id, j, i)
|
||||
end
|
||||
j = j + 1
|
||||
i = i + 1
|
||||
coroutine.yield()
|
||||
end
|
||||
end
|
||||
|
||||
function foo(x)
|
||||
if x % 10000 == 5 then
|
||||
printf("cal foo: x = %d\n", x)
|
||||
end
|
||||
coroutine.yield()
|
||||
end
|
||||
|
||||
function foo1()
|
||||
print("call foo1")
|
||||
foo(10)
|
||||
return 3
|
||||
end
|
||||
|
||||
function main()
|
||||
n = 10000000
|
||||
co_list = {}
|
||||
for i = n, 1, -1 do
|
||||
co = coroutine.create(function (i)
|
||||
foo(i)
|
||||
end)
|
||||
table.insert(co_list, co);
|
||||
end
|
||||
while(true) do
|
||||
for i = 1, #co_list do
|
||||
coroutine.resume(co_list[i], i)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function lua_call_c()
|
||||
---printf("lua: call lua_call_c\n")
|
||||
t = {"aa", "bb", "cc"}
|
||||
file = io.open("./output.txt", "a+")
|
||||
format_write(file, "%s: %d", "age", 12)
|
||||
ret = myfoo(t)
|
||||
for k, v in pairs(ret["name"]) do
|
||||
print(k, v)
|
||||
end
|
||||
---printf("lua: after my_foo\n")
|
||||
end
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
/*
|
||||
* HTTP_Service.c
|
||||
*
|
||||
* Created on: 2013-8-19
|
||||
* Author: lishu
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdio.h>
|
||||
#include <regex.h>
|
||||
#include <string>
|
||||
#include "http_service.h"
|
||||
#include "MESA_handle_logger.h"
|
||||
|
||||
int HTTP_SERVICE_VERSION_1_20160412 = 0;
|
||||
void http_service_version_1_20160412()
|
||||
{
|
||||
//20160412 create project
|
||||
}
|
||||
|
||||
void* g_log_handle = NULL;
|
||||
|
||||
int init_pmeinfo(service_pmeinfo **service_pme, int thread_seq)
|
||||
{
|
||||
service_pmeinfo* pme = (service_pmeinfo*)dictator_malloc(thread_seq, sizeof(service_pmeinfo));
|
||||
*service_pme = pme;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void clear_pmeinfo(service_pmeinfo *service_pme, int thread_seq)
|
||||
{
|
||||
if(service_pme!=NULL)
|
||||
{
|
||||
dictator_free(thread_seq, service_pme);
|
||||
}
|
||||
service_pme = NULL;
|
||||
}
|
||||
|
||||
std::string trans_to_binary(unsigned int n){
|
||||
std::string res;
|
||||
while(n){
|
||||
res = std::to_string(n % 2) + res;
|
||||
n /= 2;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string _inet_ntoa(uint32_t ip)
|
||||
{
|
||||
const char *_ip = inet_ntoa(*(struct in_addr *)&ip);
|
||||
return std::string(_ip);
|
||||
}
|
||||
|
||||
|
||||
static int get_stream_tuple4(struct streaminfo *a_tcp){
|
||||
struct stream_tuple4_v4 *tuple4_v4 = a_tcp->addr.tuple4_v4;
|
||||
printf("saddr: %s\n", _inet_ntoa(tuple4_v4->saddr).c_str());
|
||||
printf("daddr: %s\n", _inet_ntoa(tuple4_v4->daddr).c_str());
|
||||
printf("source: %d\n", ntohs(tuple4_v4->source));
|
||||
printf("dest: %d\n", ntohs(tuple4_v4->dest));
|
||||
return 0;
|
||||
}
|
||||
|
||||
uchar HTTP_SERVICE_ENTRY(stSessionInfo* session_info, void **param, int thread_seq, struct streaminfo *a_tcp, void *a_packet)
|
||||
{
|
||||
//get_stream_tuple4(a_tcp);
|
||||
uchar rec = PROT_STATE_GIVEME;
|
||||
service_pmeinfo *service_pme = (service_pmeinfo*)*param;
|
||||
http_infor *a_http = (http_infor *)(session_info->app_info);
|
||||
char filename[512] = {0};
|
||||
const char* region = NULL;
|
||||
//static int header_len = 0;
|
||||
//static int content_len = 0;
|
||||
|
||||
uchar http_state = a_http->http_state;
|
||||
|
||||
if(NULL==session_info)
|
||||
{
|
||||
return PROT_STATE_DROPME;
|
||||
}
|
||||
|
||||
if(service_pme == NULL)
|
||||
{
|
||||
if(init_pmeinfo(&service_pme, thread_seq) <0)
|
||||
{
|
||||
return PROT_STATE_DROPME;
|
||||
}
|
||||
*param = service_pme;
|
||||
}
|
||||
std::string prot_flag_str = trans_to_binary(session_info->prot_flag);
|
||||
uchar curdir = a_http->curdir;
|
||||
printf("curdir is %d, http_state is %d\n", curdir, http_state);
|
||||
/*
|
||||
MESA_handle_runtime_log(g_log_handle, RLOG_LV_INFO, HTTP_SERVICE_PLUGNAME,
|
||||
"call http_service entry, http_state is %02x\n, prot_flag mask is %s : %d", http_state, prot_flag_str.c_str(), prot_flag_str.length() - 1);
|
||||
|
||||
if(curdir == DIR_C2S){
|
||||
int i = 0;
|
||||
printf("data begin: curdir is %d, http_state is %d, prot_flag mask is %d\n", curdir, http_state, prot_flag_str.length() - 1);
|
||||
}
|
||||
*/
|
||||
switch(session_info->prot_flag)
|
||||
{
|
||||
case HTTP_STATE:
|
||||
case HTTP_CONTENT:
|
||||
break;
|
||||
case HTTP_UNGZIP_CONTENT:
|
||||
snprintf(filename, sizeof(filename), "%s/HTTP_%s_%u", LOG_PATH, printaddr(&a_tcp->addr, thread_seq), a_http->http_session_seq);
|
||||
service_pme->fp = fopen(filename, "a+");
|
||||
if(NULL==service_pme->fp)
|
||||
{
|
||||
MESA_handle_runtime_log(g_log_handle, RLOG_LV_FATAL, HTTP_SERVICE_PLUGNAME, "%s file open error.", filename);
|
||||
return PROT_STATE_DROPME;
|
||||
}
|
||||
MESA_handle_runtime_log(g_log_handle, RLOG_LV_DEBUG, HTTP_SERVICE_PLUGNAME, "%s file open.",filename);
|
||||
|
||||
fwrite(session_info->buf, session_info->buflen, 1, service_pme->fp);
|
||||
fflush(service_pme->fp);
|
||||
//content_len += session_info->buflen;
|
||||
//printf("content_len:%d\n", content_len);
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s/HTTP_%s_%u", LOG_PATH, printaddr(&a_tcp->addr, thread_seq), a_http->http_session_seq);
|
||||
MESA_handle_runtime_log(g_log_handle, RLOG_LV_DEBUG, HTTP_SERVICE_PLUGNAME, "%s file close.",filename);
|
||||
fclose(service_pme->fp);
|
||||
break;
|
||||
default:
|
||||
snprintf(filename, sizeof(filename), "%s/HTTP_%s_%u", LOG_PATH, printaddr(&a_tcp->addr, thread_seq), a_http->http_session_seq);
|
||||
service_pme->fp = fopen(filename, "a+");
|
||||
if(NULL==service_pme->fp)
|
||||
{
|
||||
MESA_handle_runtime_log(g_log_handle, RLOG_LV_FATAL, HTTP_SERVICE_PLUGNAME, "%s file open error.", filename);
|
||||
return PROT_STATE_DROPME;
|
||||
}
|
||||
MESA_handle_runtime_log(g_log_handle, RLOG_LV_DEBUG, HTTP_SERVICE_PLUGNAME, "%s file open.",filename);
|
||||
|
||||
region = http_proto_flag2region(session_info->prot_flag);
|
||||
|
||||
fwrite(region, strlen(region), 1, service_pme->fp);
|
||||
fwrite(":", 1, 1, service_pme->fp);
|
||||
fwrite(session_info->buf, session_info->buflen, 1, service_pme->fp);
|
||||
fwrite("\r\n", 2, 1, service_pme->fp);
|
||||
fflush(service_pme->fp);
|
||||
//header_len += session_info->buflen;
|
||||
//printf("header_len:%d\n", header_len);
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s/HTTP_%s_%u", LOG_PATH, printaddr(&a_tcp->addr, thread_seq), a_http->http_session_seq);
|
||||
MESA_handle_runtime_log(g_log_handle, RLOG_LV_DEBUG, HTTP_SERVICE_PLUGNAME, "%s file close.",filename);
|
||||
fclose(service_pme->fp);
|
||||
break;
|
||||
}
|
||||
|
||||
if(session_info->session_state&SESSION_STATE_CLOSE)
|
||||
{
|
||||
if(NULL!=service_pme->fp)
|
||||
{
|
||||
|
||||
service_pme->fp = NULL;
|
||||
}
|
||||
clear_pmeinfo((service_pmeinfo*)*param, thread_seq);
|
||||
*param = NULL;
|
||||
}
|
||||
return rec;
|
||||
}
|
||||
|
||||
int HTTP_SERVICE_INIT(void)
|
||||
{
|
||||
g_log_handle = MESA_create_runtime_log_handle("./log/http/http_service", 10);
|
||||
if(g_log_handle == NULL)
|
||||
{
|
||||
printf("%s init : get log handle error!\n", HTTP_SERVICE_PLUGNAME);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HTTP_SERVICE_DESTROY(void)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* HTTP_Service.h
|
||||
*
|
||||
* Created on: 2013-8-19
|
||||
* Author: lishu
|
||||
*/
|
||||
|
||||
#ifndef HTTP_SERVICE_H_
|
||||
#define HTTP_SERVICE_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include </usr/include/net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include </usr/include/linux/sockios.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <regex.h>
|
||||
|
||||
|
||||
#include "stream.h"
|
||||
#include "http.h"
|
||||
|
||||
#define HTTP_SERVICE_PLUGNAME "http_service.so"
|
||||
#define LOG_PATH "./log/http/"
|
||||
|
||||
|
||||
typedef struct service_pmeinfo
|
||||
{
|
||||
FILE* fp;
|
||||
}service_pmeinfo;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uchar HTTP_SERVICE_ENTRY(stSessionInfo* session_info, void **param, int thread_seq, struct streaminfo *a_tcp, void *a_packet);
|
||||
int HTTP_SERVICE_INIT(void);
|
||||
void HTTP_SERVICE_DESTROY(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HTTP_SERVICE_H_ */
|
||||
4
vendor/CMakeLists.txt
vendored
4
vendor/CMakeLists.txt
vendored
@@ -4,9 +4,9 @@ include(ExternalProject)
|
||||
ExternalProject_Add(lua
|
||||
PREFIX lua
|
||||
URL ${CMAKE_CURRENT_SOURCE_DIR}/lua-5.3.5.tar.gz
|
||||
URL_MD5 184779090118aebdf125fdb1233335ea
|
||||
URL_MD5 4f4b4f323fd3514a68e0ab3da8ce3455
|
||||
CONFIGURE_COMMAND cd ./src
|
||||
BUILD_COMMAND make linux
|
||||
BUILD_COMMAND make linux MYCFLAGS="-fPIC"
|
||||
INSTALL_COMMAND make install INSTALL_TOP=<INSTALL_DIR>
|
||||
BUILD_IN_SOURCE 1)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user