예제 #1
0
        public void Dispose_ExceptionInWorkerPropagates(int totThreads)
        {
            TaskCompletionSource <object> taskBlocker1 = new TaskCompletionSource <object>();

            void DoMockWorkBlocking(MockWorkIn work, CancellationToken token)
            {
                taskBlocker1.Task.Wait();
                throw new MockException();
            }

            CancellationTokenSource ts = new CancellationTokenSource();
            var cfg = new MultiThreadedWorkerConfig(totThreads);
            MultiThreadedWorker <MockWorkIn> mtw = new MultiThreadedWorker <MockWorkIn>(cfg, DoMockWorkBlocking);

            mtw.AddWorkItem(new MockWorkIn(1), ts.Token);

            TestDelegate disposeDel = delegate()
            {
                try
                {
                    taskBlocker1.SetResult(null);
                    mtw.Dispose();
                }
                catch (AggregateException ex)
                {
                    throw ex.InnerException;
                }
            };

            Assert.Throws <MockException>(disposeDel);
        }
예제 #2
0
        public void Dispose_CancelsPendingTasks(int totThreads, bool cancelsDuringWork)
        {
            TaskCompletionSource <object> taskBlocker1 = new TaskCompletionSource <object>();
            bool completed = false;

            void DoMockWorkBlocking(MockWorkIn work, CancellationToken token)
            {
                taskBlocker1.Task.Wait();
                Task.Delay(1, token).Wait();
                completed = true;
            }

            CancellationTokenSource ts = new CancellationTokenSource();
            var cfg = new MultiThreadedWorkerConfig(totThreads);
            MultiThreadedWorker <MockWorkIn> mtw = new MultiThreadedWorker <MockWorkIn>(cfg, DoMockWorkBlocking);

            mtw.AddWorkItem(new MockWorkIn(1), ts.Token);
            if (cancelsDuringWork)
            {
                ts.Cancel();
            }
            taskBlocker1.SetResult(null);

            Assert.DoesNotThrow(mtw.Dispose);

            Assert.AreEqual(!cancelsDuringWork, completed);
        }
예제 #3
0
        private static async Task <ExitCode> RunAllInParallel(List <Assembly> assemblies, RunOptions runOptions, uint threads)
        {
            _teamCityGlobalReporter.OnRunStart();

            var worker = new MultiThreadedWorker <Assembly, ExitCode>(assemblies,
                                                                      (assembly) => RunAssembly(assembly, runOptions),
                                                                      threads);
            IEnumerable <ExitCode> result = await worker.Run();

            FlushTeamCityOutput();

            _teamCityGlobalReporter.OnRunEnd();

            if (result.Any(e => e == ExitCode.Error))
            {
                return(ExitCode.Error);
            }
            else if (result.Any(e => e == ExitCode.Failure))
            {
                return(ExitCode.Failure);
            }
            else
            {
                return(ExitCode.Success);
            }
        }
예제 #4
0
        public void AddWorkItem_Cancels(int totThreads)
        {
            MockWorker mw = new MockWorker();
            CancellationTokenSource ts = new CancellationTokenSource();
            var cfg = new MultiThreadedWorkerConfig(totThreads);
            MultiThreadedWorker <MockWorkIn> mtw = new MultiThreadedWorker <MockWorkIn>(cfg, mw.DoMockWorkBlocking);

            mtw.AddWorkItem(new MockWorkIn(1), ts.Token);

            mw.TriggerOnBlockedWorkAsync(() => ts.Cancel()).Wait();

            Assert.AreEqual(1, mw.doneWork.Count(f => f.Item1));
            Assert.AreEqual(1, mw.doneWork.Count());
        }
예제 #5
0
        public void AddWorkItem_ItemsProcessed(int totItems, int totThreads, int maxQueuedItems)
        {
            MockWorker mw = new MockWorker();
            CancellationTokenSource ts = new CancellationTokenSource();
            var cfg = GetConfig(totThreads, maxQueuedItems);

            using (MultiThreadedWorker <MockWorkIn> mtw = new MultiThreadedWorker <MockWorkIn>(cfg, mw.DoMockWork_Simple))
            {
                foreach (int inputIx in Enumerable.Range(1, totItems))
                {
                    mtw.AddWorkItem(new MockWorkIn(inputIx), ts.Token);
                }
                mtw.Flush(ts.Token);
            }

            Assert.AreEqual(Enumerable.Range(1, totItems), mw.doneWork.Where(f => !f.Item1).OrderBy(f => f.Item2.ix).Select(f => f.Item2.ix));
        }
예제 #6
0
        public void AddWorkItemAsync_OneItemProcessed()
        {
            MockWorker mw = new MockWorker();
            CancellationTokenSource ts = new CancellationTokenSource();
            int inputIx        = 1;
            int totThreads     = 1;
            int maxQueuedItems = 1;
            var cfg            = GetConfig(totThreads, maxQueuedItems);

            using (MultiThreadedWorker <MockWorkIn> mtw = new MultiThreadedWorker <MockWorkIn>(cfg, mw.DoMockWork_Simple))
            {
                mtw.AddWorkItem(new MockWorkIn(inputIx), ts.Token);
            }

            Assert.AreEqual(1, mw.doneWork.Count);
            Assert.AreEqual(false, mw.doneWork.First().Item1);
            Assert.AreEqual(inputIx, mw.doneWork.First().Item2.ix);
        }
        private static async Task<ExitCode> RunAllInParallel(List<Assembly> assemblies, RunOptions runOptions, uint threads)
        {
            _teamCityGlobalReporter.OnRunStart();

            var worker = new MultiThreadedWorker<Assembly, ExitCode>(assemblies,
                                                                     (assembly) => RunAssembly(assembly, runOptions),
                                                                     threads);
            IEnumerable<ExitCode> result = await worker.Run();

            FlushTeamCityOutput();

            _teamCityGlobalReporter.OnRunEnd();

            if (result.Any(e => e == ExitCode.Error))
                return ExitCode.Error;
            else if (result.Any(e => e == ExitCode.Failure))
                return ExitCode.Failure;
            else
                return ExitCode.Success;
        }
