Example #1
0
 public IObservable <Tuple <Target, Message> > Map <Source, Target>(IObservable <Tuple <Source, Message> > source, IDictionary <Source, Target> target_by_source)
 {
     return(RX.Create <Tuple <Target, Message> >(observer =>
     {
         return source.Subscribe(
             source_node_message =>
         {
             try
             {
                 Target target_node;
                 bool found_target;
                 using (Concurrency.ReaderLock(_mutex))
                 {
                     found_target = target_by_source.TryGetValue(source_node_message.Item1, out target_node);
                 }
                 if (found_target)
                 {
                     var target_node_message = Tuple.Create(target_node, source_node_message.Item2);
                     observer.OnNext(target_node_message);
                 }
             }
             catch (Exception error)
             {
                 observer.OnError(error);
             }
         },
             observer.OnError,
             observer.OnCompleted
             );
     }));
 }
Example #2
0
        public void Test()
        {
            var lockParser = new InstanceLockParser <Model>(nameof(NStandard), x => x.Year, x => x.Month, x => x.Sex, x => "const");
            var model      = new Model {
                Year = 2012, Month = 4,
            };

            var stopwatch = new Stopwatch();

            stopwatch.Start();
            var result = Concurrency.Run(resultId =>
            {
                using (var _lock = lockParser.Parse(model).TryBegin(500))
                {
                    if (_lock.Value)
                    {
                        Thread.Sleep(1000);
                        return("Entered");
                    }
                    else
                    {
                        return("Timeout");
                    }
                }
            }, level: 2, threadCount: 2);

            stopwatch.Stop();

            Assert.Equal(1, result.Values.Count(x => x == "Entered"));
            Assert.Equal(1, result.Values.Count(x => x == "Timeout"));
            Assert.True(stopwatch.ElapsedMilliseconds < 2000);
        }
Example #3
0
        public void UpdateConflictTest()
        {
#if NETFX
            using (new TransactionHelper())
            {
                Concurrency.DatabaseWins(new DbReaderWriter(new AdventureWorks()), new DbReaderWriter(new AdventureWorks()), new DbReaderWriter(new AdventureWorks()));
            }
            using (new TransactionHelper())
            {
                Concurrency.ClientWins(new DbReaderWriter(new AdventureWorks()), new DbReaderWriter(new AdventureWorks()), new DbReaderWriter(new AdventureWorks()));
            }
            using (new TransactionHelper())
            {
                Concurrency.MergeClientAndDatabase(new DbReaderWriter(new AdventureWorks()), new DbReaderWriter(new AdventureWorks()), new DbReaderWriter(new AdventureWorks()));
            }
            using (new TransactionHelper())
            {
                Concurrency.SaveChanges(new AdventureWorks(), new AdventureWorks());
            }
#else
            Rollback((adventureWorks1, adventureWorks2, adventureWorks3) =>
                     Concurrency.DatabaseWins(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2), new DbReaderWriter(adventureWorks3)));
            Rollback((adventureWorks1, adventureWorks2, adventureWorks3) =>
                     Concurrency.ClientWins(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2), new DbReaderWriter(adventureWorks3)));
            Rollback((adventureWorks1, adventureWorks2, adventureWorks3) =>
                     Concurrency.MergeClientAndDatabase(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2), new DbReaderWriter(adventureWorks3)));
            Rollback((adventureWorks1, adventureWorks2) =>
                     Concurrency.SaveChanges(adventureWorks1, adventureWorks2));
#endif
        }
