vertx-web icon indicating copy to clipboard operation
vertx-web copied to clipboard

Cache control header "stale-while-revalidate" not work as expected in CachingWebClient

Open jingtingofkirkland opened this issue 3 years ago • 0 comments

Questions

Cache control header "stale-while-revalidate" not work as expected in CachingWebClient

Version

4.2.7

Context

We are using CachingWebClient in our project, however, During our test, we found that Cache control header "stale-while-revalidate", it not works as expected. First it did not follow the "revalidation" document to make a "revalidation" request. Second, the fired "revalidation" request's response is not cached.

Do you have a reproducer?

Config test server with header "Cache-Control: max-age=1, stale-while-revalidate=2"

  1. cachingClient make a get request, it should cache the returned response.
  2. make another request with timing between max-age and (max-age+stale-while-revalidate) in this case expected: staled response return, but fire a "revalidation" request. and refreshed the cache. actual: staled response return, "same normal request" made, and response not cached.
  3. make 3rd request timing after first request's stale-while-revalidate window, but before second request's stale-while-revalidate window. Expected: the new cached second response should returned. Actual: new request is made and no cache response returned.

here is my sample testing code snips

fun testCacheWithStaleWhileRevalidate_VertxBug() = runBlocking<Unit> {
        setupServer(CACHE_CONTROL, "max-age=1, stale-while-revalidate=2")

        var response = client.get("test-server-resource").send().await()
            .send().await()
        assertEquals("first-response", response.bodyAsString())
        launch {
            delay(2000) // delay 2 second
            // After Cache expiry, the old value should return, but trigger a revalidation request. new response should be cached.
            response = client.get("test-server-resource").send().await()
            assertEquals("first-response", response.bodyAsString())
        }
        launch {
            delay(4000) // delay total 4 second(from first request, async in used), it should hit the new cached value
            // After Cache expiry, new value should be returned.
           response = client.get("test-server-resource").send().await()
            // BUG ALERT: Following Assert will fail, because it not returning the new cached value. 
            assertEquals("second-response", response.bodyAsString())
        }
    }

Extra

  • Anything that can be relevant such as OS version, JVM version

jingtingofkirkland avatar Aug 24 '22 19:08 jingtingofkirkland