2929import io .rsocket .frame .ResumeOkFrameCodec ;
3030import io .rsocket .keepalive .KeepAliveSupport ;
3131import java .time .Duration ;
32- import java .util .concurrent .TimeoutException ;
3332import java .util .concurrent .atomic .AtomicReferenceFieldUpdater ;
3433import java .util .function .Function ;
3534import org .reactivestreams .Subscription ;
@@ -79,31 +78,49 @@ public ClientRSocketSession(
7978 this .resumeToken = resumeToken ;
8079 this .session = resumeToken .toString (CharsetUtil .UTF_8 );
8180 this .connectionFactory =
82- connectionFactory .flatMap (
83- dc -> {
84- final long impliedPosition = resumableFramesStore .frameImpliedPosition ();
85- final long position = resumableFramesStore .framePosition ();
86- dc .sendFrame (
87- 0 ,
88- ResumeFrameCodec .encode (
89- dc .alloc (),
90- resumeToken .retain (),
91- // server uses this to release its cache
92- impliedPosition , // observed on the client side
93- // server uses this to check whether there is no mismatch
94- position // sent from the client sent
95- ));
96-
97- if (logger .isDebugEnabled ()) {
98- logger .debug (
99- "Side[client]|Session[{}]. ResumeFrame[impliedPosition[{}], position[{}]] has been sent." ,
100- session ,
101- impliedPosition ,
102- position );
103- }
104-
105- return connectionTransformer .apply (dc );
106- });
81+ connectionFactory
82+ .doOnDiscard (
83+ DuplexConnection .class ,
84+ c -> {
85+ final ConnectionErrorException connectionErrorException =
86+ new ConnectionErrorException ("resumption_server=[Session Expired]" );
87+ c .sendErrorAndClose (connectionErrorException );
88+ c .receive ().subscribe ();
89+ })
90+ .flatMap (
91+ dc -> {
92+ final long impliedPosition = resumableFramesStore .frameImpliedPosition ();
93+ final long position = resumableFramesStore .framePosition ();
94+ dc .sendFrame (
95+ 0 ,
96+ ResumeFrameCodec .encode (
97+ dc .alloc (),
98+ resumeToken .retain (),
99+ // server uses this to release its cache
100+ impliedPosition , // observed on the client side
101+ // server uses this to check whether there is no mismatch
102+ position // sent from the client sent
103+ ));
104+
105+ if (logger .isDebugEnabled ()) {
106+ logger .debug (
107+ "Side[client]|Session[{}]. ResumeFrame[impliedPosition[{}], position[{}]] has been sent." ,
108+ session ,
109+ impliedPosition ,
110+ position );
111+ }
112+
113+ return connectionTransformer
114+ .apply (dc )
115+ .doOnDiscard (
116+ Tuple2 .class ,
117+ tuple2 -> {
118+ if (logger .isDebugEnabled ()) {
119+ logger .debug ("try to reestablish from discard" );
120+ }
121+ tryReestablishSession (tuple2 );
122+ });
123+ });
107124 this .resumableFramesStore = resumableFramesStore ;
108125 this .allocator = resumableDuplexConnection .alloc ();
109126 this .resumeSessionDuration = resumeSessionDuration ;
@@ -160,11 +177,20 @@ public void onImpliedPosition(long remoteImpliedPos) {
160177
161178 @ Override
162179 public void dispose () {
163- Operators .terminate (S , this );
180+ if (logger .isDebugEnabled ()) {
181+ logger .debug ("Side[client]|Session[{}]. Disposing" , session );
182+ }
183+
184+ boolean result = Operators .terminate (S , this );
185+
186+ if (logger .isDebugEnabled ()) {
187+ logger .debug ("Side[client]|Session[{}]. Sessions[isDisposed={}]" , session , result );
188+ }
164189
165190 reconnectDisposable .dispose ();
166191 resumableConnection .dispose ();
167- resumableFramesStore .dispose ();
192+ // frame store is disposed by resumable connection
193+ // resumableFramesStore.dispose();
168194
169195 if (resumeToken .refCnt () > 0 ) {
170196 resumeToken .release ();
@@ -177,6 +203,9 @@ public boolean isDisposed() {
177203 }
178204
179205 void tryReestablishSession (Tuple2 <ByteBuf , DuplexConnection > tuple2 ) {
206+ if (logger .isDebugEnabled ()) {
207+ logger .debug ("Active subscription is canceled {}" , s == Operators .cancelledSubscription ());
208+ }
180209 ByteBuf shouldBeResumeOKFrame = tuple2 .getT1 ();
181210 DuplexConnection nextDuplexConnection = tuple2 .getT2 ();
182211
@@ -189,9 +218,9 @@ void tryReestablishSession(Tuple2<ByteBuf, DuplexConnection> tuple2) {
189218 }
190219 final ConnectionErrorException connectionErrorException =
191220 new ConnectionErrorException ("RESUME_OK frame must be received before any others" );
192- resumableConnection .dispose (connectionErrorException );
221+ resumableConnection .dispose (nextDuplexConnection , connectionErrorException );
193222 nextDuplexConnection .sendErrorAndClose (connectionErrorException );
194- nextDuplexConnection .receive ().subscribe (). dispose () ;
223+ nextDuplexConnection .receive ().subscribe ();
195224
196225 throw connectionErrorException ; // throw to retry connection again
197226 }
@@ -227,10 +256,10 @@ void tryReestablishSession(Tuple2<ByteBuf, DuplexConnection> tuple2) {
227256 }
228257 final ConnectionErrorException t = new ConnectionErrorException (e .getMessage (), e );
229258
230- resumableConnection .dispose (t );
259+ resumableConnection .dispose (nextDuplexConnection , t );
231260
232261 nextDuplexConnection .sendErrorAndClose (t );
233- nextDuplexConnection .receive ().subscribe (). dispose () ;
262+ nextDuplexConnection .receive ().subscribe ();
234263
235264 return ;
236265 }
@@ -244,7 +273,7 @@ void tryReestablishSession(Tuple2<ByteBuf, DuplexConnection> tuple2) {
244273 final ConnectionErrorException connectionErrorException =
245274 new ConnectionErrorException ("resumption_server=[Session Expired]" );
246275 nextDuplexConnection .sendErrorAndClose (connectionErrorException );
247- nextDuplexConnection .receive ().subscribe (). dispose () ;
276+ nextDuplexConnection .receive ().subscribe ();
248277 return ;
249278 }
250279
@@ -263,7 +292,7 @@ void tryReestablishSession(Tuple2<ByteBuf, DuplexConnection> tuple2) {
263292 final ConnectionErrorException connectionErrorException =
264293 new ConnectionErrorException ("resumption_server_pos=[Session Expired]" );
265294 nextDuplexConnection .sendErrorAndClose (connectionErrorException );
266- nextDuplexConnection .receive ().subscribe (). dispose () ;
295+ nextDuplexConnection .receive ().subscribe ();
267296 // no need to do anything since connection resumable connection is liklly to
268297 // be disposed
269298 }
@@ -278,10 +307,10 @@ void tryReestablishSession(Tuple2<ByteBuf, DuplexConnection> tuple2) {
278307 final ConnectionErrorException connectionErrorException =
279308 new ConnectionErrorException ("resumption_server_pos=[" + remoteImpliedPos + "]" );
280309
281- resumableConnection .dispose (connectionErrorException );
310+ resumableConnection .dispose (nextDuplexConnection , connectionErrorException );
282311
283312 nextDuplexConnection .sendErrorAndClose (connectionErrorException );
284- nextDuplexConnection .receive ().subscribe (). dispose () ;
313+ nextDuplexConnection .receive ().subscribe ();
285314 }
286315 } else if (frameType == FrameType .ERROR ) {
287316 final RuntimeException exception = Exceptions .from (0 , shouldBeResumeOKFrame );
@@ -292,13 +321,14 @@ void tryReestablishSession(Tuple2<ByteBuf, DuplexConnection> tuple2) {
292321 exception );
293322 }
294323 if (exception instanceof RejectedResumeException ) {
295- resumableConnection .dispose (exception );
324+ resumableConnection .dispose (nextDuplexConnection , exception );
296325 nextDuplexConnection .dispose ();
297- nextDuplexConnection .receive ().subscribe (). dispose () ;
326+ nextDuplexConnection .receive ().subscribe ();
298327 return ;
299328 }
300329
301330 nextDuplexConnection .dispose ();
331+ nextDuplexConnection .receive ().subscribe ();
302332 throw exception ; // assume retryable exception
303333 } else {
304334 if (logger .isDebugEnabled ()) {
@@ -309,10 +339,10 @@ void tryReestablishSession(Tuple2<ByteBuf, DuplexConnection> tuple2) {
309339 final ConnectionErrorException connectionErrorException =
310340 new ConnectionErrorException ("RESUME_OK frame must be received before any others" );
311341
312- resumableConnection .dispose (connectionErrorException );
342+ resumableConnection .dispose (nextDuplexConnection , connectionErrorException );
313343
314344 nextDuplexConnection .sendErrorAndClose (connectionErrorException );
315- nextDuplexConnection .receive ().subscribe (). dispose () ;
345+ nextDuplexConnection .receive ().subscribe ();
316346
317347 // no need to do anything since remote server rejected our connection completely
318348 }
@@ -349,11 +379,7 @@ public void onError(Throwable t) {
349379 Operators .onErrorDropped (t , currentContext ());
350380 }
351381
352- if (t instanceof TimeoutException ) {
353- resumableConnection .dispose ();
354- } else {
355- resumableConnection .dispose (t );
356- }
382+ resumableConnection .dispose ();
357383 }
358384
359385 @ Override
0 commit comments