Example #4
0
        public void Test()
        {
            var lockParser = new TypeLockParser(nameof(NStandard));

            var stopwatch = new Stopwatch();

            stopwatch.Start();
            var result = Concurrency.Run(resultId =>
            {
                using (var _lock = lockParser.Parse <TypeLockTest>().TryBegin(500))
                {
                    if (_lock.Value)
                    {
                        Thread.Sleep(1000);
                        return("Entered");
                    }
                    else
                    {
                        return("Timeout");
                    }
                }
            }, level: 2, threadCount: 2);

            stopwatch.Stop();

            Assert.Equal(1, result.Values.Count(x => x == "Entered"));
            Assert.Equal(1, result.Values.Count(x => x == "Timeout"));
            Assert.True(stopwatch.ElapsedMilliseconds < 1900);
        }
        public void DbOverrideSimpleBatchTest(int concurrencyCount)
        {
            string      tmpFile = string.Empty;
            MultiDbData multiData;

            try
            {
                (tmpFile, multiData) = GetMultiDbData();
                var    flattened      = Concurrency.FlattenOverride(multiData);
                int    totalRowCount  = flattened.Count();
                double expectedChunks = Math.Ceiling((double)totalRowCount / (double)concurrencyCount);
                int    lastBatchSize  = totalRowCount;

                var output = Concurrency.ConcurrencyByInt(multiData, concurrencyCount);
                Assert.IsTrue(expectedChunks <= output[0].Count() && output[0].Count() >= expectedChunks - 1);
                Assert.AreEqual(concurrencyCount, output.Count());
                // Assert.AreEqual(lastBatchSize, output.Last().Count());
            }
            finally
            {
                if (File.Exists(tmpFile))
                {
                    File.Delete(tmpFile);
                }
            }
        }
        public void ParseString(string text, IGUIFont font, SpecialCharacterFlags flags = SpecialCharacterFlags.None)
        {
            Length = 0;
            GlyphChar[] tmp = null;
            if (!String.IsNullOrEmpty(text) && font != null)
            {
                tmp = new GlyphChar[text.Length];
                int w = 0;
                for (int i = 0; i < text.Length; i++)
                {
                    GlyphChar g = font.GetGlyph(text [i], flags);
                    w      += g.Width;
                    tmp [i] = g;
                }

                Width  = w;
                Length = text.Length;
            }

            if (tmp == null)
            {
                tmp = new GlyphChar[0];
            }

            if (m_Glyphs == null)               // called from constructor
            {
                m_Glyphs = tmp;
            }
            else
            {
                Concurrency.LockFreeUpdate(ref m_Glyphs, tmp);
            }
        }
Example #7
0
 public void DetectConflictTest()
 {
     using (new TransactionScope())
     {
         Concurrency.NoCheck();
     }
     using (new TransactionScope())
     {
         try
         {
             Concurrency.ConcurrencyCheck();
             Assert.Fail();
         }
         catch (DbUpdateConcurrencyException exception)
         {
             Trace.WriteLine(exception);
         }
     }
     using (new TransactionScope())
     {
         try
         {
             Concurrency.RowVersion();
             Assert.Fail();
         }
         catch (DbUpdateConcurrencyException exception)
         {
             Trace.WriteLine(exception);
         }
     }
 }
Example #8
0
 private async Task OnNextAsync(Tuple <string, Message> item)
 {
     try
     {
         this.TraceMessage(true, item);
         if (this.IsSelf(item.Item1))
         {
             this.Incoming.OnNext(item);
         }
         else if (!this.groupConfig.Settings.IsUseHttpTransportForInstanceCommunication)
         {
             ChannelFactory <IDxStoreInstance> factory = this.GetChannelFactory(item.Item1);
             await Concurrency.DropContext(WCF.WithServiceAsync <IDxStoreInstance>(factory, (IDxStoreInstance instance) => instance.PaxosMessageAsync(this.groupConfig.Self, item.Item2), null, default(CancellationToken)));
         }
         else
         {
             HttpRequest.PaxosMessage msg = new HttpRequest.PaxosMessage(this.nodeEndPoints.Self, item.Item2);
             string targetHost            = this.groupConfig.GetMemberNetworkAddress(item.Item1);
             await HttpClient.SendMessageAsync(targetHost, item.Item1, this.groupConfig.Name, msg);
         }
     }
     catch (Exception ex)
     {
         if (GroupMembersMesh.Tracer.IsTraceEnabled(TraceType.ErrorTrace))
         {
             GroupMembersMesh.Tracer.TraceError((long)this.identity.GetHashCode(), "{0}: OnNextAsync(Node:{1}, Msg:{2}) failed with {3}", new object[]
             {
                 this.identity,
                 item.Item1,
                 item.Item2,
                 ex
             });
         }
     }
 }
