public void Apply(IEnumerable <IShard> shards, IShardOperation operation)
 {
     foreach (var shard in GetNextOrderingOfShards(shards))
     {
         var shardOperation = operation.Prepare(shard);
         shardOperation();
     }
 }
 public T Apply <T>(IEnumerable <IShard> shards, IShardOperation <T> operation, IExitStrategy <T> exitStrategy)
 {
     foreach (var shard in GetNextOrderingOfShards(shards))
     {
         var shardOperation = operation.Prepare(shard);
         var result         = shardOperation();
         if (result != null && exitStrategy.AddResult(result, shard))
         {
             Log.Debug("Short-circuiting operation {0} after execution against shard {1}", operation.OperationName, shard);
             break;
         }
     }
     return(exitStrategy.CompileResults());
 }
            private void ExecuteForShard(object state)
            {
                var s = (IShard)state;

                try
                {
                    Func <T> shardOperation;

                    // Perform thread-safe preparation of the operation for a single shard.
                    lock (this)
                    {
                        // Prevent execution if parallel operation has already been cancelled.
                        if (_isCancelled)
                        {
                            if (--_activeCount <= 0)
                            {
                                Monitor.Pulse(this);
                            }
                            return;
                        }

                        shardOperation = _operation.Prepare(s);
                    }

                    // Perform operation execution on multiple shards in parallel.
                    var result = shardOperation();

                    // Perform thread-safe aggregation of operation results.
                    lock (this)
                    {
                        // Only add result if operation still has not been cancelled and result is not null.
                        if (!_isCancelled && !Equals(result, null))
                        {
                            _isCancelled = _exitStrategy.AddResult(result, s);
                        }

                        if (--_activeCount <= 0)
                        {
                            Monitor.Pulse(this);
                        }
                    }
                }
                catch (Exception e)
                {
                    lock (this)
                    {
                        if (!_isCancelled)
                        {
                            _exception   = e;
                            _isCancelled = true;
                        }

                        if (--_activeCount <= 0)
                        {
                            Monitor.Pulse(this);
                        }
                    }
                    Log.DebugFormat("Failed parallel operation '{0}' on shard '{1:X}'.",
                                    _operation.OperationName, s.ShardIds.First());
                }
            }