3333 * */
3434static ngx_int_t
3535ngx_http_lua_cache_load_code (ngx_log_t * log , lua_State * L ,
36- const char * key )
36+ int * ref , const char * key )
3737{
3838#ifndef OPENRESTY_LUAJIT
3939 int rc ;
@@ -45,16 +45,45 @@ ngx_http_lua_cache_load_code(ngx_log_t *log, lua_State *L,
4545 code_cache_key ));
4646 lua_rawget (L , LUA_REGISTRYINDEX ); /* sp++ */
4747
48- dd ("Code cache table to load: %p" , lua_topointer (L , -1 ));
48+ ngx_log_debug2 (NGX_LOG_DEBUG_HTTP , log , 0 ,
49+ "code cache lookup (key='%s', ref=%d)" , key , * ref );
50+
51+ dd ("code cache table to load: %p" , lua_topointer (L , -1 ));
4952
5053 if (!lua_istable (L , -1 )) {
5154 dd ("Error: code cache table to load did not exist!!" );
5255 return NGX_ERROR ;
5356 }
5457
55- lua_getfield (L , -1 , key ); /* sp++ */
58+ ngx_http_lua_assert (key != NULL );
59+
60+ if (* ref == LUA_NOREF ) {
61+ lua_getfield (L , -1 , key ); /* cache closure */
62+
63+ } else {
64+ if (* ref == LUA_REFNIL ) {
65+ lua_getfield (L , -1 , key ); /* cache ref */
66+
67+ if (!lua_isnumber (L , -1 )) {
68+ goto not_found ;
69+ }
70+
71+ * ref = lua_tonumber (L , -1 );
72+
73+ ngx_log_debug2 (NGX_LOG_DEBUG_HTTP , log , 0 ,
74+ "code cache setting ref (key='%s', ref=%d)" ,
75+ key , * ref );
76+
77+ lua_pop (L , 1 ); /* cache */
78+ }
79+
80+ lua_rawgeti (L , -1 , * ref ); /* cache closure */
81+ }
5682
5783 if (lua_isfunction (L , -1 )) {
84+ ngx_log_debug2 (NGX_LOG_DEBUG_HTTP , log , 0 ,
85+ "code cache hit (key='%s', ref=%d)" , key , * ref );
86+
5887#ifdef OPENRESTY_LUAJIT
5988 lua_remove (L , -2 ); /* sp-- */
6089 return NGX_OK ;
@@ -83,13 +112,18 @@ ngx_http_lua_cache_load_code(ngx_log_t *log, lua_State *L,
83112#endif /* OPENRESTY_LUAJIT */
84113 }
85114
115+ not_found :
116+
86117 dd ("Value associated with given key in code cache table is not code "
87118 "chunk: stack top=%d, top value type=%s\n" ,
88119 lua_gettop (L ), lua_typename (L , -1 ));
89120
90121 /* remove cache table and value from stack */
91122 lua_pop (L , 2 ); /* sp-=2 */
92123
124+ ngx_log_debug2 (NGX_LOG_DEBUG_HTTP , log , 0 ,
125+ "code cache miss (key='%s', ref=%d)" , key , * ref );
126+
93127 return NGX_DECLINED ;
94128}
95129
@@ -108,7 +142,7 @@ ngx_http_lua_cache_load_code(ngx_log_t *log, lua_State *L,
108142 *
109143 * */
110144static ngx_int_t
111- ngx_http_lua_cache_store_code (lua_State * L , const char * key )
145+ ngx_http_lua_cache_store_code (lua_State * L , int * ref , const char * key )
112146{
113147#ifndef OPENRESTY_LUAJIT
114148 int rc ;
@@ -126,8 +160,22 @@ ngx_http_lua_cache_store_code(lua_State *L, const char *key)
126160 return NGX_ERROR ;
127161 }
128162
163+ ngx_http_lua_assert (key != NULL );
164+
129165 lua_pushvalue (L , -2 ); /* closure cache closure */
130- lua_setfield (L , -2 , key ); /* closure cache */
166+
167+ if (* ref == LUA_NOREF ) {
168+ /* cache closure by cache key */
169+ lua_setfield (L , -2 , key ); /* closure cache */
170+
171+ } else {
172+ /* cache closure with reference */
173+ * ref = luaL_ref (L , -2 ); /* closure cache */
174+
175+ /* cache reference by cache key */
176+ lua_pushnumber (L , * ref ); /* closure cache ref */
177+ lua_setfield (L , -2 , key ); /* closure cache */
178+ }
131179
132180 /* remove cache table, leave closure factory at top of stack */
133181 lua_pop (L , 1 ); /* closure */
@@ -147,7 +195,7 @@ ngx_http_lua_cache_store_code(lua_State *L, const char *key)
147195
148196ngx_int_t
149197ngx_http_lua_cache_loadbuffer (ngx_log_t * log , lua_State * L ,
150- const u_char * src , size_t src_len , const u_char * cache_key ,
198+ const u_char * src , size_t src_len , int * cache_ref , const u_char * cache_key ,
151199 const char * name )
152200{
153201 int n ;
@@ -156,14 +204,8 @@ ngx_http_lua_cache_loadbuffer(ngx_log_t *log, lua_State *L,
156204
157205 n = lua_gettop (L );
158206
159- ngx_log_debug1 (NGX_LOG_DEBUG_HTTP , log , 0 ,
160- "looking up Lua code cache with key '%s'" , cache_key );
161-
162- rc = ngx_http_lua_cache_load_code (log , L , (char * ) cache_key );
207+ rc = ngx_http_lua_cache_load_code (log , L , cache_ref , (char * ) cache_key );
163208 if (rc == NGX_OK ) {
164- /* code chunk loaded from cache, sp++ */
165- dd ("Code cache hit! cache key='%s', stack top=%d, script='%.*s'" ,
166- cache_key , lua_gettop (L ), (int ) src_len , src );
167209 return NGX_OK ;
168210 }
169211
@@ -173,9 +215,6 @@ ngx_http_lua_cache_loadbuffer(ngx_log_t *log, lua_State *L,
173215
174216 /* rc == NGX_DECLINED */
175217
176- dd ("Code cache missed! cache key='%s', stack top=%d, script='%.*s'" ,
177- cache_key , lua_gettop (L ), (int ) src_len , src );
178-
179218 /* load closure factory of inline script to the top of lua stack, sp++ */
180219 rc = ngx_http_lua_clfactory_loadbuffer (L , (char * ) src , src_len , name );
181220
@@ -198,7 +237,7 @@ ngx_http_lua_cache_loadbuffer(ngx_log_t *log, lua_State *L,
198237
199238 /* store closure factory and gen new closure at the top of lua stack to
200239 * code cache */
201- rc = ngx_http_lua_cache_store_code (L , (char * ) cache_key );
240+ rc = ngx_http_lua_cache_store_code (L , cache_ref , (char * ) cache_key );
202241 if (rc != NGX_OK ) {
203242 err = "fail to generate new closure from the closure factory" ;
204243 goto error ;
@@ -217,7 +256,7 @@ ngx_http_lua_cache_loadbuffer(ngx_log_t *log, lua_State *L,
217256
218257ngx_int_t
219258ngx_http_lua_cache_loadfile (ngx_log_t * log , lua_State * L ,
220- const u_char * script , const u_char * cache_key )
259+ const u_char * script , int * cache_ref , const u_char * cache_key )
221260{
222261 int n ;
223262 ngx_int_t rc , errcode = NGX_ERROR ;
@@ -230,25 +269,22 @@ ngx_http_lua_cache_loadfile(ngx_log_t *log, lua_State *L,
230269 /* calculate digest of script file path */
231270 if (cache_key == NULL ) {
232271 dd ("CACHE file key not pre-calculated...calculating" );
233- p = ngx_copy (buf , NGX_HTTP_LUA_FILE_TAG , NGX_HTTP_LUA_FILE_TAG_LEN );
234272
273+ p = ngx_copy (buf , NGX_HTTP_LUA_FILE_TAG , NGX_HTTP_LUA_FILE_TAG_LEN );
235274 p = ngx_http_lua_digest_hex (p , script , ngx_strlen (script ));
236-
237275 * p = '\0' ;
276+
238277 cache_key = buf ;
278+ * cache_ref = LUA_NOREF ;
239279
240280 } else {
241281 dd ("CACHE file key already pre-calculated" );
242- }
243282
244- ngx_log_debug1 ( NGX_LOG_DEBUG_HTTP , log , 0 ,
245- "looking up Lua code cache with key '%s'" , cache_key );
283+ ngx_http_lua_assert ( cache_ref != NULL && * cache_ref != LUA_NOREF );
284+ }
246285
247- rc = ngx_http_lua_cache_load_code (log , L , (char * ) cache_key );
286+ rc = ngx_http_lua_cache_load_code (log , L , cache_ref , (char * ) cache_key );
248287 if (rc == NGX_OK ) {
249- /* code chunk loaded from cache, sp++ */
250- dd ("Code cache hit! cache key='%s', stack top=%d, file path='%s'" ,
251- cache_key , lua_gettop (L ), script );
252288 return NGX_OK ;
253289 }
254290
@@ -258,9 +294,6 @@ ngx_http_lua_cache_loadfile(ngx_log_t *log, lua_State *L,
258294
259295 /* rc == NGX_DECLINED */
260296
261- dd ("Code cache missed! cache key='%s', stack top=%d, file path='%s'" ,
262- cache_key , lua_gettop (L ), script );
263-
264297 /* load closure factory of script file to the top of lua stack, sp++ */
265298 rc = ngx_http_lua_clfactory_loadfile (L , (char * ) script );
266299
@@ -291,7 +324,7 @@ ngx_http_lua_cache_loadfile(ngx_log_t *log, lua_State *L,
291324
292325 /* store closure factory and gen new closure at the top of lua stack
293326 * to code cache */
294- rc = ngx_http_lua_cache_store_code (L , (char * ) cache_key );
327+ rc = ngx_http_lua_cache_store_code (L , cache_ref , (char * ) cache_key );
295328 if (rc != NGX_OK ) {
296329 err = "fail to generate new closure from the closure factory" ;
297330 goto error ;
0 commit comments