Example #9
0
    // Throws an exception on error.
    public static void Start(string serverHost, int serverTcpPort, int serverUdpPort, string logfilePath)
    {
        _logger = new Logger(logfilePath);

        // open TCP socket
        Socket tcpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        _logger.Log(string.Format("TCP connecting to {0}:{1}...", serverHost, serverTcpPort));
        tcpSocket.Connect(serverHost, serverTcpPort);
        _logger.Log(string.Format("...TCP connected to {0}", Utils.IPAddressToString(tcpSocket.RemoteEndPoint)));
        _address = Utils.IPAddressToString(tcpSocket.LocalEndPoint);

        _logger.Log("starting UDP client...");
        UdpClient udpClient     = new UdpClient(serverHost, serverUdpPort);
        int       clientUdpPort = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port;

        _logger.Log(string.Format("...started UDP client on port {0}", clientUdpPort));

        _logger.Log("sending UDP port to server...");
        Protocol.Send(tcpSocket, clientUdpPort);
        _logger.Log("...sent UDP port to server");

        Concurrency.StartThread(() => UdpSender(udpClient), "client UDP sender", _logger);
        Concurrency.StartThread(() => UdpReceiver(udpClient), "client UDP receiver", _logger);
        Concurrency.StartThread(() => TcpSender(tcpSocket), "client TCP sender", _logger);
        Concurrency.StartThread(() => TcpReceiver(tcpSocket), "client TCP receiver", _logger);
    }
Example #10
0
 public void DetectConflictTest()
 {
     Rollback((adventureWorks1, adventureWorks2, adventureWorks3) => Concurrency.NoCheck(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2), new DbReaderWriter(adventureWorks3)));
     Rollback((adventureWorks1, adventureWorks2) =>
     {
         try
         {
             Concurrency.ConcurrencyCheck(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2));
             Assert.Fail();
         }
         catch (DbUpdateConcurrencyException exception)
         {
             Trace.WriteLine(exception);
         }
     });
     Rollback((adventureWorks1, adventureWorks2) =>
     {
         try
         {
             Concurrency.RowVersion(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2));
             Assert.Fail();
         }
         catch (DbUpdateConcurrencyException exception)
         {
             Trace.WriteLine(exception);
         }
     });
 }
Example #11
0
        public void DetectConflictTest()
        {
#if NETFX
            using (new TransactionHelper())
            {
                Concurrency.NoCheck(new DbReaderWriter(new AdventureWorks()), new DbReaderWriter(new AdventureWorks()), new DbReaderWriter(new AdventureWorks()));
            }
            using (new TransactionHelper())
            {
                try
                {
                    Concurrency.ConcurrencyCheck(new DbReaderWriter(new AdventureWorks()), new DbReaderWriter(new AdventureWorks()));
                    Assert.Fail();
                }
                catch (DbUpdateConcurrencyException exception)
                {
                    Trace.WriteLine(exception);
                }
            }
            using (new TransactionHelper())
            {
                try
                {
                    Concurrency.RowVersion(new DbReaderWriter(new AdventureWorks()), new DbReaderWriter(new AdventureWorks()));
                    Assert.Fail();
                }
                catch (DbUpdateConcurrencyException exception)
                {
                    Trace.WriteLine(exception);
                }
            }
#else
            Rollback((adventureWorks1, adventureWorks2, adventureWorks3) => Concurrency.NoCheck(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2), new DbReaderWriter(adventureWorks3)));
            Rollback((adventureWorks1, adventureWorks2) =>
            {
                try
                {
                    Concurrency.ConcurrencyCheck(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2));
                    Assert.Fail();
                }
                catch (DbUpdateConcurrencyException exception)
                {
                    Trace.WriteLine(exception);
                }
            });
            Rollback((adventureWorks1, adventureWorks2) =>
            {
                try
                {
                    Concurrency.RowVersion(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2));
                    Assert.Fail();
                }
                catch (DbUpdateConcurrencyException exception)
                {
                    Trace.WriteLine(exception);
                }
            });
