Skip to content

HTTPCLIENT-2277: optimization of internal cache operations#464

Merged
ok2c merged 2 commits into
apache:5.3.xfrom
ok2c:HTTPCLIENT-2277
Jun 29, 2023
Merged

HTTPCLIENT-2277: optimization of internal cache operations#464
ok2c merged 2 commits into
apache:5.3.xfrom
ok2c:HTTPCLIENT-2277

Conversation

@ok2c
Copy link
Copy Markdown
Member

@ok2c ok2c commented Jun 26, 2023

This is a complete redesign and re-write of the internal cache implementations intended

  • to improve internal cache APIs
  • to provide support for partial matches (no direct match but there are variants for the same root)
  • to eliminate repetitive, redundant cache key calculations
  • to eliminate unnecessary duplicate cache look-ups in the course of a single message exchange

@arturobernalg Please review.

@ok2c ok2c requested a review from arturobernalg June 26, 2023 10:02
Copy link
Copy Markdown
Member

@arturobernalg arturobernalg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ok2c
The change-set generally looks solid. I've made a few observations and have some doubts.

public String getCacheKey() {
return cacheKey;
}
final CacheHit hit;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ok2c

Shouldn't this class be fully immutable?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arturobernalg It is. All its instance variables are final and immutable. There are no access methods but that does not make the class mutable.

final CacheHit root = result != null ? result.root : null;

final SimpleHttpResponse fatalErrorResponse = getFatallyNonCompliantResponse(request, context, entry != null);
final SimpleHttpResponse fatalErrorResponse = getFatallyNonCompliantResponse(request, context, hit != null);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've noticed that the hit != null condition is being checked numerous times in the code. To enhance code readability and reduce redundancy, I suggest encapsulating this logic within the CacheMatch class itself. We could add a hasHit() method as follows:

public boolean hasHit() {
    return hit != null;
}

This way, we can simply call cacheMatch.hasHit() wherever we need to check if hit is not null, improving the code's readability and maintainability."

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arturobernalg This is a matter of taste. I find hit != null clearer but it is just me.

if (staleIfErrorAppliesTo(statusCode)
&& !staleResponseNotAllowed(requestCacheControl, responseCacheControl, cacheEntry, getCurrentDate())
&& validityPolicy.mayReturnStaleIfError(requestCacheControl, responseCacheControl, cacheEntry, responseDate)) {
&& !staleResponseNotAllowed(requestCacheControl, responseCacheControl, hit, getCurrentDate())
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed in the staleResponseNotAllowed method we are passing in the complete CacheHit object, but only the entry attribute within it is being used. To maintain the original structure would it be feasible to pass just the entry object instead?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final String variantKey;
final HttpCacheEntry entry;

public CacheHit(final String rootKey, final String variantKey, final HttpCacheEntry entry) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this class be fully immutable? Also, shouldn't rootKey and entry be null-safe?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arturobernalg The class is immutable. It is also internal so I forwent getters and null checks for its instance variables.

final SimpleHttpResponse response = responseGenerator.generateResponse(request, responseEntry);
responseCache.reuseVariantEntryFor(target, request, backendResponse, responseEntry, requestDate, responseDate);
final SimpleHttpResponse response = responseGenerator.generateResponse(request, hit.entry);
responseCache.storeReusing(hit, target, request, backendResponse, requestDate, responseDate);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't be the entry instead of the hit?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

} else {
LOG.debug("Backend response is not cacheable");
responseCache.flushCacheEntriesFor(target, request, new FutureCallback<Boolean>() {
if (!Method.isSafe(request.getMethod())) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we could consider delegating this check (!Method.isSafe(request.getMethod())) inside the method of the class HttpAsyncCache and BasicHttpCache itself. This way, the method becomes more resilient and we ensure the check is always performed when needed, reducing the potential for errors.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arturobernalg I am not sure. I do not think this is a cache storage layer decision whether a method is considered safe or not. But let's discuss it when I finish refactoring the cache eviction logic.

@ok2c ok2c force-pushed the HTTPCLIENT-2277 branch from bf0dbb2 to bb2e623 Compare June 28, 2023 08:03
@ok2c
Copy link
Copy Markdown
Member Author

ok2c commented Jun 28, 2023

@arturobernalg Please do another pass.

@arturobernalg arturobernalg self-requested a review June 28, 2023 19:39
Copy link
Copy Markdown
Member

@arturobernalg arturobernalg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ok2c the change-set looks good.

@ok2c ok2c merged commit 7df675e into apache:5.3.x Jun 29, 2023
@ok2c ok2c deleted the HTTPCLIENT-2277 branch June 29, 2023 07:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants