15
15
*/
16
16
package rx .internal .operators ;
17
17
18
- import static org .junit .Assert .assertEquals ;
19
- import static org .junit .Assert .assertTrue ;
20
- import static org .junit .Assert .fail ;
18
+ import static org .junit .Assert .*;
21
19
import static org .mockito .Matchers .any ;
22
- import static org .mockito .Mockito .inOrder ;
23
- import static org .mockito .Mockito .mock ;
24
- import static org .mockito .Mockito .never ;
25
- import static org .mockito .Mockito .verify ;
26
-
27
- import java .util .ArrayList ;
28
- import java .util .Arrays ;
29
- import java .util .List ;
30
- import java .util .concurrent .CountDownLatch ;
31
- import java .util .concurrent .TimeUnit ;
20
+ import static org .mockito .Mockito .*;
21
+
22
+ import java .util .*;
23
+ import java .util .concurrent .*;
32
24
import java .util .concurrent .atomic .AtomicInteger ;
33
25
34
- import org .junit .Before ;
35
- import org .junit .Test ;
36
- import org .mockito .InOrder ;
37
- import org .mockito .MockitoAnnotations ;
26
+ import org .junit .*;
27
+ import org .mockito .*;
38
28
39
- import rx .Observable ;
29
+ import rx .* ;
40
30
import rx .Observable .OnSubscribe ;
31
+ import rx .Observable ;
41
32
import rx .Observer ;
42
- import rx .Subscriber ;
43
- import rx .Subscription ;
44
- import rx .functions .Action0 ;
45
- import rx .functions .Action1 ;
46
- import rx .functions .Func2 ;
47
- import rx .observers .Subscribers ;
48
- import rx .observers .TestSubscriber ;
49
- import rx .schedulers .Schedulers ;
50
- import rx .schedulers .TestScheduler ;
33
+ import rx .functions .*;
34
+ import rx .observers .*;
35
+ import rx .schedulers .*;
51
36
import rx .subjects .ReplaySubject ;
52
37
import rx .subscriptions .Subscriptions ;
53
38
@@ -285,6 +270,13 @@ public void call() {
285
270
s .assertNoErrors ();
286
271
}
287
272
273
+ @ Test
274
+ public void testConnectUnsubscribeRaceConditionLoop () throws InterruptedException {
275
+ for (int i = 0 ; i < 1000 ; i ++) {
276
+ testConnectUnsubscribeRaceCondition ();
277
+ }
278
+ }
279
+
288
280
@ Test
289
281
public void testConnectUnsubscribeRaceCondition () throws InterruptedException {
290
282
final AtomicInteger subUnsubCount = new AtomicInteger ();
@@ -310,12 +302,14 @@ public void call() {
310
302
});
311
303
312
304
TestSubscriber <Long > s = new TestSubscriber <Long >();
313
- o .publish ().refCount ().subscribeOn (Schedulers .newThread ()).subscribe (s );
305
+
306
+ o .publish ().refCount ().subscribeOn (Schedulers .computation ()).subscribe (s );
314
307
System .out .println ("send unsubscribe" );
315
308
// now immediately unsubscribe while subscribeOn is racing to subscribe
316
309
s .unsubscribe ();
317
310
// this generally will mean it won't even subscribe as it is already unsubscribed by the time connect() gets scheduled
318
-
311
+ // give time to the counter to update
312
+ Thread .sleep (1 );
319
313
// either we subscribed and then unsubscribed, or we didn't ever even subscribe
320
314
assertEquals (0 , subUnsubCount .get ());
321
315
@@ -532,4 +526,72 @@ public Integer call(Integer t1, Integer t2) {
532
526
ts2 .assertReceivedOnNext (Arrays .asList (30 ));
533
527
}
534
528
529
+ @ Test (timeout = 10000 )
530
+ public void testUpstreamErrorAllowsRetry () throws InterruptedException {
531
+ final AtomicInteger intervalSubscribed = new AtomicInteger ();
532
+ Observable <String > interval =
533
+ Observable .interval (200 ,TimeUnit .MILLISECONDS )
534
+ .doOnSubscribe (
535
+ new Action0 () {
536
+ @ Override
537
+ public void call () {
538
+ System .out .println ("Subscribing to interval " + intervalSubscribed .incrementAndGet ());
539
+ }
540
+ }
541
+ )
542
+ .flatMap (new Func1 <Long , Observable <String >>() {
543
+ @ Override
544
+ public Observable <String > call (Long t1 ) {
545
+ return Observable .defer (new Func0 <Observable <String >>() {
546
+ @ Override
547
+ public Observable <String > call () {
548
+ return Observable .<String >error (new Exception ("Some exception" ));
549
+ }
550
+ });
551
+ }
552
+ })
553
+ .onErrorResumeNext (new Func1 <Throwable , Observable <String >>() {
554
+ @ Override
555
+ public Observable <String > call (Throwable t1 ) {
556
+ return Observable .error (t1 );
557
+ }
558
+ })
559
+ .publish ()
560
+ .refCount ();
561
+
562
+ interval
563
+ .doOnError (new Action1 <Throwable >() {
564
+ @ Override
565
+ public void call (Throwable t1 ) {
566
+ System .out .println ("Subscriber 1 onError: " + t1 );
567
+ }
568
+ })
569
+ .retry (5 )
570
+ .subscribe (new Action1 <String >() {
571
+ @ Override
572
+ public void call (String t1 ) {
573
+ System .out .println ("Subscriber 1: " + t1 );
574
+ }
575
+ });
576
+ Thread .sleep (100 );
577
+ interval
578
+ .doOnError (new Action1 <Throwable >() {
579
+ @ Override
580
+ public void call (Throwable t1 ) {
581
+ System .out .println ("Subscriber 2 onError: " + t1 );
582
+ }
583
+ })
584
+ .retry (5 )
585
+ .subscribe (new Action1 <String >() {
586
+ @ Override
587
+ public void call (String t1 ) {
588
+ System .out .println ("Subscriber 2: " + t1 );
589
+ }
590
+ });
591
+
592
+ Thread .sleep (1300 );
593
+
594
+ System .out .println (intervalSubscribed .get ());
595
+ assertEquals (6 , intervalSubscribed .get ());
596
+ }
535
597
}
0 commit comments