#endif
        }
        public void MatchServersToFixedBucket()
        {
            try
            {
                int    targetBuckets = 3;
                int    serverCount   = 40;
                int    minDbCount    = 10;
                int    maxDbCount    = 500;
                Random rnd           = new Random();

                string      tmpFile = string.Empty;
                MultiDbData multiData;
                try
                {
                    for (int i = 0; i < 100; i++)
                    {
                        targetBuckets = rnd.Next(2, 90);
                        serverCount   = rnd.Next(targetBuckets + 1, 300);
                        minDbCount    = rnd.Next(10, 150);
                        maxDbCount    = rnd.Next(minDbCount + 1, 500);
                        int[] matrix;
                        (tmpFile, multiData) = CreateRandomizedMultiDbData(serverCount, minDbCount, maxDbCount, out matrix);

                        //The real work
                        var buckets = Concurrency.RecombineServersToFixedBucketCount(multiData, targetBuckets);

                        //Numbers for comparisons
                        var flattened    = Concurrency.ConcurrencyByServer(multiData);
                        var idealBucket  = Math.Ceiling((double)flattened.Sum(c => c.Count()) / (double)targetBuckets);
                        int maxBucket    = flattened.Where(c => c.Count() <= idealBucket).Max(c => c.Count()); //exclude the buckets that were already above the ideal
                        int medianBucket = flattened.OrderBy(c => c.Count()).ToList()[(flattened.Count() / 2) + 1].Count();

                        string message = $"Buckets: {targetBuckets}; Servers: {serverCount}; Matrix: {string.Join(",", matrix)}";
                        Assert.AreEqual(targetBuckets, buckets.Count(), message);
                        Assert.IsTrue(buckets.Max(c => c.Count()) < maxBucket + (idealBucket * 1.2), message);


                        var str = Concurrency.ConvertBucketsToConfigLines(buckets);

                        if (File.Exists(tmpFile))
                        {
                            File.Delete(tmpFile);
                        }
                    }
                }
                finally
                {
                    if (File.Exists(tmpFile))
                    {
                        File.Delete(tmpFile);
                    }
                }
            }
            catch (OutOfMemoryException)
            {
                //GitHub actions sometimes will run out of memory running this test!
            }
        }
Example #13
0
        public async Task Test_await_Task_result()
        {
            var sut = new Concurrency();
            // Also unlike Go's goroutine, Task can 'returns' result after the task completed.
            var result = await sut.BenchmarkSayAsync("Hi", TimeSpan.FromMilliseconds(5));

            // note: there's always overhead to run async operations.
            Assert.True(result > TimeSpan.FromMilliseconds(25));
        }
 static TSagaData SetConcurrency <TSagaData>(Concurrency <TSagaData> result, ContextBag context)
     where TSagaData : IContainSagaData
 {
     if (!EqualityComparer <TSagaData> .Default.Equals(result.Data, default(TSagaData)))
     {
         context.Set("NServiceBus.Persistence.Sql.Concurrency", result.Version);
     }
     return(result.Data);
 }
Example #15
0
 public override Task ExecuteAsync(int instanceId, Proposal <string, DxStoreCommand> proposal)
 {
     return(Concurrency.RunSynchronously(delegate()
     {
         lock (this.locker)
         {
             this.ExecuteLocally(instanceId, proposal);
         }
     }));
 }
Example #16
0
 public void UpdateConflictTest()
 {
     Rollback((adventureWorks1, adventureWorks2, adventureWorks3) =>
              Concurrency.DatabaseWins(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2), new DbReaderWriter(adventureWorks3)));
     Rollback((adventureWorks1, adventureWorks2, adventureWorks3) =>
              Concurrency.ClientWins(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2), new DbReaderWriter(adventureWorks3)));
     Rollback((adventureWorks1, adventureWorks2, adventureWorks3) =>
              Concurrency.MergeClientAndDatabase(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2), new DbReaderWriter(adventureWorks3)));
     Rollback((adventureWorks1, adventureWorks2) =>
              Concurrency.SaveChanges(adventureWorks1, adventureWorks2));
 }
Example #17
0
    private static void AcceptTcpClients(Socket serverSocket)
    {
        while (true)
        {
            // accept client
            Socket clientSocket = serverSocket.Accept();
            _logger.Log(string.Format("accepted client from {0}", Utils.IPAddressToString(clientSocket.RemoteEndPoint)));

            Concurrency.StartThread(() => HandleTcpClient(clientSocket), "server handle client", _logger);
        }
    }
