From 4958e1d60f2528be6ef1109bc562139b2c1f4120 Mon Sep 17 00:00:00 2001 From: Timm Fitschen <t.fitschen@indiscale.com> Date: Fri, 26 Feb 2021 10:13:35 +0100 Subject: [PATCH] EHN: ETag property for the Query --- CHANGELOG.md | 4 ++++ .../java/org/caosdb/server/query/Query.java | 21 +++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76e20e39..dceac0e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +* `ETag` property for the query. The `ETag` tags a server state and is being + updated each time the server state is being updated (i.e. the stored entities + change). This can be used to debug the query cache and also allows a client + to determine whether the server's state has changed between queries. * Basic caching for queries. The caching is enabled by default and can be controlled by the usual "cache" flag. diff --git a/src/main/java/org/caosdb/server/query/Query.java b/src/main/java/org/caosdb/server/query/Query.java index 0a877fc8..60c361be 100644 --- a/src/main/java/org/caosdb/server/query/Query.java +++ b/src/main/java/org/caosdb/server/query/Query.java @@ -39,6 +39,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.UUID; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.apache.commons.jcs.access.behavior.ICacheAccess; @@ -238,6 +239,14 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac */ private boolean cachable = true; + /** + * Tags the query cache and is renewed each time the cache is being cleared, i.e. each time the + * database is being updated. + * + * <p>As the name suggests, the idea is similar to the ETag header of the HTTP protocol. + */ + private static String cacheETag = UUID.randomUUID().toString(); + public Type getType() { return this.type; } @@ -668,6 +677,7 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac /** Remove all cached queries from the cache. */ public static void clearCache() { + cacheETag = UUID.randomUUID().toString(); cache.clear(); } @@ -678,10 +688,12 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac * @param resultSet */ private void setCache(String key, List<IdVersionPair> resultSet) { - if (resultSet instanceof Serializable) { - cache.put(key, (Serializable) resultSet); - } else { - cache.put(key, new ArrayList<>(resultSet)); + synchronized (cache) { + if (resultSet instanceof Serializable) { + cache.put(key, (Serializable) resultSet); + } else { + cache.put(key, new ArrayList<>(resultSet)); + } } } @@ -859,6 +871,7 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac ret.setAttribute("results", "0"); } ret.setAttribute("cached", Boolean.toString(this.cached)); + ret.setAttribute("etag", cacheETag); final Element parseTreeElem = new Element("ParseTree"); if (this.el.hasErrors()) { -- GitLab