Created
September 24, 2019 20:08
-
-
Save fieldju/79147912905dbc1a5c55e624a69c4b81 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.nike.cerberus.cache; | |
import org.apache.ibatis.builder.InitializingObject; | |
import org.apache.ibatis.cache.Cache; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import java.util.Objects; | |
import java.util.concurrent.TimeUnit; | |
import java.util.concurrent.locks.ReadWriteLock; | |
import static com.github.benmanes.caffeine.cache.Caffeine.newBuilder; | |
/** | |
* A simple Caffeine backed cache that auto expires items after a certain time period, | |
* to help us against bursty traffic that does repeat reads. | |
*/ | |
public class DatabaseCache implements Cache, InitializingObject { | |
private final Logger log = LoggerFactory.getLogger(getClass()); | |
private com.github.benmanes.caffeine.cache.Cache<Object, Object> delegate; | |
private final String id; | |
public DatabaseCache(String id) { | |
this.id = id; | |
} | |
/** | |
* This method gets called after this class is instantiated by MyBatis and all the properties have been set. | |
*/ | |
@Override | |
public void initialize() { | |
log.info("Database cache with namespace: {} has been initialized", id); | |
delegate = newBuilder() | |
.expireAfterWrite(10, TimeUnit.SECONDS) | |
.build(); | |
} | |
@Override | |
public String getId() { | |
return id; | |
} | |
@Override | |
public void putObject(Object key, Object value) { | |
if (key == null || value == null) { | |
return; | |
} | |
delegate.put(key, value); | |
} | |
@Override | |
public Object getObject(Object key) { | |
return delegate.getIfPresent(key); | |
} | |
@Override | |
public Object removeObject(Object key) { | |
Object res = delegate.getIfPresent(key); | |
delegate.invalidate(key); | |
return res; | |
} | |
@Override | |
public void clear() { | |
// NO-OP, my batis by default clears the entire namespaced cache when a write action occurs, | |
// we do not want that here, we are expiring the cache / making reads eventually consistent. | |
// Since we run Cerberus in a cluster anyways and each instance will have it's own generated cache, a simple small | |
// time window where items purge themselves is adequate. | |
} | |
@Override | |
public int getSize() { | |
try { | |
return Math.toIntExact(delegate.estimatedSize()); | |
} catch (ArithmeticException e) { | |
return Integer.MAX_VALUE; | |
} | |
} | |
@Override | |
public ReadWriteLock getReadWriteLock() { | |
return null; | |
} | |
@Override | |
public int hashCode() { | |
return Objects.hash(delegate, getId()); | |
} | |
@Override | |
public boolean equals(Object o) { | |
if (this == o) return true; | |
if (!(o instanceof DatabaseCache)) return false; | |
DatabaseCache that = (DatabaseCache) o; | |
return delegate.equals(that.delegate) && | |
getId().equals(that.getId()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment