package cz.cuni.mff.d3s.been.cluster.action; import static com.hazelcast.core.Instance.InstanceType.COUNT_DOWN_LATCH; import static java.util.concurrent.TimeUnit.MILLISECONDS; import com.hazelcast.core.ICountDownLatch; import com.hazelcast.core.InstanceDestroyedException; import com.hazelcast.core.MemberLeftException; import cz.cuni.mff.d3s.been.cluster.context.ClusterContext; import cz.cuni.mff.d3s.been.socketworks.twoway.Replies; import cz.cuni.mff.d3s.been.socketworks.twoway.Reply; import cz.cuni.mff.d3s.been.task.checkpoints.CheckpointRequest; /** * An {@link Action} that handles a request for a waiting until a latch becomes * zero. * * @author Martin Sixta */ final class LatchWaitAction implements Action { /** the request to handle */ private final CheckpointRequest request; /** BEEN cluster instance */ private final ClusterContext ctx; /** * Default constructor, creates the action with the specified request and * cluster context. * * @param request * the request to handle * @param ctx * the cluster context */ public LatchWaitAction(CheckpointRequest request, ClusterContext ctx) { this.request = request; this.ctx = ctx; } @Override public Reply handle() { String latchName = Actions.latchNameForRequest(request); if (!ctx.containsInstance(COUNT_DOWN_LATCH, latchName)) { return Replies.createErrorReply("No such Count Down Latch '%s'", latchName); } long timeout = request.getTimeout(); if (timeout < 0) { return Replies.createErrorReply("Timeout must be >= 0, but was %d'", timeout); } final ICountDownLatch countDownLatch = ctx.getCountDownLatch(latchName); try { boolean waitResult; if (request.getTimeout() == 0) { // await() will return after hazelcast.max.operation.timeout no matter what while (countDownLatch.hasCount()) { countDownLatch.await(); } waitResult = true; } else { waitResult = countDownLatch.await(timeout, MILLISECONDS); } if (waitResult) { return Replies.createOkReply(Boolean.toString(true)); } else { return Replies.createErrorReply("TIMEOUT"); } } catch (InstanceDestroyedException | MemberLeftException | InterruptedException e) { return Replies.createErrorReply(e.getMessage()); } } }