This is an automated email from the ASF dual-hosted git repository. cmcfarlen pushed a commit to branch 10.1.x in repository https://gitbox.apache.org/repos/asf/trafficserver.git
commit 2114e15d4054738578ee3193ba5612c9d22a2444 Author: Masaori Koshiba <[email protected]> AuthorDate: Fri Jun 6 00:56:41 2025 +0900 Serve stale contents until max-age + max_stale_age (#12241) * Serve stale contents until max-age + max_stale_age * Adjust AuTest * Clarify comments in AuTest (cherry picked from commit 9c1d1aa437a8796edd952dfc21cb86f34cf026c3) --- doc/admin-guide/files/records.yaml.en.rst | 6 ++--- src/proxy/http/HttpTransact.cc | 2 +- .../negative-revalidating-enabled.replay.yaml | 16 ++++++------ .../replay/negative-revalidating-list.replay.yaml | 7 +++--- .../proxy_serve_stale_dns_fail.test.py | 4 +-- .../replay/proxy_serve_stale.replay.yaml | 29 +++++++++++++++++++--- 6 files changed, 41 insertions(+), 23 deletions(-) diff --git a/doc/admin-guide/files/records.yaml.en.rst b/doc/admin-guide/files/records.yaml.en.rst index 7596741621..4d4a507b0d 100644 --- a/doc/admin-guide/files/records.yaml.en.rst +++ b/doc/admin-guide/files/records.yaml.en.rst @@ -1900,7 +1900,7 @@ Negative Response Caching already cached content. A revalidation failure means a connection failure or a 50x response code. When considering replying with a stale response in these negative revalidating circumstances, |TS| will respect the :ts:cv:`proxy.config.http.cache.max_stale_age` configuration and will not - use a cached response older than ``max_stale_age`` seconds. + use a cached response older than ``max_stale_age`` seconds plus ``max-age`` of cached content. A value of ``0`` disables serving stale content and a value of ``1`` enables keeping and serving stale content if revalidation fails. @@ -2740,11 +2740,11 @@ Dynamic Content & Content Negotiation ===== ====================================================================== ``0`` Default. Disable cache and go to origin server. ``1`` Return a ``502`` error on a cache miss. - ``2`` Serve stale if object's age is under + ``2`` Serve stale if object's age is under ``max-age`` + :ts:cv:`proxy.config.http.cache.max_stale_age`. Otherwise, go to origin server. ``3`` Return a ``502`` error on a cache miss or serve stale on a cache - revalidate if object's age is under + revalidate if object's age is under ``max-age`` + :ts:cv:`proxy.config.http.cache.max_stale_age`. Otherwise, go to origin server. ``4`` Return a ``502`` error on either a cache miss or on a revalidation. diff --git a/src/proxy/http/HttpTransact.cc b/src/proxy/http/HttpTransact.cc index 2a0bab4cb9..4c146a6f97 100644 --- a/src/proxy/http/HttpTransact.cc +++ b/src/proxy/http/HttpTransact.cc @@ -5970,7 +5970,7 @@ HttpTransact::is_stale_cache_response_returnable(State *s) s->cache_info.object_read->response_received_time_get(), cached_response, cached_response->get_date(), s->current.now); // Negative age is overflow - if ((current_age < 0) || (current_age > s->txn_conf->cache_max_stale_age)) { + if ((current_age < 0) || (current_age > s->txn_conf->cache_max_stale_age + get_max_age(cached_response))) { TxnDbg(dbg_ctl_http_trans, "document age is too large %" PRId64, (int64_t)current_age); return false; } diff --git a/tests/gold_tests/cache/replay/negative-revalidating-enabled.replay.yaml b/tests/gold_tests/cache/replay/negative-revalidating-enabled.replay.yaml index b4b45a4b39..4b320767bf 100644 --- a/tests/gold_tests/cache/replay/negative-revalidating-enabled.replay.yaml +++ b/tests/gold_tests/cache/replay/negative-revalidating-enabled.replay.yaml @@ -78,7 +78,7 @@ sessions: status: 200 # Verify that with negative_revalidating enabled, we serve the 200 OK out of - # the cache even though it is stale (but younger than max_stale_age). + # the cache even though it is stale (but younger than max-age + max_stale_age). - client-request: method: "GET" version: "1.1" @@ -115,10 +115,9 @@ sessions: - [ Host, example.com ] - [ uuid, 14 ] - # After this delay, the item is 8 seconds old. This makes it: - # 6 seconds beyond the server's max-age of 2 seconds and - # 2 seconds beyond ATS's max_stale_age of 6 seconds. - delay: 4s + # After this delay, the item is 10 seconds old. This is 2 seconds beyond + # the server's max-age of 2 seconds + ATS's max_stale_age of 6 seconds. + delay: 6s server-response: status: 503 @@ -221,10 +220,9 @@ sessions: - [ Host, example.com ] - [ uuid, 24 ] - # After this delay, the item is 8 seconds old. This makes it: - # 6 seconds beyond the server's max-age of 2 seconds and - # 2 seconds beyond ATS's max_stale_age of 6 seconds. - delay: 4s + # After this delay, the item is 10 seconds old. This is 2 seconds beyond + # the server's max-age of 2 seconds + ATS's max_stale_age of 6 seconds. + delay: 6s server-response: status: 503 diff --git a/tests/gold_tests/cache/replay/negative-revalidating-list.replay.yaml b/tests/gold_tests/cache/replay/negative-revalidating-list.replay.yaml index 8b757b94d2..f95dab2d93 100644 --- a/tests/gold_tests/cache/replay/negative-revalidating-list.replay.yaml +++ b/tests/gold_tests/cache/replay/negative-revalidating-list.replay.yaml @@ -132,10 +132,9 @@ sessions: - [ Host, example.com ] - [ uuid, 35 ] - # After this delay, the item is 8 seconds old. This makes it: - # 6 seconds beyond the server's max-age of 2 seconds and - # 2 seconds beyond ATS's max_stale_age of 6 seconds. - delay: 4s + # After this delay, the item is 10 seconds old. This is 2 seconds beyond + # the server's max-age of 2 seconds + ATS's max_stale_age of 6 seconds. + delay: 6s server-response: status: 503 diff --git a/tests/gold_tests/proxy_protocol/proxy_serve_stale_dns_fail.test.py b/tests/gold_tests/proxy_protocol/proxy_serve_stale_dns_fail.test.py index e3ddd17f5e..07235ed4c3 100644 --- a/tests/gold_tests/proxy_protocol/proxy_serve_stale_dns_fail.test.py +++ b/tests/gold_tests/proxy_protocol/proxy_serve_stale_dns_fail.test.py @@ -63,11 +63,11 @@ child_curl_request = ( f'{{curl}} -X PUSH -d "{stale_5}" "http://localhost:{ts_child.Variables.port}";' f'{{curl}} -X PUSH -d "{stale_10}" "http://localhost:{ts_parent.Variables.port}";' f'sleep 7; {{curl}} -s -v http://localhost:{ts_child.Variables.port};' - f'sleep 15; {{curl}} -s -v http://localhost:{ts_child.Variables.port};' + f'sleep 17; {{curl}} -s -v http://localhost:{ts_child.Variables.port};' # Test parent serving stale with failed DNS OS lookup f'{{curl}} -X PUSH -d "{stale_5}" "http://localhost:{ts_parent.Variables.port}";' f'sleep 7; {{curl}} -s -v http://localhost:{ts_parent.Variables.port};' - f'sleep 15; {{curl}} -s -v http://localhost:{ts_parent.Variables.port};') + f'sleep 17; {{curl}} -s -v http://localhost:{ts_parent.Variables.port};') # Test case for when parent server is down but child proxy can serve cache object tr = Test.AddTestRun() diff --git a/tests/gold_tests/proxy_protocol/replay/proxy_serve_stale.replay.yaml b/tests/gold_tests/proxy_protocol/replay/proxy_serve_stale.replay.yaml index 9a04d86e24..152af6ecd8 100644 --- a/tests/gold_tests/proxy_protocol/replay/proxy_serve_stale.replay.yaml +++ b/tests/gold_tests/proxy_protocol/replay/proxy_serve_stale.replay.yaml @@ -119,12 +119,33 @@ sessions: proxy-response: status: 200 + # Request the stale resource after max-age is passed. ATS will still serve stale contents until + # 12 seconds {= max-age (2 seconds) + max_stale_age (10 seconds)}. + # Note that we already delayed 4 seconds in a previous transaction. Current cache object age is 11 seconds. + - client-request: + delay: 7s + + method: "GET" + version: "1.1" + url: /a/path + headers: + fields: + - [ Host, example.com ] + - [ uuid, 4th_stale ] + - [ X-Request, 4th_stale ] + + <<: *origin_response + + # At this point, ATS should respond with a 502 since max_stale_age is exceeded. + proxy-response: + status: 200 + # Request the stale resource after enough delay to guarantee that the cached - # object's age exceeds max_stale_age (10 seconds). Note that we already - # delayed 4 seconds in a previous transaction. ATS should not serve the stale - # entry anymore because it is too old. + # object's age exceeds max-age (2 seconds) + max_stale_age (10 seconds). Note that we already + # delayed 11 seconds in a previous transaction. Current cache object age is 13 seconds. ATS + # should not serve the stale entry anymore because it is too old. - client-request: - delay: 8s + delay: 2s method: "GET" version: "1.1"
