Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
play.cache.MemcachedImpl Maven / Gradle / Ivy
package play.cache;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.net.InetSocketAddress;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import net.spy.memcached.AddrUtil;
import net.spy.memcached.ConnectionFactory;
import net.spy.memcached.ConnectionFactoryBuilder;
import net.spy.memcached.MemcachedClient;
import net.spy.memcached.auth.AuthDescriptor;
import net.spy.memcached.auth.PlainCallbackHandler;
import net.spy.memcached.transcoders.SerializingTranscoder;
import play.Logger;
import play.Play;
import play.exceptions.ConfigurationException;
/**
* Memcached implementation (using http://code.google.com/p/spymemcached/)
*
* expiration is specified in seconds
*/
public class MemcachedImpl implements CacheImpl {
private static MemcachedImpl uniqueInstance;
MemcachedClient client;
SerializingTranscoder tc;
public static MemcachedImpl getInstance() throws IOException {
return getInstance(false);
}
public static MemcachedImpl getInstance(boolean forceClientInit) throws IOException {
if (uniqueInstance == null) {
uniqueInstance = new MemcachedImpl();
} else if (forceClientInit) {
// When you stop the client, it sets the interrupted state of this thread to true. If you try to reinit it with the same thread in this state,
// Memcached client errors out. So a simple call to interrupted() will reset this flag
Thread.interrupted();
uniqueInstance.initClient();
}
return uniqueInstance;
}
private MemcachedImpl() throws IOException {
tc = new SerializingTranscoder() {
@Override
protected Object deserialize(byte[] data) {
try {
return new ObjectInputStream(new ByteArrayInputStream(data)) {
@Override
protected Class> resolveClass(ObjectStreamClass desc)
throws IOException, ClassNotFoundException {
return Class.forName(desc.getName(), false, Play.classloader);
}
}.readObject();
} catch (Exception e) {
Logger.error(e, "Could not deserialize");
}
return null;
}
@Override
protected byte[] serialize(Object object) {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
new ObjectOutputStream(bos).writeObject(object);
return bos.toByteArray();
} catch (IOException e) {
Logger.error(e, "Could not serialize");
}
return null;
}
};
initClient();
}
public void initClient() throws IOException {
System.setProperty("net.spy.log.LoggerImpl", "net.spy.memcached.compat.log.Log4JLogger");
List addrs;
if (Play.configuration.containsKey("memcached.host")) {
addrs = AddrUtil.getAddresses(Play.configuration.getProperty("memcached.host"));
} else if (Play.configuration.containsKey("memcached.1.host")) {
int nb = 1;
String addresses = "";
while (Play.configuration.containsKey("memcached." + nb + ".host")) {
addresses += Play.configuration.get("memcached." + nb + ".host") + " ";
nb++;
}
addrs = AddrUtil.getAddresses(addresses);
} else {
throw new ConfigurationException("Bad configuration for memcached: missing host(s)");
}
if (Play.configuration.containsKey("memcached.user")) {
String memcacheUser = Play.configuration.getProperty("memcached.user");
String memcachePassword = Play.configuration.getProperty("memcached.password");
if (memcachePassword == null) {
throw new ConfigurationException("Bad configuration for memcached: missing password");
}
// Use plain SASL to connect to memcached
AuthDescriptor ad = new AuthDescriptor(new String[]{"PLAIN"},
new PlainCallbackHandler(memcacheUser, memcachePassword));
ConnectionFactory cf = new ConnectionFactoryBuilder()
.setProtocol(ConnectionFactoryBuilder.Protocol.BINARY)
.setAuthDescriptor(ad)
.build();
client = new MemcachedClient(cf, addrs);
} else {
client = new MemcachedClient(addrs);
}
}
public void add(String key, Object value, int expiration) {
client.add(key, expiration, value, tc);
}
public Object get(String key) {
Future future = client.asyncGet(key, tc);
try {
return future.get(1, TimeUnit.SECONDS);
} catch (Exception e) {
future.cancel(false);
}
return null;
}
public void clear() {
client.flush();
}
public void delete(String key) {
client.delete(key);
}
public Map get(String[] keys) {
Future> future = client.asyncGetBulk(tc, keys);
try {
return future.get(1, TimeUnit.SECONDS);
} catch (Exception e) {
future.cancel(false);
}
return Collections.emptyMap();
}
public long incr(String key, int by) {
return client.incr(key, by, 0);
}
public long decr(String key, int by) {
return client.decr(key, by, 0);
}
public void replace(String key, Object value, int expiration) {
client.replace(key, expiration, value, tc);
}
public boolean safeAdd(String key, Object value, int expiration) {
Future future = client.add(key, expiration, value, tc);
try {
return future.get(1, TimeUnit.SECONDS);
} catch (Exception e) {
future.cancel(false);
}
return false;
}
public boolean safeDelete(String key) {
Future future = client.delete(key);
try {
return future.get(1, TimeUnit.SECONDS);
} catch (Exception e) {
future.cancel(false);
}
return false;
}
public boolean safeReplace(String key, Object value, int expiration) {
Future future = client.replace(key, expiration, value, tc);
try {
return future.get(1, TimeUnit.SECONDS);
} catch (Exception e) {
future.cancel(false);
}
return false;
}
public boolean safeSet(String key, Object value, int expiration) {
Future future = client.set(key, expiration, value, tc);
try {
return future.get(1, TimeUnit.SECONDS);
} catch (Exception e) {
future.cancel(false);
}
return false;
}
public void set(String key, Object value, int expiration) {
client.set(key, expiration, value, tc);
}
public void stop() {
client.shutdown();
}
}