private <Message> ActorRef<Message> 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();
final StoreTransaction txn = store.beginTransaction();
try {
root = store.getRoot(rootName, txn);
store.setListener(root, new AbstractCacheListener() {
@Override
public void evicted(Cache cache, long id) {
invalidated(cache, id);
}
@Override
public void invalidated(Cache cache, long id) {
grid1.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);
}
}
});
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.get(root);
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)
return null; // throw new java.util.concurrent.TimeoutException();
cond.await(deadline - now, TimeUnit.NANOSECONDS);
} else
cond.await();
buf = store.get(root);
}
} finally {
lck0.unlock();
}
return (ActorRef<Message>) updateCache(rootName, root, deserActor(rootName, buf));
} catch (TimeoutException e) {
LOG.error("Getting actor {} failed due to timeout", rootName);