/// <summary> /// Computes a result, or throws an exception if unable to do so. /// </summary> /// <returns></returns> public T Call() { try { WaitForStartSignal(); log.DebugFormat("Starting execution of {0} against shard {1}", operation.OperationName, shard); ///If addResult() returns true it means there is no more work to be ///performed. Cancel all the outstanding tasks. if (exitStrategy.AddResult(operation.Execute(shard), shard)) { log.DebugFormat("Short-circuiting execution of {0} on other threads after execution against shard {1}", operation.OperationName, shard); //It's ok to cancel ourselves because StartAwareFutureTask.cancel() //will return false if a task has already started executing, and we're //already executing. log.DebugFormat("Checking {0} future tasks to see if they need to be cancelled.", futureTasks.Count); foreach (StartAwareFutureTask <T> ft in futureTasks) { log.DebugFormat("Preparing to cancel future task %d.", ft.Id); //If a task was successfully cancelled that means it had not yet //started running. Since the task won't run, the task won't be // able to decrement the CountDownLatch. We need to decrement //it on behalf of the cancelled task. if (ft.Cancel(INTERRUPT_IF_RUNNING)) { log.Debug("Task cancel returned true, decrementing counter on its behalf."); doneSignal.CountDown(); } else { log.Debug("Task cancel returned false, not decrementing counter on its behalf."); } } } else { log.DebugFormat("No need to short-cirtcuit execution of {0} on other threads after execution against shard {1}", operation.OperationName, shard); } } finally { // counter must get decremented no matter what log.DebugFormat("Decrementing counter for operation {0} on shard {1}", operation.OperationName, shard); doneSignal.CountDown(); } return(default(T)); }
public T Apply <T>(IList <IShard> shards, IShardOperation <T> operation, IExitStrategy <T> exitStrategy, IExitOperationsCollector exitOperationsCollector) { foreach (IShard shard in GetNextOrderingOfShards(shards)) { if (exitStrategy.AddResult(operation.Execute(shard), shard)) { log.DebugFormat("Short-circuiting operation {0} after execution against shard {1}", operation.OperationName, shard); break; } } return(exitStrategy.CompileResults(exitOperationsCollector)); }