import org.opendaylight.controller.forwardingrulesmanager.implementation.data.FlowEntryDistributionOrder;
import org.opendaylight.controller.sal.utils.Status;
import org.opendaylight.controller.sal.utils.StatusCode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Class which will monitor the completion of a FlowEntryDistributionOrder it
private boolean amICancelled;
private CountDownLatch waitingLatch;
private Status retStatus;
+ private static final Logger logger = LoggerFactory.getLogger(FlowEntryDistributionOrderFutureTask.class);
+ // Don't wait forever to program, rather timeout if there are issues, and
+ // log an error
+ private long timeout;
+ private static final Long DEFAULTTIMEOUT = 30000L;
/**
* @param order
this.waitingLatch = new CountDownLatch(1);
// No return status yet!
this.retStatus = new Status(StatusCode.UNDEFINED);
+ // Set the timeout
+ String strTimeout = System.getProperty("FlowEntryDistributionOrderFutureTask.timeout",
+ DEFAULTTIMEOUT.toString());
+ try {
+ timeout = Long.parseLong(strTimeout);
+ } catch (Exception e) {
+ timeout = DEFAULTTIMEOUT;
+ }
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
+ if (this.waitingLatch.getCount() != 0L) {
+ this.retStatus = new Status(StatusCode.GONE);
+ this.waitingLatch.countDown();
+ logger.trace("Cancelled the workOrder");
+ return true;
+ }
return false;
}
@Override
public Status get() throws InterruptedException, ExecutionException {
+ boolean didFinish = false;
+ logger.trace("Getting status for order {}", this.order);
// If i'm done lets return the status as many times as caller wants
if (this.waitingLatch.getCount() == 0L) {
+ logger.trace("get returns the status without waiting");
return retStatus;
}
+ logger.trace("Start waiting for status to come back");
// Wait till someone signal that we are done
- this.waitingLatch.await();
+ didFinish = this.waitingLatch.await(this.timeout, TimeUnit.MILLISECONDS);
- // Return the known status
- return retStatus;
+ if (didFinish) {
+ logger.trace("Waiting for the status of order {} is over, returning it", this.order);
+ // Return the known status
+ return retStatus;
+ } else {
+ logger.error("Timing out, the workStatus for order {} has not come back in time!, it's hashcode is {}",
+ this.order, this.order.hashCode());
+ return new Status(StatusCode.TIMEOUT);
+ }
}
@Override
public Status get(long timeout, TimeUnit unit) throws InterruptedException,
ExecutionException, TimeoutException {
+ boolean didFinish = false;
+ logger.trace("Getting status for order {}", this.order);
// If i'm done lets return the status as many times as caller wants
if (this.waitingLatch.getCount() == 0L) {
+ logger.trace("get returns the status without waiting");
return retStatus;
}
+ logger.trace("Start waiting for status to come back");
// Wait till someone signal that we are done
- this.waitingLatch.await(timeout, unit);
+ didFinish = this.waitingLatch.await(timeout, unit);
- // Return the known status, could also be null if didn't return
- return retStatus;
+ if (didFinish) {
+ logger.trace("Waiting for the status is over, returning it");
+ // Return the known status, could also be null if didn't return
+ return retStatus;
+ } else {
+ // No need to bark here as long as this routine could indeed
+ // timeout
+ logger.trace("Timing out, the workStatus for order {} has not come back in time!", this.order);
+ return new Status(StatusCode.TIMEOUT);
+ }
}
@Override
* @param retStatus
*/
void gotStatus(FlowEntryDistributionOrder order, Status retStatus) {
- if (order != this.order) {
+ logger.trace("Got status for order:{} \n Status:{}", order, retStatus);
+ if (!order.equals(this.order)) {
+ logger.error("Didn't get a result for an order we did issue order expected:{}, order received:{}",
+ this.order, order);
// Weird we got a call for an order we didn't make
return;
}
this.retStatus = retStatus;
// Now we are not waiting any longer
this.waitingLatch.countDown();
+ logger.trace("Unlocked the Future");
+ }
+
+ /**
+ * Getter for the workOrder for which the order is waiting for
+ * @return the order
+ */
+ public FlowEntryDistributionOrder getOrder() {
+ return order;
}
}