|
41 | 41 | import rx.functions.Action1; |
42 | 42 | import rx.functions.Func0; |
43 | 43 | import rx.functions.Func1; |
| 44 | +import rx.functions.Func2; |
44 | 45 | import rx.observers.TestSubscriber; |
45 | 46 | import rx.schedulers.Schedulers; |
46 | 47 |
|
@@ -3868,6 +3869,77 @@ public void onNext(Integer i) { |
3868 | 3869 | assertCommandExecutionEvents(cmd, HystrixEventType.SUCCESS); |
3869 | 3870 | } |
3870 | 3871 |
|
| 3872 | + @Test |
| 3873 | + public void testUnsubscribeBeforeSubscribe() throws Exception { |
| 3874 | + //this may happen in Observable chain, so Hystrix should make sure that command never executes/allocates in this situation |
| 3875 | + Observable<String> error = Observable.error(new RuntimeException("foo")); |
| 3876 | + HystrixCommand<Integer> cmd = getCommand(ExecutionIsolationStrategy.THREAD, AbstractTestHystrixCommand.ExecutionResult.SUCCESS, 100); |
| 3877 | + Observable<Integer> cmdResult = cmd.toObservable() |
| 3878 | + .doOnNext(new Action1<Integer>() { |
| 3879 | + @Override |
| 3880 | + public void call(Integer integer) { |
| 3881 | + System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " : OnNext : " + integer); |
| 3882 | + } |
| 3883 | + }) |
| 3884 | + .doOnError(new Action1<Throwable>() { |
| 3885 | + @Override |
| 3886 | + public void call(Throwable ex) { |
| 3887 | + System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " : OnError : " + ex); |
| 3888 | + } |
| 3889 | + }) |
| 3890 | + .doOnCompleted(new Action0() { |
| 3891 | + @Override |
| 3892 | + public void call() { |
| 3893 | + System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " : OnCompleted"); |
| 3894 | + } |
| 3895 | + }) |
| 3896 | + .doOnSubscribe(new Action0() { |
| 3897 | + @Override |
| 3898 | + public void call() { |
| 3899 | + System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " : OnSubscribe"); |
| 3900 | + } |
| 3901 | + }) |
| 3902 | + .doOnUnsubscribe(new Action0() { |
| 3903 | + @Override |
| 3904 | + public void call() { |
| 3905 | + System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " : OnUnsubscribe"); |
| 3906 | + } |
| 3907 | + }); |
| 3908 | + |
| 3909 | + //the zip operator will subscribe to each observable. there is a race between the error of the first |
| 3910 | + //zipped observable terminating the zip and the subscription to the command's observable |
| 3911 | + Observable<String> zipped = Observable.zip(error, cmdResult, new Func2<String, Integer, String>() { |
| 3912 | + @Override |
| 3913 | + public String call(String s, Integer integer) { |
| 3914 | + return s + integer; |
| 3915 | + } |
| 3916 | + }); |
| 3917 | + |
| 3918 | + final CountDownLatch latch = new CountDownLatch(1); |
| 3919 | + |
| 3920 | + zipped.subscribe(new Subscriber<String>() { |
| 3921 | + @Override |
| 3922 | + public void onCompleted() { |
| 3923 | + System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " OnCompleted"); |
| 3924 | + latch.countDown(); |
| 3925 | + } |
| 3926 | + |
| 3927 | + @Override |
| 3928 | + public void onError(Throwable e) { |
| 3929 | + System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " OnError : " + e); |
| 3930 | + latch.countDown(); |
| 3931 | + } |
| 3932 | + |
| 3933 | + @Override |
| 3934 | + public void onNext(String s) { |
| 3935 | + System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " OnNext : " + s); |
| 3936 | + } |
| 3937 | + }); |
| 3938 | + |
| 3939 | + latch.await(1000, TimeUnit.MILLISECONDS); |
| 3940 | + System.out.println("ReqLog : " + HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString()); |
| 3941 | + } |
| 3942 | + |
3871 | 3943 | /** |
3872 | 3944 | *********************** THREAD-ISOLATED Execution Hook Tests ************************************** |
3873 | 3945 | */ |
|
0 commit comments