コード例 #1
0
        private Task StartCore()
        {
            _stopwatch.Start();

            // Spin up a thread dedicated to outputting stats for each defined interval
            new Thread(() =>
            {
                while (!_cts.IsCancellationRequested)
                {
                    Thread.Sleep(_config.DisplayInterval);
                    lock (Console.Out) { _aggregator.PrintCurrentResults(_stopwatch.Elapsed, showAggregatesOnly: false); }
                }
            })
            {
                IsBackground = true
            }.Start();

            IEnumerable <Task> workers = CreateWorkerSeeds().Select(x => RunSingleWorker(x.workerId, x.random));

            return(Task.WhenAll(workers));

            async Task RunSingleWorker(int workerId, Random random)
            {
                StreamCounter counter = _aggregator.GetCounters(workerId);

                for (long jobId = 0; !_cts.IsCancellationRequested; jobId++)
                {
                    TimeSpan connectionLifetime = _config.MinConnectionLifetime + random.NextDouble() * (_config.MaxConnectionLifetime - _config.MinConnectionLifetime);
                    TimeSpan cancellationDelay  =
                        (random.NextBoolean(probability: _config.CancellationProbability)) ?
                        connectionLifetime * random.NextDouble() :     // cancel in a random interval within the lifetime
                        connectionLifetime + TimeSpan.FromSeconds(10); // otherwise trigger cancellation 10 seconds after expected expiry

                    using var cts = CancellationTokenSource.CreateLinkedTokenSource(_cts.Token);
                    cts.CancelAfter(cancellationDelay);

                    bool isTestCompleted = false;
                    using var _ = cts.Token.Register(CheckForStalledConnection);

                    try
                    {
                        using var client = new TcpClient();
                        await client.ConnectAsync(_config.ServerEndpoint.Address, _config.ServerEndpoint.Port);

                        var stream = new CountingStream(client.GetStream(), counter);
                        using SslStream sslStream = await EstablishSslStream(stream, random, cts.Token);
                        await HandleConnection(workerId, jobId, sslStream, client, random, connectionLifetime, cts.Token);

                        _aggregator.RecordSuccess(workerId);
                    }
                    catch (OperationCanceledException) when(cts.IsCancellationRequested)
                    {
                        _aggregator.RecordCancellation(workerId);
                    }
                    catch (Exception e)
                    {
                        _aggregator.RecordFailure(workerId, e);
                    }
                    finally
                    {
                        isTestCompleted = true;
                    }

                    async void CheckForStalledConnection()
                    {
                        await Task.Delay(10_000);

                        if (!isTestCompleted)
                        {
                            lock (Console.Out)
                            {
                                Console.ForegroundColor = ConsoleColor.Red;
                                Console.WriteLine($"Worker #{workerId} test #{jobId} has stalled, terminating the stress app.");
                                Console.WriteLine();
                                Console.ResetColor();
                            }
                            Environment.Exit(1);
                        }
                    }
                }
            }

            IEnumerable <(int workerId, Random random)> CreateWorkerSeeds()
            {
                // deterministically generate random instance for each individual worker
                Random random = new Random(_config.RandomSeed);

                for (int workerId = 0; workerId < _config.MaxConnections; workerId++)
                {
                    yield return(workerId, random.NextRandom());
                }
            }
        }
コード例 #2
0
 public void Setup()
 {
     wordCounter = new StreamCounter();
 }