Example #18
0
        public void TestSay_Task_runs_concurrently()
        {
            var sut = new Concurrency();

            Task.Run(() => sut.Say("Hello", TimeSpan.FromMilliseconds(10)));
            sut.Say("World", TimeSpan.FromMilliseconds(1));

            var output = sut.Logs.ToArray();

            Assert.Equal(5, output.Length);
            Assert.Equal(5, output.Count(message => message.EndsWith("World")));
        }
Example #19
0
        public void RefreshGlyphs(IGUIFont font, SpecialCharacterFlags flags)
        {
            GlyphList glyphs = new GlyphList();

            foreach (GlyphChar g in Glyphs)
            {
                glyphs.AddLast(font.GetGlyph(g.Char, flags));
            }

            Concurrency.LockFreeUpdate(ref m_Glyphs, glyphs);
            NeedsWordWrap = true;
        }
 static TSagaData SetConcurrency <TSagaData>(Concurrency <TSagaData> result, ContextBag context)
     where TSagaData : IContainSagaData
 {
     // ReSharper disable once CompareNonConstrainedGenericWithNull
     //TODO: remove when core adds a class constraint to TSagaData
     if (result.Data == null)
     {
         return(default(TSagaData));
     }
     context.Set("NServiceBus.Persistence.Sql.Concurrency", result.Version);
     return(result.Data);
 }
Example #21
0
        public void Test1()
        {
            var generator = new IdGenerator <string>(() => DateTime.Now.Ticks.ToString());
            var level     = 100;

            var result = Concurrency.Run(cid =>
            {
                return(generator.TakeOne());
            }, level: level);

            Assert.Equal(level, result.Count);
            Assert.Equal(level, result.Select(x => x.Value).Distinct().Count());
        }
Example #22
0
        public void Test_wait_Task()
        {
            var sut = new Concurrency();
            // Unlike Go's goroutine, Task has its state.
            var task = Task.Run(() => sut.Say("Hi", TimeSpan.FromMilliseconds(5)));

            // wait task completes with timeout.
            task.Wait(TimeSpan.FromSeconds(1));

            var output = sut.Logs.ToArray();

            Assert.True(output.All(message => message == "Hi"));
        }
Example #23
0
        void ResetCachedData()
        {
            Concurrency.LockFreeUpdate(ref m_SortedVisibleColumns, Columns.SortedVisibleColumns.ToArray());

            var   lst    = new BinarySortedList <float> ();
            float offset = 0;

            Columns.Where(col => col.Visible).ForEach(col => {
                lst.AddLast(offset);
                offset += col.Width;
            });
            Concurrency.LockFreeUpdate(ref m_ColumnOffsets, lst);
        }
        public void LoadTextAsync(string value, float breakWidth)
        {
            BreakWidth = breakWidth;
            if (value == null)
            {
                value = String.Empty;
            }

            Task.Factory.StartNew(() => {
                Stopwatch sw = Stopwatch.StartNew();

                int index = 0;
                Paragraphs.Clear();
                ParagraphList paragraphs = new ParagraphList(LineHeight, BreakWidth);
                char splitChar           = AutoDetectLineBreakChar(value);

                if (!GroupParagraphs)
                {
                    Strings.Split(value, splitChar).ForEach(line =>
                                                            paragraphs.AddLast(new Paragraph(index++, BreakWidth, line, Font, Flags))
                                                            );
                }
                else
                {
                    const string splitStr = "\r\n\r\n";
                    Strings.Split(value, splitStr).ForEach(line => {
                        paragraphs.AddLast(new Paragraph(index++, BreakWidth, line.Replace("\n", " ") + "\n", Font, Flags));
                        paragraphs.AddLast(new Paragraph(index++, BreakWidth, "\n", Font, Flags));
                    });
                }

                paragraphs.OnUpdate();
                Concurrency.LockFreeUpdate(ref m_Paragraphs, paragraphs);

                this.LogVerbose("{0} characters of text in {1} paragraphs loaded into the editor in {2} ms.", value.Length.ToString("n0"), Paragraphs.Count.ToString("n0"), sw.ElapsedMilliseconds.ToString("n0"));
            }).ContinueWith((t) => {
                if (t.Status == TaskStatus.RanToCompletion)
                {
                    if (Paragraphs.BreakWidth != BreakWidth)
                    {
                        Paragraphs.OnUpdateBreakWidthAsync(BreakWidth);
                    }
                }
            }).ContinueWith((t) => {
                Owner.UndoRedoManager.Clear();
                if (LoadingCompleted != null)
                {
                    LoadingCompleted(this, EventArgs.Empty);
                }
            });
        }
