I had a first go at implementing a cached QueryEngineHTTP:
https://github.com/castagna/sparql-cache/raw/master/src/main/java/com/talis/labs/arq/CachedQueryEngineHTTP.java
Invalidation is by service end-point and this approach makes sense only
if you have mostly reads with few and non frequent updates.
I am not happy with all those synchronized and the static cache.
synchronized (cache) {
if (cache.containsKey(key)) {
return (ResultSetRewindable) cache.get(key);
}
}
rs = ResultSetFactory.makeRewindable(super.execSelect());
synchronized (cache) {
cache.put(key, rs);
}
The synchronization needs to be over the get and the put together. What
if another thread comes in after the first block? Both find .get is null.
You then have two threads executing the makeRewindable/execSelect This
happens to be safe because of the operation super.execSelect() is safe
in parallel but in general the operation being cached is not thread safe.
Generally this is safer: a single sync over get and the
put-if-cache-miss. And in this case just as fast, and makes only one
call to the far end:
(thread 2 waits on the lock, not makes the query on the remote end):
synchronized (cache) {
if (cache.containsKey(key)) {
return (ResultSetRewindable) cache.get(key);
rs = ResultSetFactory.makeRewindable(super.execSelect());
cache.put(key, rs);
}
Andy