Skip to content

Commit

Permalink
chore: Optimize cache invalidation.
Browse files Browse the repository at this point in the history
  • Loading branch information
nstdio committed Oct 22, 2022
1 parent c37f6fd commit bfe58ef
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 15 deletions.
26 changes: 16 additions & 10 deletions src/main/java/io/github/nstdio/http/ext/CachingInterceptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import io.github.nstdio.http.ext.Cache.CacheEntry;
import io.github.nstdio.http.ext.Cache.CacheStats;

import java.net.URI;
import java.net.http.HttpHeaders;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandler;
Expand All @@ -27,7 +29,6 @@
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Stream;

import static io.github.nstdio.http.ext.Headers.HEADER_IF_MODIFIED_SINCE;
import static io.github.nstdio.http.ext.Headers.HEADER_IF_NONE_MATCH;
Expand All @@ -36,9 +37,10 @@
import static io.github.nstdio.http.ext.Responses.isSafeRequest;
import static io.github.nstdio.http.ext.Responses.isSuccessful;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.stream.Collectors.toList;

class CachingInterceptor implements Interceptor {
private final static List<String> INVALIDATION_HEADERS = List.of("Location", "Content-Location");

private final Cache cache;
private final Clock clock;

Expand Down Expand Up @@ -170,14 +172,18 @@ private <T> BodyHandler<T> cacheAware(RequestContext ctx) {
}

private <T> HttpResponse<T> invalidate(HttpResponse<T> response) {
List<HttpRequest> toEvict = Stream.of("Location", "Content-Location")
.flatMap(s -> Headers.effectiveUri(response.headers(), s, response.uri()).stream())
.filter(uri -> response.uri().getHost().equals(uri.getHost()))
.map(uri -> HttpRequest.newBuilder(uri).build())
.collect(toList());
toEvict.add(response.request());

toEvict.forEach(cache::evictAll);
HttpHeaders headers = response.headers();
URI uri = response.uri();
String host = uri.getHost();

for (String headerName : INVALIDATION_HEADERS) {
Headers.effectiveUri(headers, headerName, uri)
.filter(u -> host.equals(u.getHost()))
.map(u -> HttpRequest.newBuilder(u).build())
.forEach(cache::evictAll);
}

cache.evictAll(response.request());

return response;
}
Expand Down
7 changes: 3 additions & 4 deletions src/main/java/io/github/nstdio/http/ext/Headers.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiPredicate;
import java.util.stream.Stream;

import static java.util.function.Predicate.not;
import static java.util.stream.Collectors.toList;

class Headers {
static final String HEADER_VARY = "Vary";
Expand Down Expand Up @@ -176,12 +176,11 @@ static Optional<Instant> parseInstant(HttpHeaders headers, String headerName) {
.map(Headers::parseInstant);
}

static List<URI> effectiveUri(HttpHeaders headers, String headerName, URI responseUri) {
static Stream<URI> effectiveUri(HttpHeaders headers, String headerName, URI responseUri) {
return headers.allValues(headerName)
.stream()
.map(s -> effectiveUri(s, responseUri))
.filter(Objects::nonNull)
.collect(toList());
.filter(Objects::nonNull);
}

static URI effectiveUri(String s, URI responseUri) {
Expand Down
3 changes: 2 additions & 1 deletion src/test/kotlin/io/github/nstdio/http/ext/HeadersTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import java.net.http.HttpHeaders
import java.time.Instant
import java.util.Map
import java.util.stream.Stream
import kotlin.streams.asSequence

internal class HeadersTest {
@ParameterizedTest
Expand Down Expand Up @@ -61,7 +62,7 @@ internal class HeadersTest {
@MethodSource("effectiveUriHeadersData")
fun effectiveUriHeaders(headers: HttpHeaders?, headerName: String?, responseUri: URI?, expected: List<URI?>?) {
//when
val uris = Headers.effectiveUri(headers, headerName, responseUri)
val uris = Headers.effectiveUri(headers, headerName, responseUri).asSequence().toList()

//then
assertThat(uris).isEqualTo(expected)
Expand Down

0 comments on commit bfe58ef

Please sign in to comment.