Thank you, I'll take a look into this today!
2011/3/10 zhiguo zhao <zha...@gmail.com>: > > Hi, > Some days I post my first > letter(http://mail-archives.apache.org/mod_mbox/httpd-dev/201103.mbox/raw/%3CAANLkTimfg4yeGExZXNP=yjybjdrmhrqpb4jo--sn6...@mail.gmail.com%3E) > in http-dev, but the letter can be send to every's box with some reason., > And now I update mod_lua to support lua server scope with > apr_reslist_apis, and I do some test with ab on my Pc. > I got better performance. (75 -> 227 -> 277) #/s > Change please see patch file, I hope this patch can be merge in svn.. :) > mod_lua in svn,head version > ----------------------------------------------------------------------- > This is ApacheBench, Version 2.3 <$Revision: 1004962 $> > Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ > Licensed to The Apache Software Foundation, http://www.apache.org/ > Benchmarking localhost (be patient) > > Server Software: Apache/2.3.12-dev > Server Hostname: localhost > Server Port: 80 > Document Path: /simple.lua > Document Length: 9 bytes > Concurrency Level: 50 > Time taken for tests: 13.310 seconds > Complete requests: 1000 > Failed requests: 0 > Write errors: 0 > Total transferred: 164000 bytes > HTML transferred: 9000 bytes > Requests per second: 75.13 [#/sec] (mean) > Time per request: 665.500 [ms] (mean) > Time per request: 13.310 [ms] (mean, across all concurrent requests) > Transfer rate: 12.03 [Kbytes/sec] received > Connection Times (ms) > min mean[+/-sd] median max > Connect: 0 1 0.5 1 5 > Processing: 89 662 1946.3 213 9253 > Waiting: 89 658 1938.1 212 9236 > Total: 90 662 1946.3 214 9253 > Percentage of the requests served within a certain time (ms) > 50% 214 > 66% 221 > 75% 228 > 80% 235 > 90% 274 > 95% 9012 > 98% 9147 > 99% 9152 > 100% 9253 (longest request) > mod_lua updated, Lua_Scope is once > ----------------------------------------------------------------------- > This is ApacheBench, Version 2.3 <$Revision: 1004962 $> > Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ > Licensed to The Apache Software Foundation, http://www.apache.org/ > Benchmarking localhost (be patient) > > Server Software: Apache/2.3.12-dev > Server Hostname: localhost > Server Port: 80 > Document Path: /simple.lua > Document Length: 9 bytes > Concurrency Level: 50 > Time taken for tests: 4.393 seconds > Complete requests: 1000 > Failed requests: 0 > Write errors: 0 > Total transferred: 164000 bytes > HTML transferred: 9000 bytes > Requests per second: 227.63 [#/sec] (mean) > Time per request: 219.650 [ms] (mean) > Time per request: 4.393 [ms] (mean, across all concurrent requests) > Transfer rate: 36.46 [Kbytes/sec] received > Connection Times (ms) > min mean[+/-sd] median max > Connect: 0 1 0.9 1 14 > Processing: 58 215 34.1 216 317 > Waiting: 56 210 36.6 214 314 > Total: 59 216 34.1 217 318 > Percentage of the requests served within a certain time (ms) > 50% 217 > 66% 227 > 75% 235 > 80% 240 > 90% 251 > 95% 265 > 98% 282 > 99% 301 > 100% 318 (longest request) > > mod_lua updated, with Lua_Scope server 10 50 > ---------------------------------------------------------------------- > This is ApacheBench, Version 2.3 <$Revision: 1004962 $> > Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ > Licensed to The Apache Software Foundation, http://www.apache.org/ > Benchmarking localhost (be patient) > > Server Software: Apache/2.3.12-dev > Server Hostname: localhost > Server Port: 80 > Document Path: /simple.lua > Document Length: 9 bytes > Concurrency Level: 50 > Time taken for tests: 3.606 seconds > Complete requests: 1000 > Failed requests: 0 > Write errors: 0 > Total transferred: 164000 bytes > HTML transferred: 9000 bytes > Requests per second: 277.32 [#/sec] (mean) > Time per request: 180.300 [ms] (mean) > Time per request: 3.606 [ms] (mean, across all concurrent requests) > Transfer rate: 44.41 [Kbytes/sec] received > Connection Times (ms) > min mean[+/-sd] median max > Connect: 0 1 0.6 1 7 > Processing: 43 176 24.9 175 272 > Waiting: 36 174 27.3 173 262 > Total: 44 177 24.9 176 272 > Percentage of the requests served within a certain time (ms) > 50% 176 > 66% 184 > 75% 189 > 80% 192 > 90% 201 > 95% 216 > 98% 233 > 99% 242 > 100% 272 (longest request) > ----------------------------------patch > file--------------------------------------------------------- > Index: lua_vmprep.c > =================================================================== > --- lua_vmprep.c (版本 1080084) > +++ lua_vmprep.c (工作副本) > @@ -288,79 +288,141 @@ > > #endif > > -AP_LUA_DECLARE(lua_State*)ap_lua_get_lua_state(apr_pool_t *lifecycle_pool, > - ap_lua_vm_spec *spec, > - apr_array_header_t > *package_paths, > - apr_array_header_t > *package_cpaths, > - ap_lua_state_open_callback > cb, > - void *btn) > +static apr_status_t vm_construct(void **vm, void *params, apr_pool_t > *lifecycle_pool) > { > + ap_lua_vm_spec *spec = params; > > - lua_State *L; > - > - if (!apr_pool_userdata_get((void **) &L, spec->file, lifecycle_pool)) { > - ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, > - "creating lua_State with file %s", spec->file); > - /* not available, so create */ > - L = luaL_newstate(); > + lua_State* L = luaL_newstate(); > #ifdef AP_ENABLE_LUAJIT > - luaopen_jit(L); > + luaopen_jit(L); > #endif > - luaL_openlibs(L); > - if (package_paths) { > - munge_path(L, "path", "?.lua", "./?.lua", lifecycle_pool, > - package_paths, spec->file); > - } > - if (package_cpaths) { > - munge_path(L, "cpath", "?.so", "./?.so", lifecycle_pool, > - package_cpaths, spec->file); > - } > + luaL_openlibs(L); > + if (spec->package_paths) { > + munge_path(L, "path", "?.lua", "./?.lua", lifecycle_pool, > + spec->package_paths, spec->file); > + } > + if (spec->package_cpaths) { > + munge_path(L, "cpath", "?.so", "./?.so", lifecycle_pool, > + spec->package_cpaths, spec->file); > + } > > - if (cb) { > - cb(L, lifecycle_pool, btn); > - } > + if (spec->cb) { > + spec->cb(L, lifecycle_pool, spec->cb_arg); > + } > > - apr_pool_userdata_set(L, spec->file, &cleanup_lua, lifecycle_pool); > > - if (spec->bytecode && spec->bytecode_len > 0) { > - luaL_loadbuffer(L, spec->bytecode, spec->bytecode_len, > spec->file); > - lua_pcall(L, 0, LUA_MULTRET, 0); > - } > - else { > - int rc; > - ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, > - "loading lua file %s", spec->file); > - rc = luaL_loadfile(L, spec->file); > - if (rc != 0) { > - char *err; > - switch (rc) { > - case LUA_ERRSYNTAX: > - err = "syntax error"; > - break; > - case LUA_ERRMEM: > - err = "memory allocation error"; > - break; > - case LUA_ERRFILE: > - err = "error opening or reading file"; > - break; > - default: > - err = "unknown error"; > - break; > - } > - ap_log_perror(APLOG_MARK, APLOG_ERR, 0, lifecycle_pool, > - "Loading lua file %s: %s", > - spec->file, err); > - return NULL; > - } > - lua_pcall(L, 0, LUA_MULTRET, 0); > - } > + if (spec->bytecode && spec->bytecode_len > 0) { > + luaL_loadbuffer(L, spec->bytecode, spec->bytecode_len, spec->file); > + lua_pcall(L, 0, LUA_MULTRET, 0); > + } > + else { > + int rc; > + ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, > + "loading lua file %s", spec->file); > + rc = luaL_loadfile(L, spec->file); > + if (rc != 0) { > + char *err; > + switch (rc) { > + case LUA_ERRSYNTAX: > + err = "syntax error"; > + break; > + case LUA_ERRMEM: > + err = "memory allocation error"; > + break; > + case LUA_ERRFILE: > + err = "error opening or reading file"; > + break; > + default: > + err = "unknown error"; > + break; > + } > + ap_log_perror(APLOG_MARK, APLOG_ERR, 0, lifecycle_pool, > + "Loading lua file %s: %s", > + spec->file, err); > + return APR_EBADF; > + } > + lua_pcall(L, 0, LUA_MULTRET, 0); > + } > > #ifdef AP_ENABLE_LUAJIT > - loadjitmodule(L, lifecycle_pool); > + loadjitmodule(L, lifecycle_pool); > #endif > - lua_pushlightuserdata(L, lifecycle_pool); > - lua_setfield(L, LUA_REGISTRYINDEX, "Apache2.Wombat.pool"); > - } > + lua_pushlightuserdata(L, lifecycle_pool); > + lua_setfield(L, LUA_REGISTRYINDEX, "Apache2.Wombat.pool"); > + *vm = L; > > + return APR_SUCCESS; > +} > + > +static apr_status_t vm_destruct(void *vm, void *params, apr_pool_t *pool) > +{ > + lua_State *L = (lua_State *)vm; > + > + (void*)params; > + (void*)pool; > + > + cleanup_lua(L); > + > + return APR_SUCCESS; > +} > + > +static apr_status_t vm_release(lua_State* vm) > +{ > + apr_reslist_t* reslist; > + lua_pushlightuserdata(vm,vm); > + lua_rawget(vm,LUA_REGISTRYINDEX); > + reslist = (apr_reslist_t*)lua_topointer(vm,-1); > + > + return apr_reslist_release(reslist, vm); > +} > + > +static apr_status_t vm_reslist_destroy(void *data) > +{ > + return apr_reslist_destroy(data); > +} > + > +AP_LUA_DECLARE(lua_State*)ap_lua_get_lua_state(apr_pool_t *lifecycle_pool, > + ap_lua_vm_spec *spec) > +{ > + lua_State *L = NULL; > + > + if (spec->scope == APL_SCOPE_SERVER) { > + apr_reslist_t *reslist; > + > + if (apr_pool_userdata_get(&reslist,"mod_lua",spec->pool)==APR_SUCCESS) { > + if(reslist==NULL) { > + if(apr_reslist_create(&reslist, > + spec->vm_server_pool_min, > + spec->vm_server_pool_max, > + spec->vm_server_pool_max, > + 0, > + vm_construct, > + vm_destruct, > + spec, > + spec->pool)!=APR_SUCCESS) > + return NULL; > + > + apr_pool_userdata_set(reslist, "mod_lua", vm_reslist_destroy, spec->pool); > + } > + apr_reslist_acquire(reslist, &L); > + lua_pushlightuserdata(L, L); > + lua_pushlightuserdata(L, reslist); > + lua_rawset(L,LUA_REGISTRYINDEX); > + apr_pool_userdata_set(L, spec->file, vm_release, lifecycle_pool); > + } > + } else { > + if (apr_pool_userdata_get((void **) &L, spec->file, > lifecycle_pool)==APR_SUCCESS) { > + > + if(L==NULL) { > + ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, > + "creating lua_State with file %s", spec->file); > + /* not available, so create */ > + > + if(!vm_construct(&L, spec, lifecycle_pool)) > + apr_pool_userdata_set(L, spec->file, &cleanup_lua, lifecycle_pool); > + } > + } > + } > + > return L; > } > Index: lua_vmprep.h > =================================================================== > --- lua_vmprep.h (版本 1080084) > +++ lua_vmprep.h (工作副本) > @@ -43,7 +43,24 @@ > #define APL_SCOPE_CONN 3 > #define APL_SCOPE_SERVER 4 > > + > /** > + * the ap_lua_?getvm family of functions is used to create and/or obtain > + * a handle to a lua state. If there is not an extant vm matching the > + * spec then a new one is created. > + */ > +/* lua_State* ap_lua_rgetvm(request_rec *r, ap_lua_vm_spec *spec); */ > + > +/* returns NULL if the spec requires a request scope */ > +/* lua_State* ap_lua_cgetvm(conn_rec *r, ap_lua_vm_spec *spec);*/ > + > +/* returns NULL if the spec requires a request scope or conn scope */ > +/* lua_State* ap_lua_sgetvm(server_rec *r, ap_lua_vm_spec *spec); */ > + > +typedef void (*ap_lua_state_open_callback) (lua_State *L, apr_pool_t *p, > + void *ctx); > + > +/** > * Specification for a lua virtual machine > */ > typedef struct > @@ -61,7 +78,11 @@ > > /* APL_SCOPE_ONCE | APL_SCOPE_REQUEST | APL_SCOPE_CONN | > APL_SCOPE_SERVER */ > int scope; > + unsigned int vm_server_pool_min; > + unsigned int vm_server_pool_max; > > + ap_lua_state_open_callback cb; > + void* cb_arg; > /* pool to use for lifecycle if APL_SCOPE_ONCE is set, otherwise unused > */ > apr_pool_t *pool; > > @@ -102,22 +123,6 @@ > */ > AP_LUA_DECLARE(void) ap_lua_load_apache2_lmodule(lua_State *L); > > -/** > - * the ap_lua_?getvm family of functions is used to create and/or obtain > - * a handle to a lua state. If there is not an extant vm matching the > - * spec then a new one is created. > - */ > -/* lua_State* ap_lua_rgetvm(request_rec *r, ap_lua_vm_spec *spec); */ > - > -/* returns NULL if the spec requires a request scope */ > -/* lua_State* ap_lua_cgetvm(conn_rec *r, ap_lua_vm_spec *spec);*/ > - > -/* returns NULL if the spec requires a request scope or conn scope */ > -/* lua_State* ap_lua_sgetvm(server_rec *r, ap_lua_vm_spec *spec); */ > - > -typedef void (*ap_lua_state_open_callback) (lua_State *L, apr_pool_t *p, > - void *ctx); > - > /* > * alternate means of getting lua_State (preferred eventually) > * Obtain a lua_State which has loaded file and is associated with > lifecycle_pool > @@ -131,11 +136,7 @@ > * @ctx a baton passed to cb > */ > AP_LUA_DECLARE(lua_State*) ap_lua_get_lua_state(apr_pool_t *lifecycle_pool, > - ap_lua_vm_spec *spec, > - apr_array_header_t > *package_paths, > - apr_array_header_t > *package_cpaths, > - ap_lua_state_open_callback > cb, > - void *btn); > + ap_lua_vm_spec *spec); > > > > Index: mod_lua.c > =================================================================== > --- mod_lua.c (版本 1080084) > +++ mod_lua.c (工作副本) > @@ -121,9 +121,15 @@ > d = apr_palloc(r->pool, sizeof(mapped_request_details)); > spec = apr_pcalloc(r->pool, sizeof(ap_lua_vm_spec)); > spec->scope = dcfg->vm_scope; > - spec->pool = r->pool; > + spec->pool = spec->scope==APL_SCOPE_SERVER ? cfg->pool : r->pool; > spec->file = r->filename; > spec->code_cache_style = dcfg->code_cache_style; > + spec->package_paths = cfg->package_paths; > + spec->package_cpaths = cfg->package_cpaths; > + spec->vm_server_pool_min = cfg->vm_server_pool_min; > + spec->vm_server_pool_max = cfg->vm_server_pool_max; > + spec->cb = &lua_open_callback; > + spec->cb_arg = NULL; > d->spec = spec; > d->function_name = "handle"; > } > @@ -135,10 +141,7 @@ > d->spec->file, > d->function_name); > L = ap_lua_get_lua_state(r->pool, > - d->spec, > - cfg->package_paths, > - cfg->package_cpaths, > - &lua_open_callback, NULL); > + d->spec); > > if (!L) { > /* TODO annotate spec with failure reason */ > @@ -246,17 +249,20 @@ > spec->file = hook_spec->file_name; > spec->code_cache_style = hook_spec->code_cache_style; > spec->scope = hook_spec->scope; > + spec->vm_server_pool_min = cfg->vm_server_pool_min; > + spec->vm_server_pool_max = cfg->vm_server_pool_max; > spec->bytecode = hook_spec->bytecode; > spec->bytecode_len = hook_spec->bytecode_len; > - spec->pool = r->pool; > + spec->pool = spec->scope==APL_SCOPE_SERVER ? cfg->pool : > r->pool; > + spec->package_paths = cfg->package_paths; > + spec->package_cpaths = cfg->package_cpaths; > + spec->cb = &lua_open_callback; > + spec->cb_arg = NULL; > > apr_filepath_merge(&spec->file, server_cfg->root_path, > spec->file, APR_FILEPATH_NOTRELATIVE, > r->pool); > L = ap_lua_get_lua_state(r->pool, > - spec, > - cfg->package_paths, > - cfg->package_cpaths, > - &lua_open_callback, NULL); > + spec); > > > >