public void JoinBackground(ITransportClient client) { double avgBytesPerSec = 0; var lastTime = DateTime.MinValue; var buffer = new byte[0]; Envelope envelope; long envelopeSize; unsafe { envelopeSize = sizeof(Envelope); } this.storeReader.Seek(this.interval); while (true) { if (this.storeReader.MoveNext(out envelope)) { var length = this.storeReader.Read(ref buffer); this.exporter.Throttle.Reset(); try { client.WriteMessage(envelope, buffer); if (lastTime > DateTime.MinValue /* at least second message */) { if (this.maxBytesPerSecond < long.MaxValue) { // throttle to arbitrary max BPS var elapsed = (envelope.OriginatingTime - lastTime).TotalSeconds; var bytesPerSec = (envelopeSize + length) / elapsed; double smoothingFactor = 1.0 / (this.bytesPerSecondSmoothingWindowSeconds / elapsed); avgBytesPerSec = (bytesPerSec * smoothingFactor) + (avgBytesPerSec * (1.0 - smoothingFactor)); if (bytesPerSec > this.maxBytesPerSecond) { var wait = (int)(((avgBytesPerSec / this.maxBytesPerSecond) - elapsed) * 1000.0); if (wait > 0) { Thread.Sleep(wait); } } } } lastTime = envelope.OriginatingTime; } finally { // writers continue upon failure - meanwhile, remote client may reconnect and resume based on replay interval this.exporter.Throttle.Set(); } } } }