package pl.piotrsukiennik.whowhen.shared.memcached;
import net.spy.memcached.MemcachedClient;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* @author Piotr Sukiennik
*/
public class AsynchronousMemcachedClientWrapper extends MemcachedClientWrapper {
public AsynchronousMemcachedClientWrapper( MemcachedClient memcachedClient ) {
super( memcachedClient );
}
public <T> Future<T> asyncGet( final MemcachedGenericKey<T> genericKey, final long intervalCheck, final TimeUnit intervalCheckUnit ) {
return new Future<T>() {
private boolean cancelled = false;
private boolean done = false;
private boolean mayInterruptIfRunning = false;
@Override
public synchronized boolean cancel( boolean mayInterruptIfRunning ) {
this.mayInterruptIfRunning = mayInterruptIfRunning;
return cancelled = true;
}
@Override
public synchronized boolean isCancelled() {
return cancelled;
}
@Override
public synchronized boolean isDone() {
return done;
}
@Override
public T get() throws InterruptedException, ExecutionException {
long intervalCheckMillis = intervalCheckUnit.convert( intervalCheck, TimeUnit.MILLISECONDS );
T target = AsynchronousMemcachedClientWrapper.super.get( genericKey );
while ( target == null ) {
if ( !genericKey.exists() ) {
return null;
}
else if ( !cancelled || ( cancelled && !mayInterruptIfRunning ) ) {
try {
Thread.sleep( intervalCheckMillis );
}
catch ( InterruptedException e ) {
e.printStackTrace();
}
try {
target = AsynchronousMemcachedClientWrapper.super.get( genericKey );
}
catch ( Exception e ) {
throw new ExecutionException( e );
}
}
else if ( cancelled && mayInterruptIfRunning ) {
throw new InterruptedException();
}
}
return target;
}
@Override
public T get( long timeout, TimeUnit unit ) throws InterruptedException, ExecutionException, TimeoutException {
timeout = unit.convert( timeout, TimeUnit.MILLISECONDS );
long intervalCheckMillis = intervalCheckUnit.convert( intervalCheck, TimeUnit.MILLISECONDS );
long waitFrom = System.currentTimeMillis();
long waitTo = waitFrom + timeout;
T target = AsynchronousMemcachedClientWrapper.super.get( genericKey );
while ( target == null ) {
if ( !genericKey.exists() ) {
return null;
}
else if ( waitFrom <= waitTo ) {
throw new TimeoutException();
}
else if ( !cancelled || ( cancelled && !mayInterruptIfRunning ) ) {
try {
Thread.sleep( intervalCheckMillis );
}
catch ( InterruptedException e ) {
e.printStackTrace();
}
try {
target = AsynchronousMemcachedClientWrapper.super.get( genericKey );
}
catch ( Exception e ) {
throw new ExecutionException( e );
}
}
else if ( cancelled && mayInterruptIfRunning ) {
throw new InterruptedException();
}
}
done = true;
return target;
}
};
}
}