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
32
33
34
35 public class GuavaVCacheService extends AbstractVCacheService {
36 private static final Logger log = LoggerFactory.getLogger(GuavaVCacheService.class);
37
38 private final GuavaServiceSettings serviceSettings;
39
40
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 }