@@ -24,10 +24,10 @@ internal class Writer<TValue> : IWriter<TValue>
2424 private readonly ISerializer < TValue > _serializer ;
2525 private readonly ConcurrentQueue < MessageSending > _toSendBuffer = new ( ) ;
2626 private readonly ConcurrentQueue < MessageSending > _inFlightMessages = new ( ) ;
27- private readonly CancellationTokenSource _disposeTokenSource = new ( ) ;
27+ private readonly CancellationTokenSource _disposeCts = new ( ) ;
2828
2929 private volatile TaskCompletionSource _tcsWakeUp = new ( ) ;
30- private volatile IWriteSession _session = new NotStartedWriterSession ( "Session not started!" ) ;
30+ private volatile IWriteSession _session = null ! ;
3131
3232 private int _limitBufferMaxSize ;
3333
@@ -51,18 +51,27 @@ public async Task<WriteResult> WriteAsync(Message<TValue> message, CancellationT
5151 {
5252 TaskCompletionSource < WriteResult > tcs = new ( ) ;
5353 cancellationToken . Register (
54- ( ) => tcs . TrySetCanceled ( cancellationToken ) ,
55- useSynchronizationContext : false
54+ ( ) => tcs . TrySetException (
55+ new WriterException ( "The write operation was canceled before it could be completed" )
56+ ) , useSynchronizationContext : false
5657 ) ;
5758
58- var data = _serializer . Serialize ( message . Data ) ;
59+ byte [ ] data ;
60+ try
61+ {
62+ data = _serializer . Serialize ( message . Data ) ;
63+ }
64+ catch ( Exception e )
65+ {
66+ throw new WriterException ( "Error when serializing message data" , e ) ;
67+ }
68+
5969 var messageData = new MessageData
6070 {
6171 Data = ByteString . CopyFrom ( data ) ,
6272 CreatedAt = Timestamp . FromDateTime ( message . Timestamp . ToUniversalTime ( ) ) ,
6373 UncompressedSize = data . Length
6474 } ;
65-
6675 foreach ( var metadata in message . Metadata )
6776 {
6877 messageData . MetadataItems . Add ( new MetadataItem
@@ -94,7 +103,14 @@ public async Task<WriteResult> WriteAsync(Message<TValue> message, CancellationT
94103 "Buffer overflow: the data size [{DataLength}] exceeds the current buffer limit ({CurLimitBufferSize}) [BufferMaxSize = {BufferMaxSize}]" ,
95104 data . Length , curLimitBufferSize , _config . BufferMaxSize ) ;
96105
97- throw new WriterException ( "Buffer overflow" ) ;
106+ try
107+ {
108+ await Task . Delay ( _config . BufferOverflowRetryTimeoutMs , cancellationToken ) ;
109+ }
110+ catch ( TaskCanceledException )
111+ {
112+ throw new WriterException ( "Buffer overflow" ) ;
113+ }
98114 }
99115
100116 try
@@ -113,7 +129,7 @@ private async void StartWriteWorker()
113129 {
114130 await Initialize ( ) ;
115131
116- while ( ! _disposeTokenSource . Token . IsCancellationRequested )
132+ while ( ! _disposeCts . Token . IsCancellationRequested )
117133 {
118134 await _tcsWakeUp . Task ;
119135 _tcsWakeUp = new TaskCompletionSource ( ) ;
@@ -129,10 +145,14 @@ private void WakeUpWorker()
129145
130146 private async Task Initialize ( )
131147 {
148+ _session = DummyWriteSession . Instance ;
149+
132150 try
133151 {
134- if ( _disposeTokenSource . IsCancellationRequested )
152+ if ( _disposeCts . IsCancellationRequested )
135153 {
154+ _logger . LogWarning ( "Initialize writer is canceled because it has been disposed" ) ;
155+
136156 return ;
137157 }
138158
@@ -162,7 +182,7 @@ private async Task Initialize()
162182 _session = new NotStartedWriterSession (
163183 $ "Stream unexpectedly closed by YDB server. Current InitRequest: { initRequest } ") ;
164184
165- _ = Task . Run ( Initialize , _disposeTokenSource . Token ) ;
185+ _ = Task . Run ( Initialize , _disposeCts . Token ) ;
166186
167187 return ;
168188 }
@@ -177,7 +197,7 @@ private async Task Initialize()
177197
178198 if ( status . StatusCode != StatusCode . SchemeError )
179199 {
180- _ = Task . Run ( Initialize , _disposeTokenSource . Token ) ;
200+ _ = Task . Run ( Initialize , _disposeCts . Token ) ;
181201 }
182202
183203 _logger . LogCritical ( "Writer initialization failed to start. Reason: {Status}" , status ) ;
@@ -207,17 +227,16 @@ private async Task Initialize()
207227 stream ,
208228 initResponse ,
209229 Initialize ,
210- e => { _session = new NotStartedWriterSession ( e ) ; } ,
211230 _logger ,
212- _inFlightMessages
231+ _toSendBuffer
213232 ) ;
214233
215234 if ( ! _inFlightMessages . IsEmpty )
216235 {
217236 var copyInFlightMessages = new ConcurrentQueue < MessageSending > ( ) ;
218237 while ( _inFlightMessages . TryDequeue ( out var sendData ) )
219238 {
220- if ( sendData . Tcs . Task . IsCanceled )
239+ if ( sendData . Tcs . Task . IsFaulted )
221240 {
222241 _logger . LogWarning ( "Message[SeqNo={SeqNo}] is cancelled" , sendData . MessageData . SeqNo ) ;
223242
@@ -232,29 +251,31 @@ private async Task Initialize()
232251
233252 _session = newSession ;
234253 newSession . RunProcessingWriteAck ( ) ;
254+ if ( ! _toSendBuffer . IsEmpty )
255+ {
256+ WakeUpWorker ( ) ; // send buffer
257+ }
235258 }
236259 catch ( Driver . TransportException e )
237260 {
238- _logger . LogError ( e , "Unable to connect the session" ) ;
239-
240- _session = new NotStartedWriterSession (
241- new WriterException ( "Transport error on creating WriterSession" , e ) ) ;
261+ _logger . LogError ( e , "Transport error on creating WriterSession" ) ;
242262
243- _ = Task . Run ( Initialize , _disposeTokenSource . Token ) ;
263+ _session = DummyWriteSession . Instance ;
264+ _ = Task . Run ( Initialize , _disposeCts . Token ) ;
244265 }
245266 }
246267
247268 public void Dispose ( )
248269 {
249270 try
250271 {
251- _disposeTokenSource . Cancel ( ) ;
272+ _disposeCts . Cancel ( ) ;
252273
253274 _session . Dispose ( ) ;
254275 }
255276 finally
256277 {
257- _disposeTokenSource . Dispose ( ) ;
278+ _disposeCts . Dispose ( ) ;
258279 }
259280 }
260281}
@@ -280,11 +301,6 @@ public NotStartedWriterSession(string reasonExceptionMessage, Status status)
280301 _reasonException = new WriterException ( reasonExceptionMessage , status ) ;
281302 }
282303
283- public NotStartedWriterSession ( WriterException reasonException )
284- {
285- _reasonException = reasonException ;
286- }
287-
288304 public Task Write ( ConcurrentQueue < MessageSending > toSendBuffer )
289305 {
290306 while ( toSendBuffer . TryDequeue ( out var messageSending ) )
@@ -297,6 +313,21 @@ public Task Write(ConcurrentQueue<MessageSending> toSendBuffer)
297313
298314 public void Dispose ( )
299315 {
316+ // Do nothing
317+ }
318+ }
319+
320+ internal class DummyWriteSession : IWriteSession
321+ {
322+ internal static readonly DummyWriteSession Instance = new ( ) ;
323+
324+ public void Dispose ( )
325+ {
326+ }
327+
328+ public Task Write ( ConcurrentQueue < MessageSending > toSendBuffer )
329+ {
330+ return Task . CompletedTask ;
300331 }
301332}
302333
@@ -312,15 +343,13 @@ public WriterSession(
312343 WriterStream stream ,
313344 InitResponse initResponse ,
314345 Func < Task > initialize ,
315- Action < WriterException > resetSessionOnTransportError ,
316346 ILogger logger ,
317347 ConcurrentQueue < MessageSending > inFlightMessages
318348 ) : base (
319349 stream ,
320350 logger ,
321351 initResponse . SessionId ,
322- initialize ,
323- resetSessionOnTransportError
352+ initialize
324353 )
325354 {
326355 _config = config ;
@@ -357,10 +386,10 @@ public async Task Write(ConcurrentQueue<MessageSending> toSendBuffer)
357386 }
358387 catch ( Driver . TransportException e )
359388 {
360- Logger . LogError ( e , "WriterSession[{SessionId}] have error on Write, last SeqNo={SeqNo}" ,
389+ Logger . LogError ( e , "WriterSession[{SessionId}] have transport error on Write, last SeqNo={SeqNo}" ,
361390 SessionId , Volatile . Read ( ref _seqNum ) ) ;
362391
363- ReconnectSession ( new WriterException ( "Transport error in the WriterSession on write messages" , e ) ) ;
392+ ReconnectSession ( ) ;
364393 }
365394 }
366395
@@ -428,13 +457,13 @@ Completing task on exception...
428457 {
429458 Logger . LogError ( e , "WriterSession[{SessionId}] have error on processing writeAck" , SessionId ) ;
430459
431- ReconnectSession ( new WriterException ( "Transport error in the WriterSession on processing writeAck" , e ) ) ;
460+ ReconnectSession ( ) ;
432461
433462 return ;
434463 }
435464
436465 Logger . LogWarning ( "WriterSession[{SessionId}]: stream is closed" , SessionId ) ;
437466
438- ReconnectSession ( new WriterException ( "WriterStream is closed" ) ) ;
467+ ReconnectSession ( ) ;
439468 }
440469}
0 commit comments