View Javadoc

1   package com.atlassian.vcache.internal.guava;
2   
3   import com.atlassian.marshalling.api.MarshallingPair;
4   import com.atlassian.vcache.DirectExternalCache;
5   import com.atlassian.vcache.ExternalCacheSettings;
6   import com.atlassian.vcache.JvmCache;
7   import com.atlassian.vcache.JvmCacheSettings;
8   import com.atlassian.vcache.StableReadExternalCache;
9   import com.atlassian.vcache.TransactionalExternalCache;
10  import com.atlassian.vcache.internal.BegunTransactionalActivityHandler;
11  import com.atlassian.vcache.internal.RequestContext;
12  import com.atlassian.vcache.internal.VCacheCreationHandler;
13  import com.atlassian.vcache.internal.VCacheSettingsDefaultsProvider;
14  import com.atlassian.vcache.internal.core.ExternalCacheKeyGenerator;
15  import com.atlassian.vcache.internal.core.Sha1ExternalCacheKeyGenerator;
16  import com.atlassian.vcache.internal.core.metrics.MetricsCollector;
17  import com.atlassian.vcache.internal.core.service.AbstractVCacheService;
18  import com.atlassian.vcache.internal.core.service.GuavaJvmCache;
19  import com.google.common.cache.Cache;
20  import org.slf4j.Logger;
21  import org.slf4j.LoggerFactory;
22  
23  import java.util.Map;
24  import java.util.Optional;
25  import java.util.concurrent.ConcurrentHashMap;
26  import java.util.function.Supplier;
27  
28  import static java.util.Objects.requireNonNull;
29  
30  /**
31   * Main service that is backed by <tt>Guava</tt>.
32   *
33   * @since 1.0.0
34   */
35  public class GuavaVCacheService extends AbstractVCacheService {
36      private static final Logger log = LoggerFactory.getLogger(GuavaVCacheService.class);
37  
38      private final GuavaServiceSettings serviceSettings;
39      // Used to keep track of the underlying Guava caches used. This is to simulate the behaviour
40      // of the real external caches.
41      private final Map<String, Cache> delegatedCaches = new ConcurrentHashMap<>();
42  
43      public GuavaVCacheService(
44              String productIdentifier,
45              Supplier<RequestContext> threadLocalContextSupplier,
46              Supplier<RequestContext> workContextContextSupplier,
47              VCacheSettingsDefaultsProvider defaultsProvider,
48              VCacheCreationHandler creationHandler,
49              MetricsCollector metricsCollector,
50              GuavaServiceSettings serviceSettings,
51              BegunTransactionalActivityHandler begunTransactionalActivityHandler) {
52          super(threadLocalContextSupplier,
53                  workContextContextSupplier,
54                  defaultsProvider,
55                  creationHandler,
56                  metricsCollector,
57                  new Sha1ExternalCacheKeyGenerator(productIdentifier),
58                  begunTransactionalActivityHandler);
59          this.serviceSettings = requireNonNull(serviceSettings);
60      }
61  
62      public GuavaVCacheService(
63              Supplier<RequestContext> threadLocalContextSupplier,
64              Supplier<RequestContext> workContextContextSupplier,
65              VCacheSettingsDefaultsProvider defaultsProvider,
66              VCacheCreationHandler creationHandler,
67              MetricsCollector metricsCollector,
68              ExternalCacheKeyGenerator externalCacheKeyGenerator,
69              GuavaServiceSettings serviceSettings,
70              BegunTransactionalActivityHandler begunTransactionalActivityHandler) {
71          super(threadLocalContextSupplier,
72                  workContextContextSupplier,
73                  defaultsProvider,
74                  creationHandler,
75                  metricsCollector,
76                  externalCacheKeyGenerator,
77                  begunTransactionalActivityHandler);
78          this.serviceSettings = requireNonNull(serviceSettings);
79      }
80  
81      @Override
82      protected Logger log() {
83          return log;
84      }
85  
86      @Override
87      protected <K, V> JvmCache<K, V> createJvmCache(String name, JvmCacheSettings settings) {
88          return new GuavaJvmCache<>(name, settings);
89      }
90  
91      @Override
92      protected <V> TransactionalExternalCache<V> createTransactionalExternalCache(
93              String name, ExternalCacheSettings settings, MarshallingPair<V> valueMarshalling, boolean valueSerializable) {
94          return new GuavaTransactionalExternalCache<>(
95                  name,
96                  obtainDelegate(name, settings),
97                  threadLocalContextSupplier,
98                  externalCacheKeyGenerator,
99                  (serviceSettings.isSerializationHack() && valueSerializable) ? Optional.empty() : Optional.of(valueMarshalling),
100                 transactionControlManager,
101                 metricsCollector);
102     }
103 
104     @Override
105     protected <V> StableReadExternalCache<V> createStableReadExternalCache(
106             String name, ExternalCacheSettings settings, MarshallingPair<V> valueMarshalling, boolean valueSerializable) {
107         return new GuavaStableReadExternalCache<>(
108                 name,
109                 obtainDelegate(name, settings),
110                 workContextContextSupplier,
111                 externalCacheKeyGenerator,
112                 (serviceSettings.isSerializationHack() && valueSerializable) ? Optional.empty() : Optional.of(valueMarshalling),
113                 metricsCollector);
114     }
115 
116     @Override
117     protected <V> DirectExternalCache<V> createDirectExternalCache(
118             String name, ExternalCacheSettings settings, MarshallingPair<V> valueMarshalling, boolean valueSerializable) {
119         return new GuavaDirectExternalCache<>(
120                 name,
121                 obtainDelegate(name, settings),
122                 workContextContextSupplier,
123                 externalCacheKeyGenerator,
124                 (serviceSettings.isSerializationHack() && valueSerializable) ? Optional.empty() : Optional.of(valueMarshalling));
125     }
126 
127     private <V> Cache<String, V> obtainDelegate(String name, ExternalCacheSettings settings) {
128         return delegatedCaches.computeIfAbsent(name, k -> GuavaUtils.buildDelegate(settings));
129     }
130 }