caching - navegadores - ¿Cómo evitar el almacenamiento en caché cuando los valores son nulos?
htaccess cache (3)
Enfrentado al mismo problema, los valores perdidos en la fuente formaban parte del flujo de trabajo normal. No he encontrado nada mejor que escribir algunos códigos utilizando los getIfPresent
, get
y put
. Vea el método a continuación, donde local
es Cache<Object, Object>
:
private <K, V> V getFromLocalCache(K key, Supplier<V> fallback) {
@SuppressWarnings("unchecked")
V s = (V) local.getIfPresent(key);
if (s != null) {
return s;
} else {
V value = fallback.get();
if (value != null) {
local.put(key, value);
}
return value;
}
}
Estoy usando guayaba para almacenar datos calientes. Cuando los datos no existen en la memoria caché, debo obtenerlos de una base de datos como esta.
public final static LoadingCache<ObjectId, User> UID2UCache = CacheBuilder.newBuilder()
//.maximumSize(2000)
.weakKeys()
.weakValues()
.expireAfterAccess(10, TimeUnit.MINUTES)
.build(
new CacheLoader<ObjectId, User>() {
@Override
public User load(ObjectId k) throws Exception {
User u = DataLoader.datastore.find(User.class).field("_id").equal(k).get();
return u;
}
});
Mi problema es que cuando los datos tampoco existen en la base de datos, prefiero devolver nulos y no hacer ningún almacenamiento en caché. Pero guava solo guarda nulo con la clave en el caché y lanza excepción cuando lo tengo
com.google.common.cache.CacheLoader $ InvalidCacheLoadException: CacheLoader devolvió nulo para la clave shisoft.
Entonces, ¿cómo evitar el almacenamiento en caché de valores nulos?
Solo arroje alguna Excepción si el usuario no se encuentra y tóquelo en el código del cliente mientras usa el método get(key)
.
new CacheLoader<ObjectId, User>() {
@Override
public User load(ObjectId k) throws Exception {
User u = DataLoader.datastore.find(User.class).field("_id").equal(k).get();
if (u != null) {
return u;
} else {
throw new UserNotFoundException();
}
}
}
Desde CacheLoader.load(K)
Javadoc:
Returns: the value associated with key; must not be null Throws: Exception - if unable to load the result
Respondiendo a sus dudas sobre el almacenamiento en caché de valores nulos:
Devuelve el valor asociado a la clave en este caché, primero cargando ese valor si es necesario. Ningún estado observable asociado con este caché se modifica hasta que se complete la carga .
(de get(key) Javadoc)
Si lanza una excepción, la carga no se considera completa, por lo que no se almacena en caché ningún valor nuevo.
EDITAR :
Tenga en cuenta que en Caffeine , que es una especie de caché de guayaba 2.0 y "proporciona un caché en memoria usando una API inspirada en Google Guava", puede devolver el null
del método de load
:
Returns: the value associated with key or null if not found
Si considera migrar, su cargador de datos podría regresar libremente cuando no se encuentre al usuario.
Solución simple: use com.google.common.base.Optional<User>
lugar de User
como valor.
public final static LoadingCache<ObjectId, Optional<User>> UID2UCache = CacheBuilder.newBuilder()
...
.build(
new CacheLoader<ObjectId, Optional<User>>() {
@Override
public Optional<User> load(ObjectId k) throws Exception {
return Optional.fromNullable(DataLoader.datastore.find(User.class).field("_id").equal(k).get());
}
});
EDIT: Creo que la respuesta de @Xaerxess es mejor.