Configure mod_mem_cache to cache files in mem, set CacheExpiresMax 1 then turn ab loose fetching a single
cachable static file and watch what happens. You get exploding memory usage in the subprocess_env serialized
headers.
The initial cache load caches whatever is in subprocess_env. On the next request, mod_cache discovers that
the cache entry is stale, but by the time it has figured out that it needs to DECLINE the request, it has
replaced r-subprocess_env with what was in the stale cache entry. Whatever is in the subprocess_env table
when the quick handler DECLINES stays there and new entries are added by Apache during normal (uncached) file
handling. The result is that when the cache_in_filter is run to cache the new response, subprocess_env
contains the values out of the stale cache entry -and- the new values added by default_handling. When the new
cache entry becomes stale, the cycle starts again and sunprocess_env grows more.
I really don't have much time to pursue this so here is a patch that:
1. saves some tables of interest from the request_rec at entry to the cache_handler. These value are restored
if the cache_handler DECLINES
2. Hacks out a bunch of code that I cannot quite grok and that I am pretty sure is causing more problems that
it is solving.
mod_cache needs some serious work before it is ready to come out of experimental.
Bill
RCS file: /cvs/phoenix/2.0.47/modules/experimental/mod_cache.c,v
retrieving revision 1.2
diff -u -r1.2 mod_cache.c
--- mod_cache.c 5 Mar 2004 02:33:46 - 1.2
+++ mod_cache.c 6 Mar 2004 21:11:23 -
@@ -57,6 +57,12 @@
cache_info *info = NULL;
cache_request_rec *cache;
cache_server_conf *conf;
+/* Hack till we come up with a better solution */
+
+apr_table_t *err_headers_out = r-err_headers_out;
+apr_table_t *notes = r-notes;
+apr_table_t *subprocess_env = r-subprocess_env;
+apr_table_t *headers_out = r-headers_out;
conf = (cache_server_conf *) ap_get_module_config(r-server-module_config,
cache_module);
@@ -151,18 +157,7 @@
*/
rv = cache_select_url(r, cache-types, url);
-if (DECLINED == rv) {
-if (!lookup) {
-/* no existing cache file */
-ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r-server,
- cache: no cache - add cache_in filter and DECLINE);
-/* add cache_in filter to cache this request */
-ap_add_output_filter_handle(cache_in_filter_handle, NULL, r,
-r-connection);
-}
-return DECLINED;
-}
-else if (OK == rv) {
+if (OK == rv) {
/* RFC2616 13.2 - Check cache object expiration */
cache-fresh = ap_cache_check_freshness(cache, r);
if (cache-fresh) {
@@ -174,127 +169,69 @@
return OK;
}
rv = ap_meets_conditions(r);
-if (rv != OK) {
+if (rv == OK) {
+/* Meets conditions or is not conditional */
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r-server,
- cache: fresh cache - returning status %d, rv);
-return rv;
-}
+ cache: fresh cache - add cache_out filter and
+ handle request);
-/*
- * Not a conditionl request. Serve up the content
- */
-ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r-server,
- cache: fresh cache - add cache_out filter and
- handle request);
+/* We are in the quick handler hook, which means that no output
+ * filters have been set. So lets run the insert_filter hook.
+ */
+ap_run_insert_filter(r);
+ap_add_output_filter_handle(cache_out_filter_handle, NULL,
+r, r-connection);
-/* We are in the quick handler hook, which means that no output
- * filters have been set. So lets run the insert_filter hook.
- */
-ap_run_insert_filter(r);
-ap_add_output_filter_handle(cache_out_filter_handle, NULL,
-r, r-connection);
-
-/* kick off the filter stack */
-out = apr_brigade_create(r-pool, c-bucket_alloc);
-if (APR_SUCCESS
-!= (rv = ap_pass_brigade(r-output_filters, out))) {
-ap_log_error(APLOG_MARK, APLOG_ERR, rv, r-server,
- cache: error returned while trying to return %s
- cached data,
- cache-type);
-return rv;
+/* kick off the filter stack */
+out = apr_brigade_create(r-pool, c-bucket_alloc);
+rv =