use of com.netflix.hystrix.AbstractCommand.TryableSemaphoreActual in project Hystrix by Netflix.
the class HystrixCommandTest method testSemaphoreThreadSafety.
@Test
public void testSemaphoreThreadSafety() {
final int NUM_PERMITS = 1;
final TryableSemaphoreActual s = new TryableSemaphoreActual(HystrixProperty.Factory.asProperty(NUM_PERMITS));
final int NUM_THREADS = 10;
ExecutorService threadPool = Executors.newFixedThreadPool(NUM_THREADS);
final int NUM_TRIALS = 100;
for (int t = 0; t < NUM_TRIALS; t++) {
System.out.println("TRIAL : " + t);
final AtomicInteger numAcquired = new AtomicInteger(0);
final CountDownLatch latch = new CountDownLatch(NUM_THREADS);
for (int i = 0; i < NUM_THREADS; i++) {
threadPool.submit(new Runnable() {
@Override
public void run() {
boolean acquired = s.tryAcquire();
if (acquired) {
try {
numAcquired.incrementAndGet();
Thread.sleep(100);
} catch (InterruptedException ex) {
ex.printStackTrace();
} finally {
s.release();
}
}
latch.countDown();
}
});
}
try {
assertTrue(latch.await(10000, TimeUnit.MILLISECONDS));
} catch (InterruptedException ex) {
fail(ex.getMessage());
}
assertEquals("Number acquired should be equal to the number of permits", NUM_PERMITS, numAcquired.get());
assertEquals("Semaphore should always get released back to 0", 0, s.getNumberOfPermitsUsed());
}
}
use of com.netflix.hystrix.AbstractCommand.TryableSemaphoreActual in project Hystrix by Netflix.
the class HystrixObservableCommandTest method testRejectedViaSemaphoreIsolation.
@Test
public void testRejectedViaSemaphoreIsolation() {
final TestCircuitBreaker circuitBreaker = new TestCircuitBreaker();
final ArrayBlockingQueue<Boolean> results = new ArrayBlockingQueue<Boolean>(2);
final TryableSemaphoreActual semaphore = new TryableSemaphoreActual(HystrixProperty.Factory.asProperty(1));
// used to wait until all commands have started
final CountDownLatch startLatch = new CountDownLatch(2);
// used to signal that all command can finish
final CountDownLatch sharedLatch = new CountDownLatch(1);
final LatchedSemaphoreCommand command1 = new LatchedSemaphoreCommand(circuitBreaker, semaphore, startLatch, sharedLatch);
final LatchedSemaphoreCommand command2 = new LatchedSemaphoreCommand(circuitBreaker, semaphore, startLatch, sharedLatch);
Observable<Boolean> merged = Observable.merge(command1.toObservable(), command2.toObservable()).subscribeOn(Schedulers.newThread());
final CountDownLatch terminal = new CountDownLatch(1);
merged.subscribe(new Subscriber<Boolean>() {
@Override
public void onCompleted() {
System.out.println(Thread.currentThread().getName() + " OnCompleted");
terminal.countDown();
}
@Override
public void onError(Throwable e) {
System.out.println(Thread.currentThread().getName() + " OnError : " + e);
terminal.countDown();
}
@Override
public void onNext(Boolean b) {
System.out.println(Thread.currentThread().getName() + " OnNext : " + b);
results.offer(b);
}
});
try {
assertTrue(startLatch.await(1000, TimeUnit.MILLISECONDS));
sharedLatch.countDown();
assertTrue(terminal.await(1000, TimeUnit.MILLISECONDS));
} catch (Throwable ex) {
ex.printStackTrace();
fail(ex.getMessage());
}
// one thread should have returned values
assertEquals(2, results.size());
// 1 should have gotten the normal value, the other - the fallback
assertTrue(results.contains(Boolean.TRUE));
assertTrue(results.contains(Boolean.FALSE));
System.out.println("REQ LOG : " + HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString());
assertCommandExecutionEvents(command1, HystrixEventType.EMIT, HystrixEventType.SUCCESS);
assertCommandExecutionEvents(command2, HystrixEventType.SEMAPHORE_REJECTED, HystrixEventType.FALLBACK_EMIT, HystrixEventType.FALLBACK_SUCCESS);
assertEquals(0, circuitBreaker.metrics.getCurrentConcurrentExecutionCount());
assertSaneHystrixRequestLog(2);
}
Aggregations