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);

Reply via email to