use of rx.functions.Action0 in project Hystrix by Netflix.
the class HystrixObservableCommandTest method testEarlyUnsubscribeDuringExecutionViaToObservable.
@Test
public void testEarlyUnsubscribeDuringExecutionViaToObservable() {
class AsyncCommand extends HystrixObservableCommand<Boolean> {
public AsyncCommand() {
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ASYNC")));
}
@Override
protected Observable<Boolean> construct() {
return Observable.defer(new Func0<Observable<Boolean>>() {
@Override
public Observable<Boolean> call() {
try {
Thread.sleep(100);
return Observable.just(true);
} catch (InterruptedException ex) {
return Observable.error(ex);
}
}
}).subscribeOn(Schedulers.io());
}
}
HystrixObservableCommand<Boolean> cmd = new AsyncCommand();
final CountDownLatch latch = new CountDownLatch(1);
Observable<Boolean> o = cmd.toObservable();
Subscription s = o.doOnUnsubscribe(new Action0() {
@Override
public void call() {
System.out.println("OnUnsubscribe");
latch.countDown();
}
}).subscribe(new Subscriber<Boolean>() {
@Override
public void onCompleted() {
System.out.println("OnCompleted");
latch.countDown();
}
@Override
public void onError(Throwable e) {
System.out.println("OnError : " + e);
}
@Override
public void onNext(Boolean b) {
System.out.println("OnNext : " + b);
}
});
try {
s.unsubscribe();
assertTrue(latch.await(200, TimeUnit.MILLISECONDS));
assertEquals("Number of execution semaphores in use", 0, cmd.getExecutionSemaphore().getNumberOfPermitsUsed());
assertEquals("Number of fallback semaphores in use", 0, cmd.getFallbackSemaphore().getNumberOfPermitsUsed());
assertFalse(cmd.isExecutionComplete());
assertFalse(cmd.isExecutedInThread());
System.out.println("EventCounts : " + cmd.getEventCounts());
System.out.println("Execution Time : " + cmd.getExecutionTimeInMilliseconds());
System.out.println("Is Successful : " + cmd.isSuccessfulExecution());
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
use of rx.functions.Action0 in project Hystrix by Netflix.
the class HystrixConfigurationStreamTest method testTwoSubscribersOneUnsubscribes.
@Test
public void testTwoSubscribersOneUnsubscribes() throws Exception {
final CountDownLatch latch1 = new CountDownLatch(1);
final CountDownLatch latch2 = new CountDownLatch(1);
final AtomicInteger payloads1 = new AtomicInteger(0);
final AtomicInteger payloads2 = new AtomicInteger(0);
Subscription s1 = stream.observe().take(100).doOnUnsubscribe(new Action0() {
@Override
public void call() {
latch1.countDown();
}
}).subscribe(new Subscriber<HystrixConfiguration>() {
@Override
public void onCompleted() {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " : Dashboard 1 OnCompleted");
latch1.countDown();
}
@Override
public void onError(Throwable e) {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " : Dashboard 1 OnError : " + e);
latch1.countDown();
}
@Override
public void onNext(HystrixConfiguration configuration) {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " : Dashboard 1 OnNext : " + configuration);
payloads1.incrementAndGet();
}
});
Subscription s2 = stream.observe().take(100).doOnUnsubscribe(new Action0() {
@Override
public void call() {
latch2.countDown();
}
}).subscribe(new Subscriber<HystrixConfiguration>() {
@Override
public void onCompleted() {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " : Dashboard 2 OnCompleted");
latch2.countDown();
}
@Override
public void onError(Throwable e) {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " : Dashboard 2 OnError : " + e);
latch2.countDown();
}
@Override
public void onNext(HystrixConfiguration configuration) {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " : Dashboard 2 OnNext : " + configuration);
payloads2.incrementAndGet();
}
});
// execute 1 command, then unsubscribe from first stream. then execute the rest
for (int i = 0; i < 50; i++) {
HystrixCommand<Integer> cmd = Command.from(groupKey, commandKey, HystrixEventType.SUCCESS, 50);
cmd.execute();
if (i == 1) {
s1.unsubscribe();
}
}
assertTrue(latch1.await(10000, TimeUnit.MILLISECONDS));
assertTrue(latch2.await(10000, TimeUnit.MILLISECONDS));
System.out.println("s1 got : " + payloads1.get() + ", s2 got : " + payloads2.get());
assertTrue("s1 got data", payloads1.get() > 0);
assertTrue("s2 got data", payloads2.get() > 0);
assertTrue("s1 got less data than s2", payloads2.get() > payloads1.get());
}
use of rx.functions.Action0 in project Hystrix by Netflix.
the class HystrixCommandTest method testUnsubscribeBeforeSubscribe.
@Test
public void testUnsubscribeBeforeSubscribe() throws Exception {
// this may happen in Observable chain, so Hystrix should make sure that command never executes/allocates in this situation
Observable<String> error = Observable.error(new RuntimeException("foo"));
HystrixCommand<Integer> cmd = getCommand(ExecutionIsolationStrategy.THREAD, AbstractTestHystrixCommand.ExecutionResult.SUCCESS, 100);
Observable<Integer> cmdResult = cmd.toObservable().doOnNext(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " : OnNext : " + integer);
}
}).doOnError(new Action1<Throwable>() {
@Override
public void call(Throwable ex) {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " : OnError : " + ex);
}
}).doOnCompleted(new Action0() {
@Override
public void call() {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " : OnCompleted");
}
}).doOnSubscribe(new Action0() {
@Override
public void call() {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " : OnSubscribe");
}
}).doOnUnsubscribe(new Action0() {
@Override
public void call() {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " : OnUnsubscribe");
}
});
// the zip operator will subscribe to each observable. there is a race between the error of the first
// zipped observable terminating the zip and the subscription to the command's observable
Observable<String> zipped = Observable.zip(error, cmdResult, new Func2<String, Integer, String>() {
@Override
public String call(String s, Integer integer) {
return s + integer;
}
});
final CountDownLatch latch = new CountDownLatch(1);
zipped.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " OnCompleted");
latch.countDown();
}
@Override
public void onError(Throwable e) {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " OnError : " + e);
latch.countDown();
}
@Override
public void onNext(String s) {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " OnNext : " + s);
}
});
latch.await(1000, TimeUnit.MILLISECONDS);
System.out.println("ReqLog : " + HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString());
}
use of rx.functions.Action0 in project Hystrix by Netflix.
the class HystrixCommandTest method testRequestThenCacheHitAndCacheHitUnsubscribed.
@Test
public void testRequestThenCacheHitAndCacheHitUnsubscribed() {
AsyncCacheableCommand original = new AsyncCacheableCommand("foo");
AsyncCacheableCommand fromCache = new AsyncCacheableCommand("foo");
final AtomicReference<Boolean> originalValue = new AtomicReference<Boolean>(null);
final AtomicReference<Boolean> fromCacheValue = new AtomicReference<Boolean>(null);
final CountDownLatch originalLatch = new CountDownLatch(1);
final CountDownLatch fromCacheLatch = new CountDownLatch(1);
Observable<Boolean> originalObservable = original.toObservable();
Observable<Boolean> fromCacheObservable = fromCache.toObservable();
Subscription originalSubscription = originalObservable.doOnUnsubscribe(new Action0() {
@Override
public void call() {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " Test.Original Unsubscribe");
originalLatch.countDown();
}
}).subscribe(new Subscriber<Boolean>() {
@Override
public void onCompleted() {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " Test.Original OnCompleted");
originalLatch.countDown();
}
@Override
public void onError(Throwable e) {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " Test.Original OnError : " + e);
originalLatch.countDown();
}
@Override
public void onNext(Boolean b) {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " Test.Original OnNext : " + b);
originalValue.set(b);
}
});
Subscription fromCacheSubscription = fromCacheObservable.doOnUnsubscribe(new Action0() {
@Override
public void call() {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " FromCache Unsubscribe");
fromCacheLatch.countDown();
}
}).subscribe(new Subscriber<Boolean>() {
@Override
public void onCompleted() {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " FromCache OnCompleted");
fromCacheLatch.countDown();
}
@Override
public void onError(Throwable e) {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " FromCache OnError : " + e);
fromCacheLatch.countDown();
}
@Override
public void onNext(Boolean b) {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " FromCache OnNext : " + b);
fromCacheValue.set(b);
}
});
try {
fromCacheSubscription.unsubscribe();
assertTrue(fromCacheLatch.await(600, TimeUnit.MILLISECONDS));
assertTrue(originalLatch.await(600, TimeUnit.MILLISECONDS));
assertEquals("Number of execution semaphores in use (original)", 0, original.getExecutionSemaphore().getNumberOfPermitsUsed());
assertEquals("Number of fallback semaphores in use (original)", 0, original.getFallbackSemaphore().getNumberOfPermitsUsed());
assertTrue(original.isExecutionComplete());
assertTrue(original.isExecutedInThread());
assertEquals(null, original.getFailedExecutionException());
assertNull(original.getExecutionException());
assertTrue(original.getExecutionTimeInMilliseconds() > -1);
assertTrue(original.isSuccessfulExecution());
assertCommandExecutionEvents(original, HystrixEventType.SUCCESS);
assertTrue(originalValue.get());
assertEquals(0, original.metrics.getCurrentConcurrentExecutionCount());
assertEquals("Number of execution semaphores in use (fromCache)", 0, fromCache.getExecutionSemaphore().getNumberOfPermitsUsed());
assertEquals("Number of fallback semaphores in use (fromCache)", 0, fromCache.getFallbackSemaphore().getNumberOfPermitsUsed());
assertFalse(fromCache.isExecutionComplete());
assertFalse(fromCache.isExecutedInThread());
assertEquals(null, fromCache.getFailedExecutionException());
assertNull(fromCache.getExecutionException());
assertCommandExecutionEvents(fromCache, HystrixEventType.RESPONSE_FROM_CACHE, HystrixEventType.CANCELLED);
assertTrue(fromCache.getExecutionTimeInMilliseconds() == -1);
assertFalse(fromCache.isSuccessfulExecution());
assertEquals(0, fromCache.metrics.getCurrentConcurrentExecutionCount());
// underlying work
assertFalse(original.isCancelled());
System.out.println("ReqLog : " + HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString());
assertSaneHystrixRequestLog(2);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
use of rx.functions.Action0 in project Hystrix by Netflix.
the class HystrixCommandTest method testRequestThenTwoCacheHitsOriginalAndOneCacheHitUnsubscribed.
@Test
public void testRequestThenTwoCacheHitsOriginalAndOneCacheHitUnsubscribed() {
AsyncCacheableCommand original = new AsyncCacheableCommand("foo");
AsyncCacheableCommand fromCache1 = new AsyncCacheableCommand("foo");
AsyncCacheableCommand fromCache2 = new AsyncCacheableCommand("foo");
final AtomicReference<Boolean> originalValue = new AtomicReference<Boolean>(null);
final AtomicReference<Boolean> fromCache1Value = new AtomicReference<Boolean>(null);
final AtomicReference<Boolean> fromCache2Value = new AtomicReference<Boolean>(null);
final CountDownLatch originalLatch = new CountDownLatch(1);
final CountDownLatch fromCache1Latch = new CountDownLatch(1);
final CountDownLatch fromCache2Latch = new CountDownLatch(1);
Observable<Boolean> originalObservable = original.toObservable();
Observable<Boolean> fromCache1Observable = fromCache1.toObservable();
Observable<Boolean> fromCache2Observable = fromCache2.toObservable();
Subscription originalSubscription = originalObservable.doOnUnsubscribe(new Action0() {
@Override
public void call() {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " Test.Original Unsubscribe");
originalLatch.countDown();
}
}).subscribe(new Subscriber<Boolean>() {
@Override
public void onCompleted() {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " Test.Original OnCompleted");
originalLatch.countDown();
}
@Override
public void onError(Throwable e) {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " Test.Original OnError : " + e);
originalLatch.countDown();
}
@Override
public void onNext(Boolean b) {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " Test.Original OnNext : " + b);
originalValue.set(b);
}
});
Subscription fromCache1Subscription = fromCache1Observable.doOnUnsubscribe(new Action0() {
@Override
public void call() {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " Test.FromCache1 Unsubscribe");
fromCache1Latch.countDown();
}
}).subscribe(new Subscriber<Boolean>() {
@Override
public void onCompleted() {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " Test.FromCache1 OnCompleted");
fromCache1Latch.countDown();
}
@Override
public void onError(Throwable e) {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " Test.FromCache1 OnError : " + e);
fromCache1Latch.countDown();
}
@Override
public void onNext(Boolean b) {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " Test.FromCache1 OnNext : " + b);
fromCache1Value.set(b);
}
});
Subscription fromCache2Subscription = fromCache2Observable.doOnUnsubscribe(new Action0() {
@Override
public void call() {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " Test.FromCache2 Unsubscribe");
fromCache2Latch.countDown();
}
}).subscribe(new Subscriber<Boolean>() {
@Override
public void onCompleted() {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " Test.FromCache2 OnCompleted");
fromCache2Latch.countDown();
}
@Override
public void onError(Throwable e) {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " Test.FromCache2 OnError : " + e);
fromCache2Latch.countDown();
}
@Override
public void onNext(Boolean b) {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " Test.FromCache2 OnNext : " + b);
fromCache2Value.set(b);
}
});
try {
Thread.sleep(10);
originalSubscription.unsubscribe();
// fromCache1Subscription.unsubscribe();
fromCache2Subscription.unsubscribe();
assertTrue(originalLatch.await(600, TimeUnit.MILLISECONDS));
assertTrue(fromCache1Latch.await(600, TimeUnit.MILLISECONDS));
assertTrue(fromCache2Latch.await(600, TimeUnit.MILLISECONDS));
System.out.println("ReqLog : " + HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString());
assertEquals("Number of execution semaphores in use (original)", 0, original.getExecutionSemaphore().getNumberOfPermitsUsed());
assertEquals("Number of fallback semaphores in use (original)", 0, original.getFallbackSemaphore().getNumberOfPermitsUsed());
assertFalse(original.isExecutionComplete());
assertTrue(original.isExecutedInThread());
assertEquals(null, original.getFailedExecutionException());
assertNull(original.getExecutionException());
assertTrue(original.getExecutionTimeInMilliseconds() > -1);
assertFalse(original.isSuccessfulExecution());
assertCommandExecutionEvents(original, HystrixEventType.CANCELLED);
assertNull(originalValue.get());
// underlying work
assertFalse(original.isCancelled());
assertEquals(0, original.metrics.getCurrentConcurrentExecutionCount());
assertEquals("Number of execution semaphores in use (fromCache1)", 0, fromCache1.getExecutionSemaphore().getNumberOfPermitsUsed());
assertEquals("Number of fallback semaphores in use (fromCache1)", 0, fromCache1.getFallbackSemaphore().getNumberOfPermitsUsed());
assertTrue(fromCache1.isExecutionComplete());
assertFalse(fromCache1.isExecutedInThread());
assertEquals(null, fromCache1.getFailedExecutionException());
assertNull(fromCache1.getExecutionException());
assertCommandExecutionEvents(fromCache1, HystrixEventType.SUCCESS, HystrixEventType.RESPONSE_FROM_CACHE);
assertTrue(fromCache1.getExecutionTimeInMilliseconds() == -1);
assertTrue(fromCache1.isSuccessfulExecution());
assertTrue(fromCache1Value.get());
assertEquals(0, fromCache1.metrics.getCurrentConcurrentExecutionCount());
assertEquals("Number of execution semaphores in use (fromCache2)", 0, fromCache2.getExecutionSemaphore().getNumberOfPermitsUsed());
assertEquals("Number of fallback semaphores in use (fromCache2)", 0, fromCache2.getFallbackSemaphore().getNumberOfPermitsUsed());
assertFalse(fromCache2.isExecutionComplete());
assertFalse(fromCache2.isExecutedInThread());
assertEquals(null, fromCache2.getFailedExecutionException());
assertNull(fromCache2.getExecutionException());
assertCommandExecutionEvents(fromCache2, HystrixEventType.RESPONSE_FROM_CACHE, HystrixEventType.CANCELLED);
assertTrue(fromCache2.getExecutionTimeInMilliseconds() == -1);
assertFalse(fromCache2.isSuccessfulExecution());
assertNull(fromCache2Value.get());
assertEquals(0, fromCache2.metrics.getCurrentConcurrentExecutionCount());
assertSaneHystrixRequestLog(3);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
Aggregations