use of rx.functions.Action0 in project Hystrix by Netflix.
the class HystrixCollapserTest method testRequestThenTwoCacheHitsAllUnsubscribed.
@Test
public void testRequestThenTwoCacheHitsAllUnsubscribed() throws Exception {
TestCollapserTimer timer = new TestCollapserTimer();
HystrixCollapser<List<String>, String, String> collapser1 = new SuccessfulCacheableCollapsedCommand(timer, "foo", true);
Observable<String> response1 = collapser1.observe();
HystrixCollapser<List<String>, String, String> collapser2 = new SuccessfulCacheableCollapsedCommand(timer, "foo", true);
Observable<String> response2 = collapser2.observe();
HystrixCollapser<List<String>, String, String> collapser3 = new SuccessfulCacheableCollapsedCommand(timer, "foo", true);
Observable<String> response3 = collapser3.observe();
final CountDownLatch latch1 = new CountDownLatch(1);
final CountDownLatch latch2 = new CountDownLatch(1);
final CountDownLatch latch3 = new CountDownLatch(1);
final AtomicReference<String> value1 = new AtomicReference<String>(null);
final AtomicReference<String> value2 = new AtomicReference<String>(null);
final AtomicReference<String> value3 = new AtomicReference<String>(null);
Subscription s1 = response1.doOnUnsubscribe(new Action0() {
@Override
public void call() {
System.out.println(System.currentTimeMillis() + " : s1 Unsubscribed!");
latch1.countDown();
}
}).subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println(System.currentTimeMillis() + " : s1 OnCompleted");
latch1.countDown();
}
@Override
public void onError(Throwable e) {
System.out.println(System.currentTimeMillis() + " : s1 OnError : " + e);
latch1.countDown();
}
@Override
public void onNext(String s) {
System.out.println(System.currentTimeMillis() + " : s1 OnNext : " + s);
value1.set(s);
}
});
Subscription s2 = response2.doOnUnsubscribe(new Action0() {
@Override
public void call() {
System.out.println(System.currentTimeMillis() + " : s2 Unsubscribed!");
latch2.countDown();
}
}).subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println(System.currentTimeMillis() + " : s2 OnCompleted");
latch2.countDown();
}
@Override
public void onError(Throwable e) {
System.out.println(System.currentTimeMillis() + " : s2 OnError : " + e);
latch2.countDown();
}
@Override
public void onNext(String s) {
System.out.println(System.currentTimeMillis() + " : s2 OnNext : " + s);
value2.set(s);
}
});
Subscription s3 = response3.doOnUnsubscribe(new Action0() {
@Override
public void call() {
System.out.println(System.currentTimeMillis() + " : s3 Unsubscribed!");
latch3.countDown();
}
}).subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println(System.currentTimeMillis() + " : s3 OnCompleted");
latch3.countDown();
}
@Override
public void onError(Throwable e) {
System.out.println(System.currentTimeMillis() + " : s3 OnError : " + e);
latch3.countDown();
}
@Override
public void onNext(String s) {
System.out.println(System.currentTimeMillis() + " : s3 OnNext : " + s);
value3.set(s);
}
});
s1.unsubscribe();
s2.unsubscribe();
s3.unsubscribe();
// let time pass that equals the default delay/period
timer.incrementTime(10);
assertTrue(latch1.await(1000, TimeUnit.MILLISECONDS));
assertTrue(latch2.await(1000, TimeUnit.MILLISECONDS));
assertNull(value1.get());
assertNull(value2.get());
assertNull(value3.get());
System.out.println("ReqLog : " + HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString());
assertEquals(0, HystrixRequestLog.getCurrentRequest().getAllExecutedCommands().size());
}
use of rx.functions.Action0 in project Hystrix by Netflix.
the class HystrixCommandTest method testEarlyUnsubscribeDuringExecutionViaObserve.
@Test
public void testEarlyUnsubscribeDuringExecutionViaObserve() {
class AsyncCommand extends HystrixCommand<Boolean> {
public AsyncCommand() {
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ASYNC")));
}
@Override
protected Boolean run() {
try {
Thread.sleep(500);
return true;
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
}
HystrixCommand<Boolean> cmd = new AsyncCommand();
final CountDownLatch latch = new CountDownLatch(1);
Observable<Boolean> o = cmd.observe();
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");
}
@Override
public void onError(Throwable e) {
System.out.println("OnError : " + e);
}
@Override
public void onNext(Boolean b) {
System.out.println("OnNext : " + b);
}
});
try {
Thread.sleep(10);
s.unsubscribe();
assertTrue(latch.await(200, TimeUnit.MILLISECONDS));
System.out.println("ReqLog : " + HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString());
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());
assertEquals(null, cmd.getFailedExecutionException());
assertNull(cmd.getExecutionException());
assertTrue(cmd.getExecutionTimeInMilliseconds() > -1);
assertFalse(cmd.isSuccessfulExecution());
assertCommandExecutionEvents(cmd, HystrixEventType.CANCELLED);
assertEquals(0, cmd.metrics.getCurrentConcurrentExecutionCount());
assertSaneHystrixRequestLog(1);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
use of rx.functions.Action0 in project Hystrix by Netflix.
the class HystrixCommandTest method testExecutionHookEarlyUnsubscribe.
@Test
public void testExecutionHookEarlyUnsubscribe() {
System.out.println("Running command.observe(), awaiting terminal state of Observable, then running assertions...");
final CountDownLatch latch = new CountDownLatch(1);
TestHystrixCommand<Integer> command = getCommand(ExecutionIsolationStrategy.THREAD, AbstractTestHystrixCommand.ExecutionResult.SUCCESS, 1000);
Observable<Integer> o = command.observe();
Subscription s = o.doOnUnsubscribe(new Action0() {
@Override
public void call() {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " : OnUnsubscribe");
latch.countDown();
}
}).subscribe(new Subscriber<Integer>() {
@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(Integer i) {
System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " : OnNext : " + i);
}
});
try {
Thread.sleep(15);
s.unsubscribe();
latch.await(3, TimeUnit.SECONDS);
TestableExecutionHook hook = command.getBuilder().executionHook;
assertTrue(hook.commandEmissionsMatch(0, 0, 0));
assertTrue(hook.executionEventsMatch(0, 0, 0));
assertTrue(hook.fallbackEventsMatch(0, 0, 0));
assertEquals("onStart - onThreadStart - !onRunStart - onExecutionStart - onUnsubscribe - onThreadComplete - ", hook.executionSequence.toString());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
use of rx.functions.Action0 in project Hystrix by Netflix.
the class HystrixObservableCommandTest method testRejectedViaThreadIsolation.
@Test
public void testRejectedViaThreadIsolation() throws InterruptedException {
final TestCircuitBreaker circuitBreaker = new TestCircuitBreaker();
final ArrayBlockingQueue<Boolean> results = new ArrayBlockingQueue<Boolean>(10);
final List<Thread> executionThreads = Collections.synchronizedList(new ArrayList<Thread>(20));
final List<Thread> responseThreads = Collections.synchronizedList(new ArrayList<Thread>(10));
final AtomicBoolean exceptionReceived = new AtomicBoolean();
final CountDownLatch scheduleLatch = new CountDownLatch(2);
final CountDownLatch successLatch = new CountDownLatch(1);
final AtomicInteger count = new AtomicInteger();
final AtomicReference<TestThreadIsolationWithSemaphoreSetSmallCommand> command1Ref = new AtomicReference<TestThreadIsolationWithSemaphoreSetSmallCommand>();
final AtomicReference<TestThreadIsolationWithSemaphoreSetSmallCommand> command2Ref = new AtomicReference<TestThreadIsolationWithSemaphoreSetSmallCommand>();
final AtomicReference<TestThreadIsolationWithSemaphoreSetSmallCommand> command3Ref = new AtomicReference<TestThreadIsolationWithSemaphoreSetSmallCommand>();
Runnable r1 = new HystrixContextRunnable(HystrixPlugins.getInstance().getConcurrencyStrategy(), new Runnable() {
@Override
public void run() {
final boolean shouldExecute = count.incrementAndGet() < 3;
try {
executionThreads.add(Thread.currentThread());
TestThreadIsolationWithSemaphoreSetSmallCommand command1 = new TestThreadIsolationWithSemaphoreSetSmallCommand(circuitBreaker, 2, new Action0() {
@Override
public void call() {
// make sure it's deterministic and we put 2 threads into the pool before the 3rd is submitted
if (shouldExecute) {
try {
scheduleLatch.countDown();
successLatch.await();
} catch (InterruptedException e) {
}
}
}
});
command1Ref.set(command1);
results.add(command1.toObservable().map(new Func1<Boolean, Boolean>() {
@Override
public Boolean call(Boolean b) {
responseThreads.add(Thread.currentThread());
return b;
}
}).doAfterTerminate(new Action0() {
@Override
public void call() {
if (!shouldExecute) {
// the final thread that shouldn't execute releases the latch once it has run
// so it is deterministic that the other two fill the thread pool until this one rejects
successLatch.countDown();
}
}
}).toBlocking().single());
} catch (Exception e) {
e.printStackTrace();
exceptionReceived.set(true);
}
}
});
Runnable r2 = new HystrixContextRunnable(HystrixPlugins.getInstance().getConcurrencyStrategy(), new Runnable() {
@Override
public void run() {
final boolean shouldExecute = count.incrementAndGet() < 3;
try {
executionThreads.add(Thread.currentThread());
TestThreadIsolationWithSemaphoreSetSmallCommand command2 = new TestThreadIsolationWithSemaphoreSetSmallCommand(circuitBreaker, 2, new Action0() {
@Override
public void call() {
// make sure it's deterministic and we put 2 threads into the pool before the 3rd is submitted
if (shouldExecute) {
try {
scheduleLatch.countDown();
successLatch.await();
} catch (InterruptedException e) {
}
}
}
});
command2Ref.set(command2);
results.add(command2.toObservable().map(new Func1<Boolean, Boolean>() {
@Override
public Boolean call(Boolean b) {
responseThreads.add(Thread.currentThread());
return b;
}
}).doAfterTerminate(new Action0() {
@Override
public void call() {
if (!shouldExecute) {
// the final thread that shouldn't execute releases the latch once it has run
// so it is deterministic that the other two fill the thread pool until this one rejects
successLatch.countDown();
}
}
}).toBlocking().single());
} catch (Exception e) {
e.printStackTrace();
exceptionReceived.set(true);
}
}
});
Runnable r3 = new HystrixContextRunnable(HystrixPlugins.getInstance().getConcurrencyStrategy(), new Runnable() {
@Override
public void run() {
final boolean shouldExecute = count.incrementAndGet() < 3;
try {
executionThreads.add(Thread.currentThread());
TestThreadIsolationWithSemaphoreSetSmallCommand command3 = new TestThreadIsolationWithSemaphoreSetSmallCommand(circuitBreaker, 2, new Action0() {
@Override
public void call() {
// make sure it's deterministic and we put 2 threads into the pool before the 3rd is submitted
if (shouldExecute) {
try {
scheduleLatch.countDown();
successLatch.await();
} catch (InterruptedException e) {
}
}
}
});
command3Ref.set(command3);
results.add(command3.toObservable().map(new Func1<Boolean, Boolean>() {
@Override
public Boolean call(Boolean b) {
responseThreads.add(Thread.currentThread());
return b;
}
}).doAfterTerminate(new Action0() {
@Override
public void call() {
if (!shouldExecute) {
// the final thread that shouldn't execute releases the latch once it has run
// so it is deterministic that the other two fill the thread pool until this one rejects
successLatch.countDown();
}
}
}).toBlocking().single());
} catch (Exception e) {
e.printStackTrace();
exceptionReceived.set(true);
}
}
});
// 2 threads, the second should be rejected by the semaphore and return fallback
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
Thread t3 = new Thread(r3);
t1.start();
t2.start();
// wait for the previous 2 thread to be running before starting otherwise it can race
scheduleLatch.await(500, TimeUnit.MILLISECONDS);
t3.start();
try {
t1.join();
t2.join();
t3.join();
} catch (Exception e) {
e.printStackTrace();
fail("failed waiting on threads");
}
// we should have 2 of the 3 return results
assertEquals(2, results.size());
// the other thread should have thrown an Exception
assertTrue(exceptionReceived.get());
assertCommandExecutionEvents(command1Ref.get(), HystrixEventType.EMIT, HystrixEventType.SUCCESS);
assertCommandExecutionEvents(command2Ref.get(), HystrixEventType.EMIT, HystrixEventType.SUCCESS);
assertCommandExecutionEvents(command3Ref.get(), HystrixEventType.THREAD_POOL_REJECTED, HystrixEventType.FALLBACK_MISSING);
assertEquals(0, circuitBreaker.metrics.getCurrentConcurrentExecutionCount());
assertSaneHystrixRequestLog(3);
}
use of rx.functions.Action0 in project Hystrix by Netflix.
the class HystrixObservableCollapserTest method testRequestThenTwoCacheHitsAllUnsubscribed.
@Test
public void testRequestThenTwoCacheHitsAllUnsubscribed() throws Exception {
TestCollapserTimer timer = new TestCollapserTimer();
HystrixObservableCollapser<String, String, String, String> collapser1 = new SuccessfulCacheableCollapsedCommand(timer, "foo", true);
Observable<String> response1 = collapser1.observe();
HystrixObservableCollapser<String, String, String, String> collapser2 = new SuccessfulCacheableCollapsedCommand(timer, "foo", true);
Observable<String> response2 = collapser2.observe();
HystrixObservableCollapser<String, String, String, String> collapser3 = new SuccessfulCacheableCollapsedCommand(timer, "foo", true);
Observable<String> response3 = collapser3.observe();
final CountDownLatch latch1 = new CountDownLatch(1);
final CountDownLatch latch2 = new CountDownLatch(1);
final CountDownLatch latch3 = new CountDownLatch(1);
final AtomicReference<String> value1 = new AtomicReference<String>(null);
final AtomicReference<String> value2 = new AtomicReference<String>(null);
final AtomicReference<String> value3 = new AtomicReference<String>(null);
Subscription s1 = response1.doOnUnsubscribe(new Action0() {
@Override
public void call() {
System.out.println(System.currentTimeMillis() + " : s1 Unsubscribed!");
latch1.countDown();
}
}).subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println(System.currentTimeMillis() + " : s1 OnCompleted");
latch1.countDown();
}
@Override
public void onError(Throwable e) {
System.out.println(System.currentTimeMillis() + " : s1 OnError : " + e);
latch1.countDown();
}
@Override
public void onNext(String s) {
System.out.println(System.currentTimeMillis() + " : s1 OnNext : " + s);
value1.set(s);
}
});
Subscription s2 = response2.doOnUnsubscribe(new Action0() {
@Override
public void call() {
System.out.println(System.currentTimeMillis() + " : s2 Unsubscribed!");
latch2.countDown();
}
}).subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println(System.currentTimeMillis() + " : s2 OnCompleted");
latch2.countDown();
}
@Override
public void onError(Throwable e) {
System.out.println(System.currentTimeMillis() + " : s2 OnError : " + e);
latch2.countDown();
}
@Override
public void onNext(String s) {
System.out.println(System.currentTimeMillis() + " : s2 OnNext : " + s);
value2.set(s);
}
});
Subscription s3 = response3.doOnUnsubscribe(new Action0() {
@Override
public void call() {
System.out.println(System.currentTimeMillis() + " : s3 Unsubscribed!");
latch3.countDown();
}
}).subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println(System.currentTimeMillis() + " : s3 OnCompleted");
latch3.countDown();
}
@Override
public void onError(Throwable e) {
System.out.println(System.currentTimeMillis() + " : s3 OnError : " + e);
latch3.countDown();
}
@Override
public void onNext(String s) {
System.out.println(System.currentTimeMillis() + " : s3 OnNext : " + s);
value3.set(s);
}
});
s1.unsubscribe();
s2.unsubscribe();
s3.unsubscribe();
// let time pass that equals the default delay/period
timer.incrementTime(10);
assertTrue(latch1.await(1000, TimeUnit.MILLISECONDS));
assertTrue(latch2.await(1000, TimeUnit.MILLISECONDS));
assertNull(value1.get());
assertNull(value2.get());
assertNull(value3.get());
System.out.println("ReqLog : " + HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString());
assertEquals(0, HystrixRequestLog.getCurrentRequest().getAllExecutedCommands().size());
}
Aggregations