@@ -21,19 +21,19 @@ internal static class StreamCopier
2121 private const int DefaultBufferSize = 65536 ;
2222 public const long UnknownLength = - 1 ;
2323
24- public static ValueTask < ( StreamCopyResult , Exception ? ) > CopyAsync ( bool isRequest , Stream input , Stream output , long promisedContentLength , IClock clock , ActivityCancellationTokenSource activityToken , CancellationToken cancellation )
25- => CopyAsync ( isRequest , input , output , promisedContentLength , clock , activityToken , autoFlush : false , cancellation ) ;
24+ public static ValueTask < ( StreamCopyResult , Exception ? ) > CopyAsync ( bool isRequest , Stream input , Stream output , long promisedContentLength , TimeProvider timeProvider , ActivityCancellationTokenSource activityToken , CancellationToken cancellation )
25+ => CopyAsync ( isRequest , input , output , promisedContentLength , timeProvider , activityToken , autoFlush : false , cancellation ) ;
2626
27- public static ValueTask < ( StreamCopyResult , Exception ? ) > CopyAsync ( bool isRequest , Stream input , Stream output , long promisedContentLength , IClock clock , ActivityCancellationTokenSource activityToken , bool autoFlush , CancellationToken cancellation )
27+ public static ValueTask < ( StreamCopyResult , Exception ? ) > CopyAsync ( bool isRequest , Stream input , Stream output , long promisedContentLength , TimeProvider timeProvider , ActivityCancellationTokenSource activityToken , bool autoFlush , CancellationToken cancellation )
2828 {
2929 Debug . Assert ( input is not null ) ;
3030 Debug . Assert ( output is not null ) ;
31- Debug . Assert ( clock is not null ) ;
31+ Debug . Assert ( timeProvider is not null ) ;
3232 Debug . Assert ( activityToken is not null ) ;
3333
34- // Avoid capturing 'isRequest' and 'clock ' in the state machine when telemetry is disabled
34+ // Avoid capturing 'isRequest' and 'timeProvider ' in the state machine when telemetry is disabled
3535 var telemetry = ForwarderTelemetry . Log . IsEnabled ( EventLevel . Informational , EventKeywords . All )
36- ? new StreamCopierTelemetry ( isRequest , clock )
36+ ? new StreamCopierTelemetry ( isRequest , timeProvider )
3737 : null ;
3838
3939 return CopyAsync ( input , output , promisedContentLength , telemetry , activityToken , autoFlush , cancellation ) ;
@@ -142,48 +142,46 @@ internal static class StreamCopier
142142
143143 private sealed class StreamCopierTelemetry
144144 {
145- private static readonly TimeSpan _timeBetweenTransferringEvents = TimeSpan . FromSeconds ( 1 ) ;
146-
147145 private readonly bool _isRequest ;
148- private readonly IClock _clock ;
146+ private readonly TimeProvider _timeProvider ;
149147 private long _contentLength ;
150148 private long _iops ;
151- private TimeSpan _readTime ;
152- private TimeSpan _writeTime ;
153- private TimeSpan _firstReadTime ;
154- private TimeSpan _lastTime ;
155- private TimeSpan _nextTransferringEvent ;
149+ private long _readTime ;
150+ private long _writeTime ;
151+ private long _firstReadTime ;
152+ private long _lastTime ;
153+ private long _nextTransferringEvent ;
156154
157- public StreamCopierTelemetry ( bool isRequest , IClock clock )
155+ public StreamCopierTelemetry ( bool isRequest , TimeProvider timeProvider )
158156 {
159157 _isRequest = isRequest ;
160- _clock = clock ?? throw new ArgumentNullException ( nameof ( clock ) ) ;
161- _firstReadTime = new TimeSpan ( - 1 ) ;
158+ _timeProvider = timeProvider ?? throw new ArgumentNullException ( nameof ( timeProvider ) ) ;
159+ _firstReadTime = - 1 ;
162160
163161 ForwarderTelemetry . Log . ForwarderStage ( isRequest ? ForwarderStage . RequestContentTransferStart : ForwarderStage . ResponseContentTransferStart ) ;
164162
165- _lastTime = clock . GetStopwatchTime ( ) ;
166- _nextTransferringEvent = _lastTime + _timeBetweenTransferringEvents ;
163+ _lastTime = timeProvider . GetTimestamp ( ) ;
164+ _nextTransferringEvent = _lastTime + _timeProvider . TimestampFrequency ;
167165 }
168166
169167 public void AfterRead ( long contentLength )
170168 {
171169 _contentLength = contentLength ;
172170 _iops ++ ;
173171
174- var readStop = _clock . GetStopwatchTime ( ) ;
172+ var readStop = _timeProvider . GetTimestamp ( ) ;
175173 var currentReadTime = readStop - _lastTime ;
176174 _lastTime = readStop ;
177175 _readTime += currentReadTime ;
178- if ( _firstReadTime . Ticks < 0 )
176+ if ( _firstReadTime < 0 )
179177 {
180178 _firstReadTime = currentReadTime ;
181179 }
182180 }
183181
184182 public void AfterWrite ( )
185183 {
186- var writeStop = _clock . GetStopwatchTime ( ) ;
184+ var writeStop = _timeProvider . GetTimestamp ( ) ;
187185 _writeTime += writeStop - _lastTime ;
188186 _lastTime = writeStop ;
189187
@@ -193,12 +191,12 @@ public void AfterWrite()
193191 _isRequest ,
194192 _contentLength ,
195193 _iops ,
196- _readTime . Ticks ,
197- _writeTime . Ticks ) ;
194+ _timeProvider . GetElapsedTime ( 0 , _readTime ) . Ticks ,
195+ _timeProvider . GetElapsedTime ( 0 , _writeTime ) . Ticks ) ;
198196
199197 // Avoid attributing the time taken by logging ContentTransferring to the next read call
200- _lastTime = _clock . GetStopwatchTime ( ) ;
201- _nextTransferringEvent = _lastTime + _timeBetweenTransferringEvents ;
198+ _lastTime = _timeProvider . GetTimestamp ( ) ;
199+ _nextTransferringEvent = _lastTime + _timeProvider . TimestampFrequency ;
202200 }
203201 }
204202
@@ -208,9 +206,9 @@ public void Stop()
208206 _isRequest ,
209207 _contentLength ,
210208 _iops ,
211- _readTime . Ticks ,
212- _writeTime . Ticks ,
213- Math . Max ( 0 , _firstReadTime . Ticks ) ) ;
209+ _timeProvider . GetElapsedTime ( 0 , _readTime ) . Ticks ,
210+ _timeProvider . GetElapsedTime ( 0 , _writeTime ) . Ticks ,
211+ _timeProvider . GetElapsedTime ( 0 , Math . Max ( 0 , _firstReadTime ) ) . Ticks ) ;
214212 }
215213 }
216214}
0 commit comments