Example #25
0
        public async Task Test_await_Task()
        {
            var sut = new Concurrency();
            // async/await pattern is recommended over 'blocking' methods.
            // but it forces to reimplement all blocking methods as they return Task or Task<T> type.
            await sut.SayAsync("Hi", TimeSpan.FromMilliseconds(5));

            // you can also  mix Task.Run and blocking method though, it is not recommended.
            // await Task.Run(() => sut.Say("Hi", TimeSpan.FromMilliseconds(5)));

            var output = sut.Logs.ToArray();

            Assert.True(output.All(message => message == "Hi"));
        }
Example #26
0
 private static void TcpSender(Socket socket)
 {
     while (true)
     {
         object obj = null;
         if (Concurrency.Dequeue(_tcpSendQueue, out obj))
         {
             System.Type type = obj.GetType();
             _logger.Log(string.Format("TCP sending object of type {0}...", type));
             Protocol.Send(socket, obj);
             _logger.Log(string.Format("...TCP sent object of type {0}", type));
         }
     }
 }
Example #27
0
        public void TestSay()
        {
            var sut      = new Concurrency();
            var duration = TimeSpan.FromMilliseconds(5);

            Task.Run(() => sut.Say("Hello", duration));
            sut.Say("World", duration);
            // wait for task same as Go's.
            Thread.Sleep(duration);

            var output = sut.Logs.ToArray();

            Assert.Equal(10, output.Length);
            Assert.Equal(5, output.Count(message => message.EndsWith("Hello")));
        }
