1.9.30 sync.
[gae.git] / java / src / main / com / google / appengine / api / datastore / MemcacheServiceHelper.java
blob1f9900e3428d872c570a8915688e4fb579d73a77
1 package com.google.appengine.api.datastore;
3 import static com.google.common.base.Preconditions.checkArgument;
5 import com.google.appengine.api.memcache.AsyncMemcacheService;
6 import com.google.appengine.api.memcache.ConsistentErrorHandler;
7 import com.google.appengine.api.memcache.ErrorHandlers;
8 import com.google.appengine.api.memcache.Expiration;
9 import com.google.appengine.api.memcache.InvalidValueException;
10 import com.google.appengine.api.memcache.MemcacheService.CasValues;
11 import com.google.appengine.api.memcache.MemcacheService.IdentifiableValue;
12 import com.google.appengine.api.memcache.MemcacheService.SetPolicy;
13 import com.google.appengine.api.memcache.MemcacheServiceException;
14 import com.google.appengine.api.memcache.MemcacheServiceFactory;
16 import java.util.Collection;
17 import java.util.Map;
18 import java.util.Set;
19 import java.util.concurrent.Future;
20 import java.util.logging.Level;
21 import java.util.logging.Logger;
23 /**
24 * Helper class for the memcache service.
27 class MemcacheServiceHelper {
29 static final double DEFAULT_MEMCACHE_RPC_DEADLINE_SECS = 1;
31 static Logger logger = Logger.getLogger(MemcacheServiceHelper.class.getName());
32 private static final Level LOG_LEVEL = Level.INFO;
34 static final String NAMESPACE = "__ah-datastore-l2-v1__";
36 private double rpcDeadlineSecs = DEFAULT_MEMCACHE_RPC_DEADLINE_SECS;
37 private Expiration defaultValueExpirationTime;
38 private final AsyncMemcacheService memcacheService;
40 private MemcacheServiceHelper() {
41 memcacheService = MemcacheServiceFactory.getAsyncMemcacheService(NAMESPACE);
42 memcacheService.setErrorHandler(new MemcacheExceptionConvertingErrorHandler());
45 MemcacheServiceHelper(AsyncMemcacheService memcacheService) {
46 this.memcacheService = memcacheService;
49 /**
50 * Updates the memcache operation RPC deadline to use for memcache RPCs.
52 * @param rpcDeadlineSecs the memcache operation RPC deadline in seconds.
53 * @return {@code this} (for chaining).
54 * @throws IllegalArgumentException if the {@code rpcDeadlineSecs} is not greater than zero.
56 public MemcacheServiceHelper rpcDeadlineSecs(double rpcDeadlineSecs) {
57 checkArgument(rpcDeadlineSecs > 0, "The rpcDeadlineSecs argument must be greater than 0");
58 this.rpcDeadlineSecs = rpcDeadlineSecs;
59 return this;
62 /**
63 * @return the memcache operation RPC deadline in seconds.
65 public double getRpcDeadlineSecs() {
66 return rpcDeadlineSecs;
69 /**
70 * Updates the expiration time for values stored in the cache without an explicit expiration time.
71 * By default, values without an explicit expiration time are cached for as long of a duration as
72 * possible.
74 * @param defaultValueExpirationTime the default value expiration time. Or {@code null} to specify
75 * an indefinite default expiration time.
76 * @return {@code this} (for chaining).
78 public MemcacheServiceHelper defaultValueExpirationTime( Expiration defaultValueExpirationTime) {
79 this.defaultValueExpirationTime = defaultValueExpirationTime;
80 return this;
83 /**
84 * @return the default value expiration time for values stored in the cache without
85 * an explicit expiration time or {@code null} if no default expiration time has been
86 * specified.
88 public Expiration getDefaultValueExpirationTime() {
89 return defaultValueExpirationTime;
92 /**
93 * Updates the {@link MemcacheServiceHelper} instance to log and absorb any memcache
94 * service errors. By default, memcache service errors are converted to
95 * {@code DatastoreFailureException} exceptions and thrown from the memcache operation
96 * methods.
98 * @return the newly created {@code MemcacheServiceHelper} instance.
100 public MemcacheServiceHelper logAndAbsorbMemcacheServiceErrors() {
101 memcacheService.setErrorHandler(ErrorHandlers.getConsistentLogAndContinue(LOG_LEVEL));
102 return this;
106 * Fetches previously-stored cache values. The values returned can be used in subsequent calls
107 * to {@link #putIfUntouched}.
109 * @param keys a collection of keys for which values should be retrieved
110 * @return a mapping from keys to values of any entries found. If a requested
111 * key is not found in the cache the key will not be in the returned Map.
112 * @throws IllegalArgumentException if any element of {@code keys} is {@code null}
113 * or not {@link Serializable}.
114 * @throws DatastoreFailureException if a memcache service error occurs and
115 * {@link #logAndAbsorbMemcacheServiceErrors} has not been specified.
117 public <K> Future<Map<K, IdentifiableValue>> getIdentifiable(Collection<K> keys) {
118 return memcacheService.getIdentifiables(keys);
122 * Sets the value in the cache for each key/value pair in the {@code values} map if the update
123 * satisfies the cache update {@code policy}.
124 * <p>
125 * The expiration time for each value stored is specified by
126 * {@link #defaultValueExpirationTime(Expiration)}.
128 * @param values the key/value mappings to add to the cache
129 * @param policy what to do if the cache entry is or is not already present
130 * @return the set of keys for which entries were created. Keys in {@code values} may not be
131 * in the returned set because of the {@code policy} regarding pre-existing entries.
132 * @throws IllegalArgumentException if any of the keys or values are {@code null} or
133 * or are not {@link Serializable}.
134 * @throws DatastoreFailureException if a memcache service error occurs and
135 * {@link #logAndAbsorbMemcacheServiceErrors} has not been specified.
137 public <K> Future<Set<K>> put(Map<K, ?> values, SetPolicy policy) {
138 return put(values, policy, defaultValueExpirationTime);
142 * Sets the value in the cache for each key/value pair in the {@code values} map if the update
143 * satisfies the cache update {@code policy}.
145 * @param values the key/value mappings to add to the cache
146 * @param policy what to do if the cache entry is or is not already present
147 * @param valueExpirationTime the memcache value expiration time to use for each value updated
148 * in the cache. This overrides the default value expiration time. If {@code null} the
149 * expiration time is indefinite.
150 * @return the set of keys for which entries were created. Keys in {@code values} may not be
151 * in the returned set because of the {@code policy} regarding pre-existing entries.
152 * @throws IllegalArgumentException if any of the keys or values are {@code null} or
153 * or are not {@link Serializable}.
154 * @throws DatastoreFailureException if a memcache service error occurs and
155 * {@link #logAndAbsorbMemcacheServiceErrors} has not been specified.
157 public <K> Future<Set<K>> put(Map<K, ?> values, SetPolicy policy, Expiration valueExpirationTime) {
158 return memcacheService.putAll(values, valueExpirationTime, policy);
162 * Atomically stores the new value of each {@link CasValues} object in the {@code values} map if
163 * no other value has been stored in the cache since the {@code CasValues} object's old value
164 * was retrieved from {@link #getIdentifiable}. If another value in the cache for {@code key}
165 * has been stored, or if the cache entry has been evicted then nothing is stored by this call.
166 * <p>
167 * The expiration time for each {@CasValues} object with a {@code null} expiration time is
168 * specified by {@link #defaultValueExpirationTime(Expiration)}.
170 * @param values the key/values mappings to compare and swap.
171 * @return the set of keys for which the new value was stored.
172 * @throws IllegalArgumentException If any of the keys or newValues are {@code null} or
173 * or are not {@link Serializable}. Also throws IllegalArgumentException if {@code values} has
174 * any nulls.
175 * @throws DatastoreFailureException if a memcache service error occurs and
176 * {@link #logAndAbsorbMemcacheServiceErrors} has not been specified.
178 public <K> Future<Set<K>> putIfUntouched(Map<K, CasValues> values) {
179 return putIfUntouched(values, defaultValueExpirationTime);
183 * Atomically stores the new value of each {@link CasValues} object in the {@code values} map if
184 * no other value has been stored in the cache since the {@code CasValues} object's old value
185 * was retrieved from {@link #getIdentifiable}. If another value in the cache for {@code key}
186 * has been stored, or if the cache entry has been evicted then nothing is stored by this call.
187 * <p>
189 * @param values the key/values mappings to compare and swap.
190 * @param valueExpirationTime the expiration time to use for all {@code values} with a
191 * {@code null} {@link Expiration expiration} value in the {@code CasValues} object.
192 * This overrides the default value expiration time. If this is {@code null} and the
193 * {@code CasValues} object's expiration time is {@code null} then an indefinite expiration
194 * time will be specified for that {@code CasValue} object.
195 * @return the set of keys for which the new value was stored.
196 * @throws IllegalArgumentException If any of the keys or newValues are {@code null} or
197 * or are not {@link Serializable}. Also throws IllegalArgumentException if {@code values} has
198 * any nulls.
199 * @throws DatastoreFailureException if a memcache service error occurs and
200 * {@link #logAndAbsorbMemcacheServiceErrors} has not been specified.
202 public <K> Future<Set<K>> putIfUntouched(Map<K, CasValues> values, Expiration valueExpirationTime) {
203 return memcacheService.putIfUntouched(values, valueExpirationTime);
207 * Deletes cache entries for the specified keys.
209 * @param keys a collection of keys for entries to delete
210 * @return the set of keys successfully deleted. Any keys in {@code keys} but not in the
211 * returned set were not found in the cache. The iteration order of the returned set matches
212 * the iteration order of the provided {@code keys}.
213 * @throws IllegalArgumentException if any element of {@code keys} is not {@link Serializable}
214 * and is not {@code null}
215 * @throws DatastoreFailureException if a memcache service error occurs and
216 * {@link #logAndAbsorbMemcacheServiceErrors} has not been specified.
218 public <K> Future<Set<K>> delete(Collection<K> keys) {
219 return memcacheService.deleteAll(keys);
223 * A memcache service error handler that converts memcache service errors into
224 * {@link DatastoreFailureException} exceptions.
226 private static class MemcacheExceptionConvertingErrorHandler implements ConsistentErrorHandler {
228 @Override
229 public void handleDeserializationError(InvalidValueException t) {
230 throw new DatastoreFailureException("Memcache deserialization error", t);
233 @Override
234 public void handleServiceError(MemcacheServiceException t) {
235 throw new DatastoreFailureException("Memcache service error", t);
240 * Contains static creation methods for {@link MemcacheServiceHelper} instances.
242 public static final class Builder {
245 * Creates a {@link MemcacheServiceHelper} instance with the specified memcache RPC deadline to
246 * use for memcache RPCs.
248 * @param rpcDeadlineSecs the memcache operation RPC deadline in seconds.
249 * @return the newly created {@code MemcacheServiceHelper} instance.
250 * @throws IllegalArgumentException if the {@code rpcDeadlineSecs} is not greater than zero.
252 public static MemcacheServiceHelper withRpcDeadlineSecs(double rpcDeadlineSecs) {
253 return new MemcacheServiceHelper().rpcDeadlineSecs(rpcDeadlineSecs);
257 * Creates a {@link MemcacheServiceHelper} instance with the specified expiration time for
258 * values stored in the cache without an explicit expiration time. By default, values without
259 * an explicit expiration time are cached for as long of a duration as possible.
261 * @param defaultValueExpirationTime the default value expiration time. Or {@code null} to
262 * specify an indefinite default expiration time.
263 * @return the newly created {@code MemcacheServiceHelper} instance.
265 public static MemcacheServiceHelper withDefaultValueExpirationTime( Expiration defaultValueExpirationTime) {
266 return new MemcacheServiceHelper().defaultValueExpirationTime(defaultValueExpirationTime);
270 * Creates a {@link MemcacheServiceHelper} instance which logs and absorbs any memcache
271 * service errors. By default, memcache service errors are converted to
272 * {@code DatastoreFailureException} exceptions and thrown from the memcache operation methods.
274 * @return the newly created {@code MemcacheServiceHelper} instance.
276 public static MemcacheServiceHelper withLogAndAbsorbMemcacheServiceErrors() {
277 return new MemcacheServiceHelper().logAndAbsorbMemcacheServiceErrors();
281 * Creates a {@link MemcacheServiceHelper} instance with the default configuration.
283 public static MemcacheServiceHelper withDefaults() {
284 return new MemcacheServiceHelper();
287 private Builder() {}