Beispiel #1
0
 private void CheckPipelineState(int size, int capacity, InterlockedFlag capacityReached)
 {
     Assert.IsTrue(size >= 0);
     Assert.IsTrue(capacity > 0);
     // a understood flaw of the current algorithm is that the capacity can be exceeded by one item. we've decided that this is acceptable and we allow it to happen.
     Assert.IsTrue(size <= capacity, string.Format("size ({0}) must be less than the capacity ({1})", size, capacity));
     if (capacityReached != null && size == capacity)
     {
         capacityReached.TrySet();
     }
 }
Beispiel #2
0
        private ProducerObserver(ILogger logger, IGrainFactory grainFactory)
        {
            _logger   = logger;
            _observer = null;
            _timers   = new Dictionary <IDisposable, TimerState>();

            _itemsProduced         = 0;
            _expectedItemsProduced = 0;
            _streamId            = default(Guid);
            _providerName        = null;
            _cleanedUpFlag       = new InterlockedFlag();
            _observerDisposedYet = false;
            _grainFactory        = grainFactory;
        }
Beispiel #3
0
        private async Task AsyncPipelineBlackBoxConsistencyTest(int workerCount)
        {
            if (workerCount < 1)
            {
                throw new ArgumentOutOfRangeException("You must specify at least one worker.", "workerCount");
            }

            int          loopCount = _iterationCount / workerCount;
            const double variance  = 0.1;
            int          expectedTasksCompleted = loopCount * workerCount;
            var          delayLength            = TimeSpan.FromSeconds(1);
            const int    pipelineCapacity       = _defaultPipelineCapacity;
            var          pipeline       = new AsyncPipeline(pipelineCapacity);
            int          tasksCompleted = 0;

            // the following value is wrapped within an array to avoid a modified closure warning from ReSharper.
            int[] pipelineSize    = { 0 };
            var   capacityReached = new InterlockedFlag();

            Action workFunc =
                () =>
            {
                var sz = Interlocked.Increment(ref pipelineSize[0]);
                CheckPipelineState(sz, pipelineCapacity, capacityReached);
                Task.Delay(delayLength).Wait();
                Interlocked.Decrement(ref pipelineSize[0]);
                Interlocked.Increment(ref tasksCompleted);
            };

            Action workerFunc =
                () =>
            {
                for (var j = 0; j < loopCount; j++)
                {
                    Task task = new Task(workFunc);
                    pipeline.Add(task, whiteBox: null);
                    task.Start();
                }
            };

            Func <Task> monitorFunc =
                async() =>
            {
                var delay = TimeSpan.FromSeconds(5);
                while (tasksCompleted < expectedTasksCompleted)
                {
                    Console.WriteLine("test in progress: tasksCompleted = {0}.", tasksCompleted);
                    await Task.Delay(delay);
                }
            };

            var workers   = new Task[workerCount];
            var stopwatch = Stopwatch.StartNew();

            for (var i = 0; i < workerCount; ++i)
            {
                workers[i] = Task.Run(workerFunc);
            }
            Task.Run(monitorFunc).Ignore();
            await Task.WhenAll(workers);

            pipeline.Wait();
            stopwatch.Stop();
            Assert.AreEqual(expectedTasksCompleted, tasksCompleted, "The test did not complete the expected number of tasks.");

            var targetTimeSec = expectedTasksCompleted * delayLength.TotalSeconds / pipelineCapacity;
            var minTimeSec    = (1.0 - variance) * targetTimeSec;
            var maxTimeSec    = (1.0 + variance) * targetTimeSec;
            var actualSec     = stopwatch.Elapsed.TotalSeconds;

            Console.WriteLine(
                "Test finished in {0} sec, {1}% of target time {2} sec. Permitted variance is +/-{3}%",
                actualSec,
                actualSec / targetTimeSec * 100,
                targetTimeSec,
                variance * 100);

            Assert.IsTrue(capacityReached.IsSet, "Pipeline capacity not reached; the delay length probably is too short to be useful.");
            Assert.IsTrue(
                actualSec >= minTimeSec,
                string.Format("The unit test completed too early ({0} sec < {1} sec).", actualSec, minTimeSec));
            Assert.IsTrue(
                actualSec <= maxTimeSec,
                string.Format("The unit test completed too late ({0} sec > {1} sec).", actualSec, maxTimeSec));
        }