@@ -285,12 +285,7 @@ void subscribe(DownstreamSubscription<T> subscription) {
285
285
286
286
private void doSubscribe (DownstreamSubscription <T > subscription ) {
287
287
if (state == State .ABORTED ) {
288
- final EventExecutor executor = subscription .executor ;
289
- if (executor .inEventLoop ()) {
290
- failLateProcessorSubscriber (subscription );
291
- } else {
292
- executor .execute (() -> failLateProcessorSubscriber (subscription ));
293
- }
288
+ subscription .failLateProcessorSubscriber ();
294
289
return ;
295
290
}
296
291
@@ -301,63 +296,11 @@ private void doSubscribe(DownstreamSubscription<T> subscription) {
301
296
}
302
297
}
303
298
304
- private static void failLateProcessorSubscriber (DownstreamSubscription <?> subscription ) {
305
- final Subscriber <?> lateSubscriber = subscription .subscriber ();
306
- try {
307
- lateSubscriber .onSubscribe (NoopSubscription .get ());
308
- lateSubscriber .onError (
309
- new IllegalStateException ("duplicator is closed or no more downstream can be added." ));
310
- } catch (Throwable t ) {
311
- throwIfFatal (t );
312
- logger .warn ("Subscriber should not throw an exception. subscriber: {}" , lateSubscriber , t );
313
- }
314
- }
315
-
316
- void unsubscribe (DownstreamSubscription <T > subscription , @ Nullable Throwable cause ) {
299
+ private void cleanupIfLastSubscription () {
317
300
if (executor .inEventLoop ()) {
318
- doUnsubscribe (subscription , cause );
319
- } else {
320
- executor .execute (() -> doUnsubscribe (subscription , cause ));
321
- }
322
- }
323
-
324
- private void doUnsubscribe (DownstreamSubscription <T > subscription , @ Nullable Throwable cause ) {
325
- if (!downstreamSubscriptions .remove (subscription )) {
326
- return ;
327
- }
328
-
329
- final Subscriber <? super T > subscriber = subscription .subscriber ();
330
- subscription .clearSubscriber ();
331
-
332
- final CompletableFuture <Void > completionFuture = subscription .whenComplete ();
333
- if (cause == null ) {
334
- try {
335
- subscriber .onComplete ();
336
- completionFuture .complete (null );
337
- } catch (Throwable t ) {
338
- completionFuture .completeExceptionally (t );
339
- throwIfFatal (t );
340
- logger .warn ("Subscriber.onComplete() should not raise an exception. subscriber: {}" ,
341
- subscriber , t );
342
- } finally {
343
- doCleanupIfLastSubscription ();
344
- }
345
- return ;
346
- }
347
-
348
- try {
349
- if (subscription .notifyCancellation || !(cause instanceof CancelledSubscriptionException )) {
350
- subscriber .onError (cause );
351
- }
352
- completionFuture .completeExceptionally (cause );
353
- } catch (Throwable t ) {
354
- final Exception composite = new CompositeException (t , cause );
355
- completionFuture .completeExceptionally (composite );
356
- throwIfFatal (t );
357
- logger .warn ("Subscriber.onError() should not raise an exception. subscriber: {}" ,
358
- subscriber , composite );
359
- } finally {
360
301
doCleanupIfLastSubscription ();
302
+ } else {
303
+ executor .execute (this ::doCleanupIfLastSubscription );
361
304
}
362
305
}
363
306
@@ -613,7 +556,7 @@ static final class DownstreamSubscription<T> implements Subscription {
613
556
private final StreamMessage <T > streamMessage ;
614
557
private Subscriber <? super T > subscriber ;
615
558
private final StreamMessageProcessor <T > processor ;
616
- private final EventExecutor executor ;
559
+ private final EventExecutor downstreamExecutor ;
617
560
private final boolean withPooledObjects ;
618
561
private final boolean notifyCancellation ;
619
562
@@ -640,7 +583,7 @@ static final class DownstreamSubscription<T> implements Subscription {
640
583
this .streamMessage = streamMessage ;
641
584
this .subscriber = subscriber ;
642
585
this .processor = processor ;
643
- this . executor = executor ;
586
+ downstreamExecutor = executor ;
644
587
this .withPooledObjects = withPooledObjects ;
645
588
this .notifyCancellation = notifyCancellation ;
646
589
}
@@ -661,17 +604,36 @@ void clearSubscriber() {
661
604
}
662
605
}
663
606
607
+ void failLateProcessorSubscriber () {
608
+ if (downstreamExecutor .inEventLoop ()) {
609
+ failLateProcessorSubscriber0 ();
610
+ } else {
611
+ downstreamExecutor .execute (this ::failLateProcessorSubscriber0 );
612
+ }
613
+ }
614
+
615
+ private void failLateProcessorSubscriber0 () {
616
+ try {
617
+ subscriber .onSubscribe (NoopSubscription .get ());
618
+ subscriber .onError (
619
+ new IllegalStateException ("duplicator is closed or no more downstream can be added." ));
620
+ } catch (Throwable t ) {
621
+ throwIfFatal (t );
622
+ logger .warn ("Subscriber should not throw an exception. subscriber: {}" , subscriber , t );
623
+ }
624
+ }
625
+
664
626
// Called from processor.processorExecutor
665
627
void invokeOnSubscribe () {
666
628
if (invokedOnSubscribe ) {
667
629
return ;
668
630
}
669
631
invokedOnSubscribe = true ;
670
632
671
- if (executor .inEventLoop ()) {
633
+ if (downstreamExecutor .inEventLoop ()) {
672
634
invokeOnSubscribe0 ();
673
635
} else {
674
- executor .execute (this ::invokeOnSubscribe0 );
636
+ downstreamExecutor .execute (this ::invokeOnSubscribe0 );
675
637
}
676
638
}
677
639
@@ -680,7 +642,7 @@ void invokeOnSubscribe0() {
680
642
try {
681
643
subscriber .onSubscribe (this );
682
644
} catch (Throwable t ) {
683
- processor . unsubscribe (this , t );
645
+ unsubscribe (t );
684
646
throwIfFatal (t );
685
647
logger .warn ("Subscriber.onSubscribe() should not raise an exception. subscriber: {}" ,
686
648
subscriber , t );
@@ -692,7 +654,7 @@ public void request(long n) {
692
654
if (n <= 0 ) {
693
655
final Throwable cause = new IllegalArgumentException (
694
656
"n: " + n + " (expected: > 0, see Reactive Streams specification rule 3.9)" );
695
- processor . unsubscribe (this , cause );
657
+ unsubscribe (cause );
696
658
return ;
697
659
}
698
660
@@ -726,10 +688,10 @@ private void accumulateDemand(long n) {
726
688
}
727
689
728
690
void signal () {
729
- if (executor .inEventLoop ()) {
691
+ if (downstreamExecutor .inEventLoop ()) {
730
692
doSignal ();
731
693
} else {
732
- executor .execute (this ::doSignal );
694
+ downstreamExecutor .execute (this ::doSignal );
733
695
}
734
696
}
735
697
@@ -757,7 +719,7 @@ private boolean doSignalSingle(SignalQueue signals) {
757
719
758
720
if (cancelledOrAborted != null ) {
759
721
// Stream ended due to cancellation or abortion.
760
- processor . unsubscribe (this , cancelledOrAborted );
722
+ unsubscribe (cancelledOrAborted );
761
723
return false ;
762
724
}
763
725
@@ -771,7 +733,7 @@ private boolean doSignalSingle(SignalQueue signals) {
771
733
if (signal instanceof CloseEvent ) {
772
734
// The stream has reached at its end.
773
735
offset ++;
774
- processor . unsubscribe (this , ((CloseEvent ) signal ).cause );
736
+ unsubscribe (((CloseEvent ) signal ).cause );
775
737
return false ;
776
738
}
777
739
@@ -812,7 +774,7 @@ private boolean doSignalSingle(SignalQueue signals) {
812
774
// If an exception such as IllegalReferenceCountException is raised while operating
813
775
// on the ByteBuf, catch it and notify the subscriber with it. So the
814
776
// subscriber does not hang forever.
815
- processor . unsubscribe (this , thrown );
777
+ unsubscribe (thrown );
816
778
return false ;
817
779
}
818
780
@@ -832,7 +794,7 @@ private boolean doSignalSingle(SignalQueue signals) {
832
794
try {
833
795
subscriber .onNext (obj );
834
796
} catch (Throwable t ) {
835
- processor . unsubscribe (this , t );
797
+ unsubscribe (t );
836
798
throwIfFatal (t );
837
799
logger .warn ("Subscriber.onNext({}) should not raise an exception. subscriber: {}" ,
838
800
obj , subscriber , t );
@@ -844,6 +806,54 @@ private boolean doSignalSingle(SignalQueue signals) {
844
806
}
845
807
}
846
808
809
+ void unsubscribe (@ Nullable Throwable cause ) {
810
+ if (downstreamExecutor .inEventLoop ()) {
811
+ doUnsubscribe (cause );
812
+ } else {
813
+ downstreamExecutor .execute (() -> doUnsubscribe (cause ));
814
+ }
815
+ }
816
+
817
+ private void doUnsubscribe (@ Nullable Throwable cause ) {
818
+ if (!processor .downstreamSubscriptions .remove (this )) {
819
+ return ;
820
+ }
821
+
822
+ final Subscriber <? super T > subscriber = this .subscriber ;
823
+ clearSubscriber ();
824
+
825
+ final CompletableFuture <Void > completionFuture = whenComplete ();
826
+ if (cause == null ) {
827
+ try {
828
+ subscriber .onComplete ();
829
+ completionFuture .complete (null );
830
+ } catch (Throwable t ) {
831
+ completionFuture .completeExceptionally (t );
832
+ throwIfFatal (t );
833
+ logger .warn ("Subscriber.onComplete() should not raise an exception. subscriber: {}" ,
834
+ subscriber , t );
835
+ } finally {
836
+ processor .cleanupIfLastSubscription ();
837
+ }
838
+ return ;
839
+ }
840
+
841
+ try {
842
+ if (notifyCancellation || !(cause instanceof CancelledSubscriptionException )) {
843
+ subscriber .onError (cause );
844
+ }
845
+ completionFuture .completeExceptionally (cause );
846
+ } catch (Throwable t ) {
847
+ final Exception composite = new CompositeException (t , cause );
848
+ completionFuture .completeExceptionally (composite );
849
+ throwIfFatal (t );
850
+ logger .warn ("Subscriber.onError() should not raise an exception. subscriber: {}" ,
851
+ subscriber , composite );
852
+ } finally {
853
+ processor .cleanupIfLastSubscription ();
854
+ }
855
+ }
856
+
847
857
@ Override
848
858
public void cancel () {
849
859
abort (subscriber instanceof AbortingSubscriber ? ((AbortingSubscriber <?>) subscriber ).cause ()
0 commit comments