예제 #8
0
        public TFrameList Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
        {
            if (reader.TryReadNil())
            {
                return((TFrameList)(IList <T>)null);
            }

            Interlocked.Increment(ref ParallelGatekeeperSingleton.wrapperDepth);
            try
            {
                options.Security.DepthStep(ref reader);
                try
                {
                    FrameFormatterSerializationOptions frameOptions = options.GetOptionParams();
                    if (frameOptions.MthWorkerConfig.MaxConcurrentTasks == 1 || ParallelGatekeeperSingleton.wrapperDepth > 1)
                    {
                        return(DeserializeSynchronous(ref reader, options));
                    }

                    var readerBackup = reader.CreatePeekReader();
                    int count        = reader.ReadArrayHeader();
                    if (count == 0)
                    {
                        reader = readerBackup;
                        return(DeserializeSynchronous(ref reader, options));
                    }
                    var peekreader = reader.CreatePeekReader();
                    if (FrameItemFormatter <T> .ReadElementHeader(ref peekreader) == Frame <T> .unassigned)
                    {
                        if (frameOptions.ThrowOnUnnasignedFrameDeserialization)
                        {
                            throw new StreamSerializationException($"Unassigned buffer length found during parallel deserialize for {nameof(TFrameList)}");
                        }
                        reader = readerBackup;
                        return(DeserializeSynchronous(ref reader, options));
                    }

                    IMessagePackFormatter <T> formatterT   = options.Resolver.GetFormatterWithVerify <T>();
                    ListFrameWrapper          valueWrapper = GetTFrameListWrapper(count);
                    Frame <T>[]        resItems            = valueWrapper.AsFrameArray();
                    BatchSizeEstimator batchEstimator      = new BatchSizeEstimator(frameOptions.BatchSizeEstimatorConfig);

                    void ProcessBatch(BatchWithBufferWritersAndElementOffset batch, CancellationToken token)
                    {
                        try
                        {
                            ReadOnlySpan <int>    lengths = batch.buffers.lengths.WrittenSpan;
                            ReadOnlyMemory <byte> bodies  = batch.buffers.concatenatedBodies.WrittenMemory;
                            int batchSize = batch.buffers.lengths.WrittenCount;
                            var destSpan  = resItems.AsSpan(batch.offset, batchSize);

                            for (int ix = 0, bodyStartIx = 0; ix < batchSize; ix++)
                            {
                                int itemLen = lengths[ix];
                                ReadOnlyMemory <byte> body      = bodies.Slice(bodyStartIx, itemLen);
                                MessagePackReader     tmpReader = new MessagePackReader(body)
                                {
                                    CancellationToken = token
                                };
                                destSpan[ix].BufferLength = body.Length;
                                destSpan[ix].Item         = formatterT.Deserialize(ref tmpReader, options);
                                bodyStartIx += itemLen;
                            }
                        }
                        finally
                        {
                            objPoolBufferWriterBodies.Return(batch.buffers.concatenatedBodies);
                            objPoolBufferWriterBodyLengths.Return(batch.buffers.lengths);
                        }
                    }

                    using (var mtw = new MultiThreadedWorker <BatchWithBufferWritersAndElementOffset>(
                               frameOptions.MthWorkerConfig, ProcessBatch))
                    {
                        int i = 0;
                        while (i < count)
                        {
                            int batchSize    = Math.Min(count - i, batchEstimator.RecomendedBatchSize);
                            var currentBatch = new BatchWithBufferWritersAndElementOffset()
                            {
                                offset  = i,
                                buffers = new BatchWithBufferWriters()
                                {
                                    concatenatedBodies = objPoolBufferWriterBodies.Get(),
                                    lengths            = objPoolBufferWriterBodyLengths.Get()
                                }
                            };
                            for (int seqIx = 0; seqIx < batchSize; seqIx++)
                            {
                                int itemLength = FrameItemFormatter <T> .ReadElementHeader(ref reader);

                                if (itemLength == Frame <T> .unassigned)
                                {
                                    throw new StreamSerializationException($"Unassigned buffer length found during parallel deserialize for {nameof(TFrameList)}");
                                }
                                currentBatch.buffers.lengths.GetSpan(1)[0] = itemLength;
                                currentBatch.buffers.lengths.Advance(1);
                                ReadOnlySequence <byte> raw = reader.ReadRaw(itemLength);
                                raw.CopyTo(currentBatch.buffers.concatenatedBodies.GetSpan(itemLength));
                                currentBatch.buffers.concatenatedBodies.Advance(itemLength);
                                batchEstimator.UpdateEstimate(itemLength);
                            }
                            mtw.AddWorkItem(currentBatch, reader.CancellationToken);
                            i += batchSize;
                        }
                    }
                    return(valueWrapper.AsFrameList());
                }
                finally
                {
                    reader.Depth--;
                }
            }
            finally
            {
                Interlocked.Decrement(ref ParallelGatekeeperSingleton.wrapperDepth);
            }
        }