public SenderTask(Settings settings, Metrics metrics, CancellationToken cancellationToken)
     : base(settings, metrics, cancellationToken)
 {
     this.senders = new List <Task>();
 }
        async Task SendTask()
        {
            var sender    = new MessageSender(this.Settings.ConnectionString, this.Settings.SendPath, NoRetry.Default);
            var payload   = new byte[this.Settings.MessageSizeInBytes];
            var semaphore = new DynamicSemaphoreSlim(this.Settings.MaxInflightSends.Value);
            var done      = new SemaphoreSlim(1);

            done.Wait();
            long totalSends = 0;

            this.Settings.MaxInflightSends.Changing += (a, e) => AdjustSemaphore(e, semaphore);
            var sw = Stopwatch.StartNew();

            // first send will fail out if the cxn string is bad
            await sender.SendAsync(new Message(payload) { TimeToLive = TimeSpan.FromMinutes(5) });

            for (int j = 0; j < Settings.MessageCount && !this.CancellationToken.IsCancellationRequested; j++)
            {
                var sendMetrics = new SendMetrics()
                {
                    Tick = sw.ElapsedTicks
                };

                var nsec = sw.ElapsedTicks;
                semaphore.Wait();
                //await semaphore.WaitAsync().ConfigureAwait(false);
                sendMetrics.InflightSends         = this.Settings.MaxInflightSends.Value - semaphore.CurrentCount;
                sendMetrics.GateLockDuration100ns = sw.ElapsedTicks - nsec;

                if (Settings.SendDelay > 0)
                {
                    await Task.Delay(Settings.SendDelay);
                }
                if (Settings.SendBatchCount <= 1)
                {
                    sender.SendAsync(new Message(payload)
                    {
                        TimeToLive = TimeSpan.FromMinutes(5)
                    })
                    .ContinueWith(async(t) =>
                    {
                        if (t.IsFaulted || t.IsCanceled)
                        {
                            await HandleExceptions(semaphore, sendMetrics, t.Exception);
                        }
                        else
                        {
                            sendMetrics.SendDuration100ns = sw.ElapsedTicks - nsec;
                            sendMetrics.Sends             = 1;
                            sendMetrics.Messages          = 1;
                            semaphore.Release();
                            Metrics.PushSendMetrics(sendMetrics);
                        }
                        if (Interlocked.Increment(ref totalSends) >= Settings.MessageCount)
                        {
                            done.Release();
                        }
                    }).Fork();
                }
                else
                {
                    List <Message> batch = new List <Message>();
                    for (int i = 0; i < Settings.SendBatchCount && j < Settings.MessageCount && !this.CancellationToken.IsCancellationRequested; i++, j++)
                    {
                        batch.Add(new Message(payload)
                        {
                            TimeToLive = TimeSpan.FromMinutes(5)
                        });
                    }
                    sender.SendAsync(batch)
                    .ContinueWith(async(t) =>
                    {
                        if (t.IsFaulted || t.IsCanceled)
                        {
                            await HandleExceptions(semaphore, sendMetrics, t.Exception);
                        }
                        else
                        {
                            sendMetrics.SendDuration100ns = sw.ElapsedTicks - nsec;
                            sendMetrics.Sends             = 1;
                            sendMetrics.Messages          = Settings.SendBatchCount;
                            semaphore.Release();
                            Metrics.PushSendMetrics(sendMetrics);
                        }
                        if (Interlocked.Increment(ref totalSends) >= Settings.MessageCount)
                        {
                            done.Release();
                        }
                    }).Fork();
                }
            }
            await done.WaitAsync();
        }
Example #3
0
 public IncreaseInflightReceivesExperiment(int count, Metrics metrics, Settings settings) : base(metrics, settings)
 {
     this.count = count;
 }