Example #28
0
 public void ConflictTest()
 {
     Concurrency.DefaultControl();
     try
     {
         Concurrency.CheckModifiedDate();
         Assert.Fail();
     }
     catch (ChangeConflictException exception)
     {
         Trace.WriteLine(exception);
     }
     Concurrency.DatabaseWins();
     Concurrency.ClientWins();
     Concurrency.MergeClientAndDatabase();
 }
        public void InvertSelection()
        {
            int           rowCount = RowCount;
            HashSet <int> sel      = new HashSet <int> ();

            for (int i = 0; i < rowCount; i++)
            {
                if (!m_SelectedRowIndices.Contains(i))
                {
                    sel.Add(i);
                }
            }

            Concurrency.LockFreeUpdate(ref m_SelectedRowIndices, sel);
            OnSelectionChanged();
        }
        public void MatchServersToFixedBucket_ToConfigLines()
        {
            int    targetBuckets = 3;
            int    serverCount   = 40;
            int    minDbCount    = 10;
            int    maxDbCount    = 500;
            Random rnd           = new Random();

            string      tmpFile = string.Empty;
            MultiDbData multiData;

            try
            {
                for (int i = 0; i < 20; i++)
                {
                    targetBuckets = rnd.Next(2, 51);
                    serverCount   = rnd.Next(targetBuckets + 1, 400);
                    minDbCount    = rnd.Next(10, 201);
                    maxDbCount    = rnd.Next(minDbCount + 1, 600);
                    int[] matrix;
                    (tmpFile, multiData) = CreateRandomizedMultiDbData(serverCount, minDbCount, maxDbCount, out matrix);

                    var    buckets = Concurrency.RecombineServersToFixedBucketCount(multiData, targetBuckets);
                    var    str     = Concurrency.ConvertBucketsToConfigLines(buckets);
                    string message = $"Buckets: {targetBuckets}; Servers: {serverCount}; Matrix: {string.Join(",", matrix)}";
                    Assert.AreEqual(buckets.Count(), str.Count(), message);
                    for (int j = 0; j < buckets.Count(); j++)
                    {
                        Assert.AreEqual(buckets[j].Count(), str[j].Count(), message);
                        Assert.AreEqual(buckets[j].First().Item1, str[j].First().Substring(0, str[j].First().IndexOf(":")), message);
                        Assert.AreEqual(buckets[j].Last().Item1, str[j].Last().Substring(0, str[j].Last().IndexOf(":")), message);
                    }

                    if (File.Exists(tmpFile))
                    {
                        File.Delete(tmpFile);
                    }
                }
            }
            finally
            {
                if (File.Exists(tmpFile))
                {
                    File.Delete(tmpFile);
                }
            }
        }
        /// <summary>Does the test.</summary>
        /// <param name="level">The level.</param>
        /// <param name="concurrency">The concurrency.</param>
        /// <param name="transactionMode">The transaction mode.</param>
        private void DoTest(MessageCount level, Concurrency concurrency, TransactionModeUtils.TransactionMode transactionMode)
        {
            var messageCount = (int)level;
            var concurrentConsumers = (int)concurrency;
            var transactional = transactionMode.IsTransactional();

            var template = this.CreateTemplate(concurrentConsumers);

            var latch = new CountdownEvent(messageCount);
            for (var i = 0; i < messageCount; i++)
            {
                template.ConvertAndSend(queue.Name, i + "foo");
            }

            var container = new SimpleMessageListenerContainer(template.ConnectionFactory);
            var listener = new LifecyclePocoListener(latch);
            container.MessageListener = new MessageListenerAdapter(listener);
            container.AcknowledgeMode = transactionMode.AcknowledgeMode();
            container.ChannelTransacted = transactionMode.IsTransactional();
            container.ConcurrentConsumers = concurrentConsumers;

            if (transactionMode.Prefetch() > 0)
            {
                container.PrefetchCount = transactionMode.Prefetch();
                container.TxSize = transactionMode.TxSize();
            }

            container.QueueNames = new[] { queue.Name };
            container.AfterPropertiesSet();
            container.Start();

            try
            {
                var waited = latch.Wait(50);
                Logger.Info("All messages received before stop: " + waited);
                if (messageCount > 1)
                {
                    Assert.False(waited, "Expected not to receive all messages before stop");
                }

                Assert.AreEqual(concurrentConsumers, container.ActiveConsumerCount);
                container.Stop();
                Thread.Sleep(500);
                Assert.AreEqual(0, container.ActiveConsumerCount);
                if (!transactional)
                {
                    var messagesReceivedAfterStop = listener.Count;
                    waited = latch.Wait(500);
                    Logger.Info("All messages received after stop: " + waited);
                    if (messageCount < 100)
                    {
                        Assert.True(waited, "Expected to receive all messages after stop");
                    }

                    Assert.AreEqual(messagesReceivedAfterStop, listener.Count, "Unexpected additional messages received after stop");

                    for (var i = 0; i < messageCount; i++)
                    {
                        template.ConvertAndSend(queue.Name, i + "bar");
                    }

                    latch = new CountdownEvent(messageCount);
                    listener.Reset(latch);
                }

                var messagesReceivedBeforeStart = listener.Count;
                container.Start();
                var timeout = Math.Min(1 + messageCount / (4 * concurrentConsumers), 30);

                Logger.Debug("Waiting for messages with timeout = " + timeout + " (s)");
                waited = latch.Wait(timeout * 1000);
                Logger.Info("All messages received after start: " + waited);
                Assert.AreEqual(concurrentConsumers, container.ActiveConsumerCount);
                if (transactional)
                {
                    Assert.True(waited, "Timed out waiting for message");
                }
                else
                {
                    var count = listener.Count;
                    Assert.True(messagesReceivedBeforeStart < count, "Expected additional messages received after start: " + messagesReceivedBeforeStart + ">=" + count);
                    Assert.Null(template.Receive(queue.Name), "Messages still available");
                }

                Assert.AreEqual(concurrentConsumers, container.ActiveConsumerCount);
            }
            finally
            {
                // Wait for broker communication to finish before trying to stop
                // container
                Thread.Sleep(500);
                container.Shutdown();
                Assert.AreEqual(0, container.ActiveConsumerCount);
            }

            Assert.Null(template.ReceiveAndConvert(queue.Name));
        }