This is an automated email from the ASF dual-hosted git repository.
radu pushed a commit to branch feature/SLING-9655
in repository
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-graphql-core.git
The following commit(s) were added to refs/heads/feature/SLING-9655 by this
push:
new f735eb9 SLING-9655 - Caching support for the GraphQL core
f735eb9 is described below
commit f735eb9f5dfad51f13fe9f48c4ef5547a88d0af9
Author: Radu Cotescu <[email protected]>
AuthorDate: Mon Aug 24 18:10:40 2020 +0200
SLING-9655 - Caching support for the GraphQL core
* switched the default GraphQLCacheProvider implementation
to an in-memory LRU cache
---
...erImpl.java => SimpleGraphQLCacheProvider.java} | 123 +++++++++++++--------
.../sling/graphql/core/servlet/GraphQLServlet.java | 1 -
...st.java => SimpleGraphQLCacheProviderTest.java} | 19 +++-
.../graphql/core/it/GraphQLCoreTestSupport.java | 4 -
.../sling/graphql/core/it/GraphQLServletIT.java | 1 -
5 files changed, 91 insertions(+), 57 deletions(-)
diff --git
a/src/main/java/org/apache/sling/graphql/core/cache/GraphQLCacheProviderImpl.java
b/src/main/java/org/apache/sling/graphql/core/cache/SimpleGraphQLCacheProvider.java
similarity index 52%
rename from
src/main/java/org/apache/sling/graphql/core/cache/GraphQLCacheProviderImpl.java
rename to
src/main/java/org/apache/sling/graphql/core/cache/SimpleGraphQLCacheProvider.java
index dcfb4ae..e68977d 100644
---
a/src/main/java/org/apache/sling/graphql/core/cache/GraphQLCacheProviderImpl.java
+++
b/src/main/java/org/apache/sling/graphql/core/cache/SimpleGraphQLCacheProvider.java
@@ -21,79 +21,92 @@ package org.apache.sling.graphql.core.cache;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
-import java.util.Hashtable;
-
-import javax.cache.Cache;
-import javax.cache.CacheManager;
-import javax.cache.configuration.MutableConfiguration;
-import javax.cache.spi.CachingProvider;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.graphql.api.cache.GraphQLCacheProvider;
import org.apache.sling.graphql.core.engine.SlingGraphQLException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Deactivate;
-import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.AttributeType;
+import org.osgi.service.metatype.annotations.Designate;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-@Component(
- immediate = true
-)
-public class GraphQLCacheProviderImpl implements GraphQLCacheProvider {
+@Component()
+@Designate(ocd = SimpleGraphQLCacheProvider.Config.class)
+public class SimpleGraphQLCacheProvider implements GraphQLCacheProvider {
+
+ @ObjectClassDefinition(
+ name = "Apache Sling GraphQL Simple Cache Provider",
+ description = "The Apache Sling GraphQL Simple Cache Provider
provides an in-memory size bound cache for persisted GraphQL " +
+ "queries."
+ )
+ public @interface Config {
+
+ @AttributeDefinition(
+ name = "Capacity",
+ description = "The number of persisted queries to cache.",
+ type = AttributeType.INTEGER,
+ min = "0"
+ )
+ int capacity() default DEFAULT_CACHE_SIZE;
+ }
- private static final Logger LOGGER =
LoggerFactory.getLogger(GraphQLCacheProviderImpl.class);
+ private static final int DEFAULT_CACHE_SIZE = 1024;
+ private static final Logger LOGGER =
LoggerFactory.getLogger(SimpleGraphQLCacheProvider.class);
- @Reference
- private CachingProvider cachingProvider;
+ private InMemoryLRUCache persistedQueriesCache;
+ private ReadWriteLock readWriteLock;
+ private Lock readLock;
+ private Lock writeLock;
- private Cache<String, String> persistedQueriesCache;
+ @Activate
+ public SimpleGraphQLCacheProvider(Config config) {
+ readWriteLock = new ReentrantReadWriteLock();
+ readLock = readWriteLock.readLock();
+ writeLock = readWriteLock.writeLock();
+ int cacheSize = config.capacity();
+ if (cacheSize < 0) {
+ cacheSize = 0;
+ LOGGER.debug("Cache capacity set to {}. Defaulting to 0.",
config.capacity());
+ }
+ persistedQueriesCache = new InMemoryLRUCache(cacheSize);
+ LOGGER.debug("Initialized the in-memory cache for a maximum of {}
queries.", config.capacity());
+ }
- private ServiceRegistration<GraphQLCacheProvider> registration;
@Override
@Nullable
public String getQuery(@NotNull String hash, @NotNull String resourceType,
@Nullable String selectorString) {
- return persistedQueriesCache.get(getCacheKey(hash, resourceType,
selectorString));
+ readLock.lock();
+ try {
+ return persistedQueriesCache.get(getCacheKey(hash, resourceType,
selectorString));
+ } finally {
+ readLock.unlock();
+ }
}
@Override
@NotNull
public String cacheQuery(@NotNull String query, @NotNull String
resourceType, @Nullable String selectorString) {
- String hash = getHash(query);
- String key = getCacheKey(hash, resourceType, selectorString);
- persistedQueriesCache.put(key, query);
- return hash;
- }
-
-
- @Activate
- private void activate(BundleContext bundleContext) {
- if (cachingProvider != null) {
- try {
- CacheManager cacheManager = cachingProvider.getCacheManager();
- persistedQueriesCache = cacheManager
-
.createCache(bundleContext.getBundle().getSymbolicName() + "_persistedQueries",
new MutableConfiguration<>());
- registration =
bundleContext.registerService(GraphQLCacheProvider.class, this, new
Hashtable<>());
- } catch (Exception e) {
- LOGGER.error("Unable to configure a cache for persisted
queries.", e);
- }
- } else {
- LOGGER.error("Cannot activate the " +
GraphQLCacheProvider.class.getName() + " without a cachingProvider.");
- }
- }
-
- @Deactivate
- private void deactivate() {
- if (registration != null) {
- registration.unregister();
+ writeLock.lock();
+ try {
+ String hash = getHash(query);
+ String key = getCacheKey(hash, resourceType, selectorString);
+ persistedQueriesCache.put(key, query);
+ return hash;
+ } finally {
+ writeLock.unlock();
}
- cachingProvider.close();
}
@NotNull
@@ -125,4 +138,18 @@ public class GraphQLCacheProviderImpl implements
GraphQLCacheProvider {
return buffer.toString();
}
+ private static class InMemoryLRUCache extends LinkedHashMap<String,
String> {
+
+ private final int capacity;
+
+ public InMemoryLRUCache(int capacity) {
+ this.capacity = capacity;
+ }
+
+ @Override
+ protected boolean removeEldestEntry(Map.Entry eldest) {
+ return size() > capacity;
+ }
+ }
+
}
diff --git
a/src/main/java/org/apache/sling/graphql/core/servlet/GraphQLServlet.java
b/src/main/java/org/apache/sling/graphql/core/servlet/GraphQLServlet.java
index a54b0e4..537875e 100644
--- a/src/main/java/org/apache/sling/graphql/core/servlet/GraphQLServlet.java
+++ b/src/main/java/org/apache/sling/graphql/core/servlet/GraphQLServlet.java
@@ -21,7 +21,6 @@
package org.apache.sling.graphql.core.servlet;
import java.io.IOException;
-import java.nio.charset.StandardCharsets;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
diff --git
a/src/test/java/org/apache/sling/graphql/core/cache/GraphQLCacheProviderImplTest.java
b/src/test/java/org/apache/sling/graphql/core/cache/SimpleGraphQLCacheProviderTest.java
similarity index 71%
rename from
src/test/java/org/apache/sling/graphql/core/cache/GraphQLCacheProviderImplTest.java
rename to
src/test/java/org/apache/sling/graphql/core/cache/SimpleGraphQLCacheProviderTest.java
index 19c0d3a..8da286a 100644
---
a/src/test/java/org/apache/sling/graphql/core/cache/GraphQLCacheProviderImplTest.java
+++
b/src/test/java/org/apache/sling/graphql/core/cache/SimpleGraphQLCacheProviderTest.java
@@ -18,15 +18,28 @@
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
package org.apache.sling.graphql.core.cache;
+import java.lang.annotation.Annotation;
+
import org.junit.Test;
import static org.junit.Assert.assertEquals;
-public class GraphQLCacheProviderImplTest {
+public class SimpleGraphQLCacheProviderTest {
@Test
- public void getHash() throws Exception {
- GraphQLCacheProviderImpl provider = new GraphQLCacheProviderImpl();
+ public void getHash() {
+ SimpleGraphQLCacheProvider provider = new
SimpleGraphQLCacheProvider(new SimpleGraphQLCacheProvider.Config() {
+ @Override
+ public Class<? extends Annotation> annotationType() {
+ return null;
+ }
+
+ @Override
+ public int capacity() {
+ return 0;
+ }
+ });
+
assertEquals("b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9",
provider.getHash("hello world"));
}
}
diff --git
a/src/test/java/org/apache/sling/graphql/core/it/GraphQLCoreTestSupport.java
b/src/test/java/org/apache/sling/graphql/core/it/GraphQLCoreTestSupport.java
index 604f218..60d10f0 100644
--- a/src/test/java/org/apache/sling/graphql/core/it/GraphQLCoreTestSupport.java
+++ b/src/test/java/org/apache/sling/graphql/core/it/GraphQLCoreTestSupport.java
@@ -94,10 +94,6 @@ public abstract class GraphQLCoreTestSupport extends
TestSupport {
.asOption(),
mavenBundle().groupId("org.apache.sling").artifactId("org.apache.sling.servlet-helpers").versionAsInProject(),
mavenBundle().groupId("com.cedarsoftware").artifactId("json-io").versionAsInProject(),
-
mavenBundle().groupId("javax.cache").artifactId("cache-api").versionAsInProject(),
-
mavenBundle().groupId("com.typesafe").artifactId("config").versionAsInProject(),
-
mavenBundle().groupId("com.github.ben-manes.caffeine").artifactId("caffeine").versionAsInProject(),
-
mavenBundle().groupId("com.github.ben-manes.caffeine").artifactId("jcache").versionAsInProject(),
slingResourcePresence(),
jsonPath(),
junitBundles()
diff --git
a/src/test/java/org/apache/sling/graphql/core/it/GraphQLServletIT.java
b/src/test/java/org/apache/sling/graphql/core/it/GraphQLServletIT.java
index 9f2d45e..e110f45 100644
--- a/src/test/java/org/apache/sling/graphql/core/it/GraphQLServletIT.java
+++ b/src/test/java/org/apache/sling/graphql/core/it/GraphQLServletIT.java
@@ -26,7 +26,6 @@ import org.apache.sling.graphql.api.SchemaProvider;
import org.apache.sling.graphql.core.mocks.ReplacingSchemaProvider;
import org.apache.sling.resource.presence.ResourcePresence;
import org.apache.sling.servlethelpers.MockSlingHttpServletResponse;
-import org.apache.sling.servlethelpers.internalrequests.SlingInternalRequest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.Configuration;