use of co.paralleluniverse.strands.concurrent.ReentrantLock in project quasar by puniverse.
the class GlxGlobalRegistry method getActor0.
private CacheEntry getActor0(final String rootName, long timeout, TimeUnit unit) throws SuspendExecution, RuntimeException, InterruptedException {
final long deadline = unit != null ? System.nanoTime() + unit.toNanos(timeout) : 0;
final Store store = grid.store();
final long root;
final ReentrantLock lck0 = new ReentrantLock();
final Condition cond = lck0.newCondition();
boolean listening = false;
final StoreTransaction txn = store.beginTransaction();
try {
root = store.getRoot(rootName, txn);
final CacheListener listener = new AbstractCacheListener() {
@Override
public void evicted(Cache cache, long id) {
invalidated(cache, id);
}
@Override
public void invalidated(Cache cache, long id) {
grid.getDelegate().store().getAsync(id);
}
@Override
public void received(Cache cache, long id, long version, ByteBuffer data) {
if (data != null && data.remaining() > 0) {
LOG.debug("Received root {} ({})", rootName, Long.toHexString(id));
lck0.lock();
try {
cond.signalAll();
} finally {
lck0.unlock();
}
store.setListener(root, null);
}
}
};
listening = (store.setListenerIfAbsent(root, listener) == listener);
store.commit(txn);
} catch (TimeoutException e) {
LOG.error("Getting actor {} failed due to timeout", rootName);
store.rollback(txn);
store.abort(txn);
throw new RuntimeException("Actor discovery failed");
}
try {
byte[] buf = store.gets(root, null);
long version = store.getVersion(root);
store.release(root);
if (listening) {
lck0.lock();
try {
while (buf == null || buf.length == 0) {
LOG.debug("Store returned null for root {}", rootName);
if (deadline > 0) {
final long now = System.nanoTime();
if (now > deadline)
// throw new java.util.concurrent.TimeoutException();
return null;
cond.await(deadline - now, TimeUnit.NANOSECONDS);
} else
cond.await();
buf = store.gets(root, null);
version = store.getVersion(root);
store.release(root);
}
} finally {
lck0.unlock();
}
} else
assert buf != null && buf.length > 0;
final ActorRef<?> actor = deserActor(rootName, buf);
return new CacheEntry(actor, root, version);
} catch (TimeoutException e) {
LOG.error("Getting actor {} failed due to timeout", rootName);
throw new RuntimeException("Actor discovery failed");
}
}
Aggregations