@@ -21,7 +21,9 @@ internal class Reader<TValue> : IReader<TValue>
2121 private readonly ReaderConfig _config ;
2222 private readonly IDeserializer < TValue > _deserializer ;
2323 private readonly ILogger _logger ;
24- private readonly GrpcRequestSettings _readerGrpcRequestSettings ;
24+ private readonly GrpcRequestSettings _readerGrpcRequestSettings = new ( ) ;
25+
26+ private ReaderSession < TValue > ? _currentReaderSession ;
2527
2628 private readonly Channel < InternalBatchMessages < TValue > > _receivedMessagesChannel =
2729 Channel . CreateUnbounded < InternalBatchMessages < TValue > > (
@@ -41,7 +43,6 @@ internal Reader(IDriver driver, ReaderConfig config, IDeserializer<TValue> deser
4143 _config = config ;
4244 _deserializer = deserializer ;
4345 _logger = driver . LoggerFactory . CreateLogger < Reader < TValue > > ( ) ;
44- _readerGrpcRequestSettings = new GrpcRequestSettings { CancellationToken = _disposeCts . Token } ;
4546
4647 _ = Initialize ( ) ;
4748 }
@@ -68,7 +69,7 @@ public async ValueTask<Message<TValue>> ReadAsync(CancellationToken cancellation
6869 }
6970 }
7071
71- throw new ObjectDisposedException ( "Reader" ) ;
72+ throw new ReaderException ( "Reader is disposed " ) ;
7273 }
7374
7475 public async ValueTask < BatchMessages < TValue > > ReadBatchAsync ( CancellationToken cancellationToken = default )
@@ -86,7 +87,7 @@ public async ValueTask<BatchMessages<TValue>> ReadBatchAsync(CancellationToken c
8687 }
8788 }
8889
89- throw new ObjectDisposedException ( "Reader" ) ;
90+ throw new ReaderException ( "Reader is disposed " ) ;
9091 }
9192
9293 private async Task Initialize ( )
@@ -185,15 +186,15 @@ await stream.Write(new MessageFromClient
185186 ReadRequest = new StreamReadMessage . Types . ReadRequest { BytesSize = _config . MemoryUsageMaxBytes }
186187 } ) ;
187188
188- new ReaderSession < TValue > (
189+ _currentReaderSession = new ReaderSession < TValue > (
189190 _config ,
190191 stream ,
191192 initResponse . SessionId ,
192193 Initialize ,
193194 _logger ,
194195 _receivedMessagesChannel . Writer ,
195196 _deserializer
196- ) . RunProcessingTopic ( ) ;
197+ ) ;
197198 }
198199 catch ( Driver . TransportException e )
199200 {
@@ -203,18 +204,12 @@ await stream.Write(new MessageFromClient
203204 }
204205 }
205206
206- public void Dispose ( )
207+ public ValueTask DisposeAsync ( )
207208 {
208- try
209- {
210- _receivedMessagesChannel . Writer . TryComplete ( ) ;
209+ _receivedMessagesChannel . Writer . TryComplete ( ) ;
210+ _disposeCts . Cancel ( ) ;
211211
212- _disposeCts . Cancel ( ) ;
213- }
214- finally
215- {
216- _disposeCts . Dispose ( ) ;
217- }
212+ return _currentReaderSession ? . DisposeAsync ( ) ?? ValueTask . CompletedTask ;
218213 }
219214}
220215
@@ -247,6 +242,8 @@ internal class ReaderSession<TValue> : TopicSession<MessageFromClient, MessageFr
247242 private readonly ChannelWriter < InternalBatchMessages < TValue > > _channelWriter ;
248243 private readonly CancellationTokenSource _lifecycleReaderSessionCts = new ( ) ;
249244 private readonly IDeserializer < TValue > _deserializer ;
245+ private readonly Task _runProcessingStreamResponse ;
246+ private readonly Task _runProcessingStreamRequest ;
250247
251248 private readonly Channel < MessageFromClient > _channelFromClientMessageSending =
252249 Channel . CreateUnbounded < MessageFromClient > (
@@ -279,29 +276,13 @@ IDeserializer<TValue> deserializer
279276 _readerConfig = config ;
280277 _channelWriter = channelWriter ;
281278 _deserializer = deserializer ;
279+
280+ _runProcessingStreamResponse = RunProcessingStreamResponse ( ) ;
281+ _runProcessingStreamRequest = RunProcessingStreamRequest ( ) ;
282282 }
283283
284- public async void RunProcessingTopic ( )
284+ private async Task RunProcessingStreamResponse ( )
285285 {
286- _ = Task . Run ( async ( ) =>
287- {
288- try
289- {
290- await foreach ( var messageFromClient in _channelFromClientMessageSending . Reader . ReadAllAsync ( ) )
291- {
292- await SendMessage ( messageFromClient ) ;
293- }
294- }
295- catch ( Driver . TransportException e )
296- {
297- Logger . LogError ( e , "ReaderSession[{SessionId}] have transport error on Write" , SessionId ) ;
298-
299- ReconnectSession ( ) ;
300-
301- _lifecycleReaderSessionCts . Cancel ( ) ;
302- }
303- } ) ;
304-
305286 try
306287 {
307288 while ( await Stream . MoveNextAsync ( ) )
@@ -349,6 +330,10 @@ public async void RunProcessingTopic()
349330 Logger . LogError ( e , "ReaderSession[{SessionId}] have transport error on processing server messages" ,
350331 SessionId ) ;
351332 }
333+ catch ( OperationCanceledException )
334+ {
335+ Logger . LogInformation ( "" ) ;
336+ }
352337 finally
353338 {
354339 ReconnectSession ( ) ;
@@ -357,6 +342,25 @@ public async void RunProcessingTopic()
357342 }
358343 }
359344
345+ private async Task RunProcessingStreamRequest ( )
346+ {
347+ try
348+ {
349+ await foreach ( var messageFromClient in _channelFromClientMessageSending . Reader . ReadAllAsync ( ) )
350+ {
351+ await SendMessage ( messageFromClient ) ;
352+ }
353+ }
354+ catch ( Driver . TransportException e )
355+ {
356+ Logger . LogError ( e , "ReaderSession[{SessionId}] have transport error on Write" , SessionId ) ;
357+
358+ ReconnectSession ( ) ;
359+
360+ _lifecycleReaderSessionCts . Cancel ( ) ;
361+ }
362+ }
363+
360364 internal async void TryReadRequestBytes ( long bytes )
361365 {
362366 var readRequestBytes = Interlocked . Add ( ref _readRequestBytes , bytes ) ;
@@ -550,4 +554,20 @@ protected override MessageFromClient GetSendUpdateTokenRequest(string token)
550554 }
551555 } ;
552556 }
557+
558+ public override async ValueTask DisposeAsync ( )
559+ {
560+ _channelFromClientMessageSending . Writer . Complete ( ) ;
561+
562+ try
563+ {
564+ await _runProcessingStreamRequest ;
565+ await Stream . RequestStreamComplete ( ) ;
566+ await _runProcessingStreamResponse ; // waiting all ack's commits
567+ }
568+ finally
569+ {
570+ Stream . Dispose ( ) ;
571+ }
572+ }
553573}
0 commit comments