--------------------- PatchSet 5792 Date: 2003/06/21 12:50:00 Author: hno Branch: collapsed_forwarding-2_5 Tag: (none) Log: collapsed_forwarding directive to collaps multiple requests or for the same object into a single request to the backend server. Intended to be used in accelerator setups. This also includes the functionality of the log_access branch, plus new acl options in the access_log directive. Members: src/cf.data.pre:1.49.2.40->1.49.2.40.4.1 src/client_side.c:1.47.2.31->1.47.2.31.4.1 src/http.c:1.17.6.5->1.17.6.5.4.1 src/store.c:1.16.6.2->1.16.6.2.6.1 src/structs.h:1.48.2.11->1.48.2.11.4.1 Index: squid/src/cf.data.pre =================================================================== RCS file: /cvsroot/squid-sf//squid/src/cf.data.pre,v retrieving revision 1.49.2.40 retrieving revision 1.49.2.40.4.1 diff -u -r1.49.2.40 -r1.49.2.40.4.1 --- squid/src/cf.data.pre 20 Jun 2003 02:14:11 -0000 1.49.2.40 +++ squid/src/cf.data.pre 21 Jun 2003 12:50:00 -0000 1.49.2.40.4.1 @@ -1,6 +1,6 @@ # -# $Id: cf.data.pre,v 1.49.2.40 2003/06/20 02:14:11 squidadm Exp $ +# $Id: cf.data.pre,v 1.49.2.40.4.1 2003/06/21 12:50:00 hno Exp $ # # # SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -1739,6 +1739,30 @@ client requested. (default) DOC_END +NAME: collapsed_forwarding +COMMENT: (on|off) +TYPE: onoff +LOC: Config.onoff.collapsed_forwarding +DEFAULT: off +DOC_START + This option enables collaps of multiple requests for the same URI + to be processed as one request. Normally disabled to avoid corner + cases with hung requests, but there can be large benefit from + enabling this in accelerator setups where the web servers are + reliable. +DOC_END + +NAME: collapsed_forwarding_stale_hit +COMMENT: (on|off) +TYPE: onoff +LOC: Config.onoff.collapsed_forwarding_stale +DEFAULT: off +DOC_START + This option decreases latency on collapsed forwarding by + having the second/third/... concurrent request for a stale object + return the stale information directly, assuming it won't have + changed. +DOC_END COMMENT_START TIMEOUTS Index: squid/src/client_side.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/client_side.c,v retrieving revision 1.47.2.31 retrieving revision 1.47.2.31.4.1 diff -u -r1.47.2.31 -r1.47.2.31.4.1 --- squid/src/client_side.c 25 May 2003 02:15:08 -0000 1.47.2.31 +++ squid/src/client_side.c 21 Jun 2003 12:50:01 -0000 1.47.2.31.4.1 @@ -1,6 +1,6 @@ /* - * $Id: client_side.c,v 1.47.2.31 2003/05/25 02:15:08 squidadm Exp $ + * $Id: client_side.c,v 1.47.2.31.4.1 2003/06/21 12:50:01 hno Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -372,6 +372,7 @@ clientHttpRequest *http = data; char *url = http->uri; StoreEntry *entry = NULL; + int hit = 0; debug(33, 3) ("clientProcessExpired: '%s'\n", http->uri); assert(http->entry->lastmod >= 0); /* @@ -386,30 +387,37 @@ http->request->flags.refresh = 1; http->old_entry = http->entry; http->old_sc = http->sc; + http->request->lastmod = http->old_entry->lastmod; + debug(33, 5) ("clientProcessExpired: lastmod %ld\n", (long int) entry->lastmod); /* * Assert that 'http' is already a client of old_entry. If * it is not, then the beginning of the object data might get * freed from memory before we need to access it. */ assert(http->sc->callback_data == http); - entry = storeCreateEntry(url, - http->log_uri, - http->request->flags, - http->request->method); + if (http->entry->mem_obj && http->entry->mem_obj->ims_entry) { + entry = http->entry->mem_obj->ims_entry; + storeLockObject(entry); + hit = 1; + } + if (!entry) { + entry = storeCreateEntry(url, + http->log_uri, + http->request->flags, + http->request->method); + if (Config.onoff.collapsed_forwarding && http->entry->mem_obj) { + http->entry->mem_obj->ims_entry = entry; + storeLockObject(http->entry->mem_obj->ims_entry); + } + } /* NOTE, don't call storeLockObject(), storeCreateEntry() does it */ http->sc = storeClientListAdd(entry, http); #if DELAY_POOLS /* delay_id is already set on original store client */ delaySetStoreClient(http->sc, delayClient(http)); #endif - http->request->lastmod = http->old_entry->lastmod; - debug(33, 5) ("clientProcessExpired: lastmod %ld\n", (long int) entry->lastmod); http->entry = entry; http->out.offset = 0; - fwdStart(http->conn->fd, http->entry, http->request); - /* Register with storage manager to receive updates when data comes in. */ - if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) - debug(33, 0) ("clientProcessExpired: found ENTRY_ABORTED object\n"); storeClientCopy(http->sc, entry, http->out.offset, http->out.offset, @@ -417,6 +425,8 @@ memAllocate(MEM_CLIENT_SOCK_BUF), clientHandleIMSReply, http); + if (!hit) + fwdStart(http->conn->fd, http->entry, http->request); } static int @@ -550,6 +560,10 @@ } http->old_entry = NULL; /* done with old_entry */ http->old_sc = NULL; + if (entry->mem_obj && entry->mem_obj->ims_entry) { + storeUnlockObject(entry->mem_obj->ims_entry); + entry->mem_obj->ims_entry = NULL; + } assert(!EBIT_TEST(entry->flags, ENTRY_ABORTED)); if (recopy) { storeClientCopy(http->sc, entry, @@ -841,6 +855,10 @@ safe_free(http->al.cache.authuser); safe_free(http->redirect.location); stringClean(&http->range_iter.boundary); + if (http->old_entry && http->old_entry->mem_obj && http->old_entry->mem_obj->ims_entry && http->old_entry->mem_obj->ims_entry == http->entry) { + storeUnlockObject(http->old_entry->mem_obj->ims_entry); + http->old_entry->mem_obj->ims_entry = NULL; + } if ((e = http->entry)) { http->entry = NULL; storeUnregister(http->sc, e, http); @@ -1461,6 +1479,19 @@ memFree(buf, MEM_CLIENT_SOCK_BUF); debug(33, 3) ("clientCacheHit: request aborted\n"); return; + } else if (EBIT_TEST(e->flags, KEY_PRIVATE)) { + /* This is not a cache hit */ + memFree(buf, MEM_CLIENT_SOCK_BUF); + debug(33, 3) ("clientCacheHit: late cache miss detected\n"); + http->log_type = LOG_TCP_MISS; + if ((e = http->entry)) { + http->entry = NULL; + storeUnregister(http->sc, e, http); + http->sc = NULL; + storeUnlockObject(e); + } + clientProcessMiss(http); + return; } else if (size < 0) { /* swap in failure */ memFree(buf, MEM_CLIENT_SOCK_BUF); @@ -1547,7 +1578,10 @@ if (checkNegativeHit(e)) { http->log_type = LOG_TCP_NEGATIVE_HIT; clientSendMoreData(data, buf, size); - } else if (r->method == METHOD_HEAD) { + return; + } +#if THIS_IS_FALSE + if (r->method == METHOD_HEAD) { /* * RFC 2068 seems to indicate there is no "conditional HEAD" * request. We cannot validate a cached object for a HEAD @@ -1556,7 +1590,13 @@ if (e->mem_status == IN_MEMORY) http->log_type = LOG_TCP_MEM_HIT; clientSendMoreData(data, buf, size); - } else if (!Config.onoff.offline && refreshCheckHTTP(e, r) && !http->flags.internal) { + return; + } +#endif + if (Config.onoff.collapsed_forwarding_stale && e->mem_obj && e->mem_obj->ims_entry) { + goto hit; + } + if (!Config.onoff.offline && refreshCheckHTTP(e, r) && !http->flags.internal) { debug(33, 5) ("clientCacheHit: in refreshCheck() block\n"); /* * We hold a stale copy; it needs to be validated @@ -1599,7 +1639,10 @@ clientProcessMiss(http); } memFree(buf, MEM_CLIENT_SOCK_BUF); - } else if (r->flags.ims) { + return; + } +hit: + if (r->flags.ims) { /* * Handle If-Modified-Since requests from the client */ @@ -1632,16 +1675,16 @@ memBufClean(&mb); storeComplete(e); } - } else { - /* - * plain ol' cache hit - */ - if (e->mem_status == IN_MEMORY) - http->log_type = LOG_TCP_MEM_HIT; - else if (Config.onoff.offline) - http->log_type = LOG_TCP_OFFLINE_HIT; - clientSendMoreData(data, buf, size); + return; } + /* + * plain ol' cache hit + */ + if (e->mem_status == IN_MEMORY) + http->log_type = LOG_TCP_MEM_HIT; + else if (Config.onoff.offline) + http->log_type = LOG_TCP_OFFLINE_HIT; + clientSendMoreData(data, buf, size); } /* put terminating boundary for multiparts */ @@ -2470,6 +2513,8 @@ } assert(http->out.offset == 0); http->entry = clientCreateStoreEntry(http, r->method, r->flags); + if (Config.onoff.collapsed_forwarding && r->flags.cachable && (r->method = METHOD_GET || r->method == METHOD_HEAD)) + storeSetPublicKey(http->entry); if (http->redirect.status) { HttpReply *rep = httpReplyCreate(); #if LOG_TCP_REDIRECTS Index: squid/src/http.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/http.c,v retrieving revision 1.17.6.5 retrieving revision 1.17.6.5.4.1 diff -u -r1.17.6.5 -r1.17.6.5.4.1 --- squid/src/http.c 20 Jun 2003 02:14:11 -0000 1.17.6.5 +++ squid/src/http.c 21 Jun 2003 12:50:01 -0000 1.17.6.5.4.1 @@ -1,6 +1,6 @@ /* - * $Id: http.c,v 1.17.6.5 2003/06/20 02:14:11 squidadm Exp $ + * $Id: http.c,v 1.17.6.5.4.1 2003/06/21 12:50:01 hno Exp $ * * DEBUG: section 11 Hypertext Transfer Protocol (HTTP) * AUTHOR: Harvest Derived @@ -426,7 +426,7 @@ storeTimestampsSet(entry); /* Check if object is cacheable or not based on reply code */ debug(11, 3) ("httpProcessReplyHeader: HTTP CODE: %d\n", reply->sline.status); - if (neighbors_do_private_keys) + if (neighbors_do_private_keys && !Config.onoff.collapsed_forwarding) httpMaybeRemovePublic(entry, reply->sline.status); switch (httpCachableReply(httpState)) { case 1: Index: squid/src/store.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/store.c,v retrieving revision 1.16.6.2 retrieving revision 1.16.6.2.6.1 diff -u -r1.16.6.2 -r1.16.6.2.6.1 --- squid/src/store.c 1 Feb 2003 03:15:49 -0000 1.16.6.2 +++ squid/src/store.c 21 Jun 2003 12:50:01 -0000 1.16.6.2.6.1 @@ -1,6 +1,6 @@ /* - * $Id: store.c,v 1.16.6.2 2003/02/01 03:15:49 squidadm Exp $ + * $Id: store.c,v 1.16.6.2.6.1 2003/06/21 12:50:01 hno Exp $ * * DEBUG: section 20 Storage Manager * AUTHOR: Harvest Derived @@ -160,6 +160,10 @@ * still have mem->clients set if mem->fd == -1 */ assert(mem->fd == -1 || mem->clients.head == NULL); + if (mem->ims_entry) { + storeUnlockObject(mem->ims_entry); + mem->ims_entry = NULL; + } httpReplyDestroy(mem->reply); requestUnlink(mem->request); mem->request = NULL; Index: squid/src/structs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/structs.h,v retrieving revision 1.48.2.11 retrieving revision 1.48.2.11.4.1 diff -u -r1.48.2.11 -r1.48.2.11.4.1 --- squid/src/structs.h 11 May 2003 03:13:50 -0000 1.48.2.11 +++ squid/src/structs.h 21 Jun 2003 12:50:01 -0000 1.48.2.11.4.1 @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.48.2.11 2003/05/11 03:13:50 squidadm Exp $ + * $Id: structs.h,v 1.48.2.11.4.1 2003/06/21 12:50:01 hno Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -592,6 +592,8 @@ int vary_ignore_expire; int pipeline_prefetch; int request_entities; + int collapsed_forwarding; + int collapsed_forwarding_stale; } onoff; acl *aclList; struct { @@ -1507,6 +1509,7 @@ unsigned int chksum; #endif const char *vary_headers; + StoreEntry *ims_entry; }; struct _StoreEntry {