use of java.util.concurrent.locks.Condition in project ignite by apache.
the class GridJobProcessor method requestJobSiblings.
/**
* @param ses Session.
* @return Siblings.
* @throws IgniteCheckedException If failed.
*/
public Collection<ComputeJobSibling> requestJobSiblings(final ComputeTaskSession ses) throws IgniteCheckedException {
assert ses != null;
final UUID taskNodeId = ses.getTaskNodeId();
ClusterNode taskNode = ctx.discovery().node(taskNodeId);
if (taskNode == null)
throw new IgniteCheckedException("Node that originated task execution has left grid: " + taskNodeId);
// Tuple: error message-response.
final IgniteBiTuple<String, GridJobSiblingsResponse> t = new IgniteBiTuple<>();
final Lock lock = new ReentrantLock();
final Condition cond = lock.newCondition();
GridMessageListener msgLsnr = new GridMessageListener() {
@Override
public void onMessage(UUID nodeId, Object msg, byte plc) {
String err = null;
GridJobSiblingsResponse res = null;
if (!(msg instanceof GridJobSiblingsResponse))
err = "Received unexpected message: " + msg;
else if (!nodeId.equals(taskNodeId))
err = "Received job siblings response from unexpected node [taskNodeId=" + taskNodeId + ", nodeId=" + nodeId + ']';
else {
// Sender and message type are fine.
res = (GridJobSiblingsResponse) msg;
if (res.jobSiblings() == null) {
try {
res.unmarshalSiblings(marsh);
} catch (IgniteCheckedException e) {
U.error(log, "Failed to unmarshal job siblings.", e);
err = e.getMessage();
}
}
}
lock.lock();
try {
if (t.isEmpty()) {
t.set(err, res);
cond.signalAll();
}
} finally {
lock.unlock();
}
}
};
GridLocalEventListener discoLsnr = new GridLocalEventListener() {
@Override
public void onEvent(Event evt) {
assert evt instanceof DiscoveryEvent && (evt.type() == EVT_NODE_FAILED || evt.type() == EVT_NODE_LEFT) : "Unexpected event: " + evt;
DiscoveryEvent discoEvt = (DiscoveryEvent) evt;
if (taskNodeId.equals(discoEvt.eventNode().id())) {
lock.lock();
try {
if (t.isEmpty()) {
t.set("Node that originated task execution has left grid: " + taskNodeId, null);
cond.signalAll();
}
} finally {
lock.unlock();
}
}
}
};
boolean loc = ctx.localNodeId().equals(taskNodeId);
// 1. Create unique topic name.
Object topic = TOPIC_JOB_SIBLINGS.topic(ses.getId(), topicIdGen.getAndIncrement());
try {
// 2. Register listener.
ctx.io().addMessageListener(topic, msgLsnr);
// 3. Send message.
ctx.io().sendToGridTopic(taskNode, TOPIC_JOB_SIBLINGS, new GridJobSiblingsRequest(ses.getId(), loc ? topic : null, loc ? null : U.marshal(marsh, topic)), SYSTEM_POOL);
// 4. Listen to discovery events.
ctx.event().addLocalEventListener(discoLsnr, EVT_NODE_FAILED, EVT_NODE_LEFT);
// 5. Check whether node has left before disco listener has been installed.
taskNode = ctx.discovery().node(taskNodeId);
if (taskNode == null)
throw new IgniteCheckedException("Node that originated task execution has left grid: " + taskNodeId);
// 6. Wait for result.
lock.lock();
try {
long netTimeout = ctx.config().getNetworkTimeout();
if (t.isEmpty())
cond.await(netTimeout, MILLISECONDS);
if (t.isEmpty())
throw new IgniteCheckedException("Timed out waiting for job siblings (consider increasing" + "'networkTimeout' configuration property) [ses=" + ses + ", netTimeout=" + netTimeout + ']');
// Error is set?
if (t.get1() != null)
throw new IgniteCheckedException(t.get1());
else
// Return result
return t.get2().jobSiblings();
} catch (InterruptedException e) {
throw new IgniteCheckedException("Interrupted while waiting for job siblings response: " + ses, e);
} finally {
lock.unlock();
}
} finally {
ctx.io().removeMessageListener(topic, msgLsnr);
ctx.event().removeLocalEventListener(discoLsnr);
}
}
use of java.util.concurrent.locks.Condition in project ignite by apache.
the class OffheapReadWriteLock method waitAcquireWriteLock.
/**
* Acquires write lock in waiting loop.
*
* @param lock Lock address.
* @param lockIdx Lock index.
* @param tag Validation tag.
* @return {@code True} if lock was acquired, {@code false} if tag validation failed.
*/
private boolean waitAcquireWriteLock(long lock, int lockIdx, int tag) {
ReentrantLock lockObj = locks[lockIdx];
Condition waitCond = writeConditions[lockIdx];
assert lockObj.isHeldByCurrentThread();
boolean interrupted = false;
try {
while (true) {
try {
long state = GridUnsafe.getLongVolatile(null, lock);
if (!checkTag(state, tag)) {
// We cannot lock with this tag, release waiter.
long updated = updateState(state, 0, 0, -1);
if (GridUnsafe.compareAndSwapLong(null, lock, state, updated)) {
int writeWaitCnt = writersWaitCount(updated);
int readWaitCnt = readersWaitCount(updated);
signalNextWaiter(writeWaitCnt, readWaitCnt, lockIdx);
return false;
}
} else if (canWriteLock(state)) {
long updated = updateState(state, -1, 0, -1);
if (GridUnsafe.compareAndSwapLong(null, lock, state, updated))
return true;
} else
waitCond.await();
} catch (InterruptedException ignore) {
interrupted = true;
}
}
} finally {
if (interrupted)
Thread.currentThread().interrupt();
}
}
use of java.util.concurrent.locks.Condition in project ignite by apache.
the class OffheapReadWriteLock method signalNextWaiter.
/**
* @param writeWaitCnt Writers wait count.
* @param readWaitCnt Readers wait count.
* @param idx Lock index.
*/
private void signalNextWaiter(int writeWaitCnt, int readWaitCnt, int idx) {
// to this particular lock, we can't wake up just one of them.
if (writeWaitCnt == 0) {
Condition readCondition = readConditions[idx];
readCondition.signalAll();
} else if (readWaitCnt == 0) {
Condition writeCond = writeConditions[idx];
writeCond.signalAll();
} else {
// We have both writers and readers.
if (USE_RANDOM_RW_POLICY) {
boolean write = (balancers[idx].incrementAndGet() & 0x1) == 0;
Condition cond = (write ? writeConditions : readConditions)[idx];
cond.signalAll();
} else {
Condition cond = writeConditions[idx];
cond.signalAll();
}
}
}
use of java.util.concurrent.locks.Condition in project knime-core by knime.
the class WorkflowManager method waitWhileInExecution.
/**
* Causes the current thread to wait until the the workflow has reached a non-executing state unless a given timeout
* elapsed.
*
* @param mutex The lock to sleep on (m_workflowMutex of the nodes/wfm to be waited for)
* @param time the maximum time to wait (0 or negative for waiting infinitely)
* @param unit the time unit of the {@code time} argument
* @return {@code false} if the waiting time detectably elapsed before return from the method, else {@code true}. It
* returns {@code true} if the time argument is 0 or negative.
* @throws InterruptedException if the current thread is interrupted
*/
private static boolean waitWhileInExecution(final WorkflowLock workflowLock, final NodeContainerStateObservable[] ncs, final long time, final TimeUnit unit) throws InterruptedException {
final ReentrantLock lock = workflowLock.getReentrantLock();
final Condition whileInExecCondition = lock.newCondition();
NodeStateChangeListener listener = new NodeStateChangeListener() {
@Override
public void stateChanged(final NodeStateEvent stateEvent) {
lock.lock();
try {
if (!containsExecutingNode(ncs)) {
whileInExecCondition.signalAll();
}
} finally {
lock.unlock();
}
}
};
lock.lockInterruptibly();
Arrays.stream(ncs).filter(nc -> nc != null).forEach(nc -> nc.addNodeStateChangeListener(listener));
try {
if (!containsExecutingNode(ncs)) {
return true;
}
if (time > 0) {
return whileInExecCondition.await(time, unit);
} else {
whileInExecCondition.await();
return true;
}
} finally {
lock.unlock();
Arrays.stream(ncs).filter(nc -> nc != null).forEach(nc -> nc.removeNodeStateChangeListener(listener));
}
}
use of java.util.concurrent.locks.Condition in project JGroups by belaban.
the class NAKACK_StressTest method start.
private static void start(final int num_threads, final int num_msgs, boolean oob) {
final NAKACK2 nak = new NAKACK2();
final AtomicInteger counter = new AtomicInteger(num_msgs);
final AtomicLong seqno = new AtomicLong(1);
final AtomicInteger delivered_msgs = new AtomicInteger(0);
final Lock lock = new ReentrantLock();
final Condition all_msgs_delivered = lock.newCondition();
final ConcurrentLinkedQueue<Long> delivered_msg_list = new ConcurrentLinkedQueue<>();
final Address local_addr = Util.createRandomAddress("A");
final Address sender = Util.createRandomAddress("B");
nak.setDownProtocol(new Protocol() {
public Object down(Event evt) {
return null;
}
});
nak.setUpProtocol(new Protocol() {
public Object up(Message msg) {
delivered_msgs.incrementAndGet();
NakAckHeader2 hdr = msg.getHeader(NAKACK_ID);
if (hdr != null)
delivered_msg_list.add(hdr.getSeqno());
if (delivered_msgs.get() >= num_msgs) {
lock.lock();
try {
all_msgs_delivered.signalAll();
} finally {
lock.unlock();
}
}
return null;
}
public void up(MessageBatch batch) {
for (Message msg : batch) {
delivered_msgs.incrementAndGet();
NakAckHeader2 hdr = (NakAckHeader2) msg.getHeader(NAKACK_ID);
if (hdr != null)
delivered_msg_list.add(hdr.getSeqno());
if (delivered_msgs.get() >= num_msgs) {
lock.lock();
try {
all_msgs_delivered.signalAll();
} finally {
lock.unlock();
}
}
}
}
});
nak.setDiscardDeliveredMsgs(true);
nak.down(new Event(Event.SET_LOCAL_ADDRESS, local_addr));
nak.down(new Event(Event.BECOME_SERVER));
View view = View.create(local_addr, 1, local_addr, sender);
nak.down(new Event(Event.VIEW_CHANGE, view));
MutableDigest digest = new MutableDigest(view.getMembersRaw());
digest.set(local_addr, 0, 0);
digest.set(sender, 0, 0);
nak.down(new Event(Event.SET_DIGEST, digest));
final CountDownLatch latch = new CountDownLatch(1);
Sender[] adders = new Sender[num_threads];
for (int i = 0; i < adders.length; i++) {
adders[i] = new Sender(nak, latch, counter, seqno, oob, sender);
adders[i].start();
}
long start = System.currentTimeMillis();
// starts all adders
latch.countDown();
int max_tries = 30;
lock.lock();
try {
while (delivered_msgs.get() < num_msgs && max_tries-- > 0) {
try {
all_msgs_delivered.await(1000, TimeUnit.MILLISECONDS);
System.out.println("received " + delivered_msgs.get() + " msgs");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} finally {
lock.unlock();
}
long time = System.currentTimeMillis() - start;
double requests_sec = num_msgs / (time / 1000.0);
System.out.printf("\nTime: %d ms, %.2f requests / sec\n", time, requests_sec);
System.out.println("Delivered messages: " + delivered_msg_list.size());
if (delivered_msg_list.size() < 100)
System.out.println("Elements: " + delivered_msg_list);
nak.stop();
List<Long> results = new ArrayList<>(delivered_msg_list);
if (oob)
Collections.sort(results);
assert results.size() == num_msgs : "expected " + num_msgs + ", but got " + results.size();
System.out.println("Checking results consistency");
int i = 1;
for (Long num : results) {
if (num != i) {
assert i == num : "expected " + i + " but got " + num;
return;
}
i++;
}
System.out.println("OK");
}
Aggregations