How to setup aggressive caching?
Standard cache configuration
The RavenDB client provides a caching mechanism out of the box. You can decide if Raven should cache a request or not for a particular URL. The default caching configuration is to cache all request:
documentStore.getConventions().setShouldCacheRequest(new RequestCachePolicy() {
@SuppressWarnings("boxing")
@Override
public Boolean shouldCacheRequest(String url) {
return true;
}
});
The second cache option is the number of cached requests. The default value is 2048:
documentStore.setMaxNumberOfCachedRequests(2048);
The client utilizes the notion of the 304 Not Modified
server's response and will serve the data from the cache if available.
Aggressive mode
The aggressive caching feature goes even further. Enabling it causes that the client can do not even ask the server and simply return the response directly from a local cache, without any usage of 304 Not Modified
status.
It means that a result will be returned very fast. The way it works is that the client subscribes to server notifications and by taking advantage of them is able to invalidate cached documents
when they are changed. Hence the client knows when it can serve the response from the cache, and when it has to send the request to get the up-to-date result.
Important
Despite the fact that the aggressive cache uses the notifications to invalidate the cache, it is still possible to get a stale data because of the time needed to receive the notification from the server.
To activate the aggressive caching mode use the code:
try (AutoCloseable aggressivelyCacheFor = session.advanced().getDocumentStore().aggressivelyCacheFor(5 * 60 * 1000)) {
Order user = session.load(Order.class, "orders/1");
}
Now, if there is a value in the cache for orders/1
that is at most 5 minutes old and we haven't got any change notification about it, we can directly return it. The same mechanism works on queries as well:
try (AutoCloseable aggressivelyCacheFor = session.advanced().getDocumentStore().aggressivelyCacheFor(5 * 60 * 1000)) {
List<Order> order = session.query(Order.class).toList();
}
The usage of the notification system means that you can set an aggressive cache duration to longer period. The document store exposes the method:
try (AutoCloseable scope = session.advanced().getDocumentStore().aggressivelyCache()) {
// empty
}
which is equivalent to:
try (AutoCloseable scope = session.advanced().getDocumentStore().aggressivelyCacheFor(24 * 3600 * 1000)) {
// empty
}
Disabling the use of notifications
You can disable the usage of Changes API by the aggressive cache to track cached items and invalidate the cache when needed:
documentStore.getConventions().setShouldAggressiveCacheTrackChanges(false);
Note that it makes that it becomes more likely to get stale results.
Invalidate on SaveChanges
In addition to the use of notifications, the aggressive cache also revalidates the cache after calling session.SaveChanges()
. This option is configurable by the following convention:
documentStore.getConventions().setShouldSaveChangesForceAggressiveCacheCheck(true);
Its default value is true
. This will work nicely as long as you have just a single client. For multiple clients you should use ShouldAggressiveCacheTrackChanges
.