View Javadoc

1   package com.atlassian.vcache.internal.memcached;
2   
3   import com.atlassian.vcache.internal.BegunTransactionalActivityHandler;
4   import com.atlassian.vcache.internal.RequestContext;
5   import com.atlassian.vcache.internal.VCacheCreationHandler;
6   import com.atlassian.vcache.internal.VCacheSettingsDefaultsProvider;
7   import com.atlassian.vcache.internal.core.ExternalCacheKeyGenerator;
8   import com.atlassian.vcache.internal.core.Sha1ExternalCacheKeyGenerator;
9   import com.atlassian.vcache.internal.core.metrics.DefaultMetricsCollector;
10  import com.atlassian.vcache.internal.core.metrics.MetricsCollector;
11  import net.spy.memcached.MemcachedClientIF;
12  
13  import java.time.Duration;
14  import java.util.function.Function;
15  import java.util.function.Supplier;
16  
17  import static java.util.Objects.requireNonNull;
18  
19  /**
20   * Builder for creating {@link MemcachedVCacheServiceSettings} instances.
21   * <p>
22   * All settings must be set before {@link #build()} can be called, except for
23   * {@link #metricsCollector(MetricsCollector)}, {@link #begunTransactionalActivityHandler(BegunTransactionalActivityHandler)}
24   * and {@link #dontExternaliseCache(Function)}. See their Javadoc for the defaults used.
25   * </p>
26   * <p>
27   * Either {@link #externalCacheKeyGenerator(ExternalCacheKeyGenerator)} or {@link #productIdentifier(String)} must be
28   * called.
29   * </p>
30   *
31   * @since 1.3.0
32   */
33  public class MemcachedVCacheServiceSettingsBuilder {
34      private Supplier<MemcachedClientIF> clientSupplier;
35      private Supplier<RequestContext> threadLocalContextSupplier;
36      private Supplier<RequestContext> workContextContextSupplier;
37      private VCacheSettingsDefaultsProvider defaultsProvider;
38      private VCacheCreationHandler creationHandler;
39      private MetricsCollector metricsCollector;
40      private ExternalCacheKeyGenerator externalCacheKeyGenerator;
41      // By default, don't care
42      private BegunTransactionalActivityHandler begunTransactionalActivityHandler = context -> {
43      };
44      // By default, externalise the external caches.
45      private Function<String, Boolean> dontExternaliseCache = name -> false;
46      // By default, don't use this hack
47      private boolean serializationHack;
48      // By default, wait a fixed time
49      @SuppressWarnings("checkstyle:MagicNumber")
50      private Duration lockTimeout = Duration.ofSeconds(30);
51  
52      /**
53       * Sets the client supplier.
54       *
55       * @param clientSupplier the client supplier.
56       * @return the builder
57       */
58      public MemcachedVCacheServiceSettingsBuilder clientSupplier(Supplier<MemcachedClientIF> clientSupplier) {
59          this.clientSupplier = requireNonNull(clientSupplier);
60          return this;
61      }
62  
63      /**
64       * Sets the context supplier.
65       *
66       * @param threadLocalContextSupplier the context supplier.
67       * @return the builder.
68       */
69      public MemcachedVCacheServiceSettingsBuilder threadLocalContextSupplier(Supplier<RequestContext> threadLocalContextSupplier) {
70          this.threadLocalContextSupplier = requireNonNull(threadLocalContextSupplier);
71          return this;
72      }
73  
74      /**
75       * Sets the context supplier for caches that can be thread safe.
76       *
77       * @param contextSupplier the context supplier.
78       * @return the builder.
79       */
80      public MemcachedVCacheServiceSettingsBuilder workContextContextSupplier(Supplier<RequestContext> contextSupplier) {
81          this.workContextContextSupplier = contextSupplier;
82          return this;
83      }
84  
85      /**
86       * Sets the defaults provider.
87       *
88       * @param defaultsProvider the defaults provider.
89       * @return the builder.
90       */
91      public MemcachedVCacheServiceSettingsBuilder defaultsProvider(VCacheSettingsDefaultsProvider defaultsProvider) {
92          this.defaultsProvider = requireNonNull(defaultsProvider);
93          return this;
94      }
95  
96      /**
97       * Set the creation handler.
98       *
99       * @param creationHandler the creation handler.
100      * @return the builder.
101      */
102     public MemcachedVCacheServiceSettingsBuilder creationHandler(VCacheCreationHandler creationHandler) {
103         this.creationHandler = requireNonNull(creationHandler);
104         return this;
105     }
106 
107     /**
108      * Sets the metrics collector. If not invoked, then the {@link DefaultMetricsCollector} implementation will be
109      * used.
110      *
111      * @param metricsCollector the metrics collector.
112      * @return the builder.
113      */
114     public MemcachedVCacheServiceSettingsBuilder metricsCollector(MetricsCollector metricsCollector) {
115         this.metricsCollector = requireNonNull(metricsCollector);
116         return this;
117     }
118 
119     /**
120      * Equivalent to calling {@link #externalCacheKeyGenerator(ExternalCacheKeyGenerator)} passing a
121      * {@link Sha1ExternalCacheKeyGenerator} instance created using the supplied product identifier.
122      *
123      * @param productIdentifier the product identifier to use with the {@link Sha1ExternalCacheKeyGenerator}.
124      * @return the builder.
125      */
126     public MemcachedVCacheServiceSettingsBuilder productIdentifier(String productIdentifier) {
127         this.externalCacheKeyGenerator = new Sha1ExternalCacheKeyGenerator(productIdentifier);
128         return this;
129     }
130 
131     /**
132      * Set the external cache key generator.
133      *
134      * @param externalCacheKeyGenerator the external cache key generator.
135      * @return the builder.
136      */
137     public MemcachedVCacheServiceSettingsBuilder externalCacheKeyGenerator(ExternalCacheKeyGenerator externalCacheKeyGenerator) {
138         this.externalCacheKeyGenerator = requireNonNull(externalCacheKeyGenerator);
139         return this;
140     }
141 
142     /**
143      * Sets the begun transaction activity handler. If not invoked, then a default implementation is provided that does
144      * nothing.
145      *
146      * @param handler the begun transaction activity handler.
147      * @return the builder.
148      */
149     public MemcachedVCacheServiceSettingsBuilder begunTransactionalActivityHandler(BegunTransactionalActivityHandler handler) {
150         this.begunTransactionalActivityHandler = requireNonNull(handler);
151         return this;
152     }
153 
154     /**
155      * Sets the function to determine whether an {@link com.atlassian.vcache.ExternalCache} should really be externalised.
156      * If the supplied function returns <tt>true</tt> for a cache, then an in-memory implementation will be used.
157      * <p>
158      * If not set, then a default implementation is provided that will externalise all {@link com.atlassian.vcache.ExternalCache}'s.
159      * nothing.
160      * </p>
161      * <p>
162      * Note: this function is provided to allow for an orderly migration of external caches from being in-memory
163      * to be stored in Memcached.
164      * </p>
165      *
166      * @param dontExternaliseCache the function to determine whether an {@link com.atlassian.vcache.ExternalCache}
167      *                                 should really be externalised.
168      * @return the builder.
169      */
170     public MemcachedVCacheServiceSettingsBuilder dontExternaliseCache(Function<String, Boolean> dontExternaliseCache) {
171         this.dontExternaliseCache = requireNonNull(dontExternaliseCache);
172         return this;
173     }
174 
175     /**
176      * Enable the serialization hack, whereby if an {@link com.atlassian.vcache.ExternalCache}'s values are
177      * {@link java.io.Serializable}, then the values are not marshalled before they are passed to the delegate
178      * Atlassian Cache. This is to allow for performance optimisations.
179      */
180     public MemcachedVCacheServiceSettingsBuilder enableSerializationHack() {
181         serializationHack = true;
182         return this;
183     }
184 
185     /**
186      * Change the timeout that is used when acquiring locks.
187      * @param lockTimeout the timeout that is used when acquiring locks.
188      * @return the current builder
189      */
190     public MemcachedVCacheServiceSettingsBuilder lockTimeout(Duration lockTimeout) {
191         this.lockTimeout = requireNonNull(lockTimeout);
192         return this;
193     }
194 
195     /**
196      * Returns a new {@link MemcachedVCacheServiceSettings} instance configured using the supplied settings.
197      *
198      * @return a new {@link MemcachedVCacheServiceSettings} instance configured using the supplied settings.
199      */
200     public MemcachedVCacheServiceSettings build() {
201         return new MemcachedVCacheServiceSettings(
202                 requireNonNull(clientSupplier, "missing clientSupplier"),
203                 requireNonNull(threadLocalContextSupplier, "missing threadLocalContextSupplier"),
204                 requireNonNull(workContextContextSupplier, "missing thread safe workContextContextSupplier"),
205                 requireNonNull(defaultsProvider, "missing defaultsProvider"),
206                 requireNonNull(creationHandler, "missing creationHandler"),
207                 (metricsCollector != null) ? metricsCollector : new DefaultMetricsCollector(threadLocalContextSupplier),
208                 requireNonNull(externalCacheKeyGenerator, "missing externalCacheKeyGenerator"),
209                 begunTransactionalActivityHandler,
210                 dontExternaliseCache,
211                 serializationHack,
212                 lockTimeout);
213     }
214 }