Search in sources :

Example 6 with HystrixRuntimeException

use of com.netflix.hystrix.exception.HystrixRuntimeException in project Hystrix by Netflix.

the class HystrixCommand method queue.

/**
     * Used for asynchronous execution of command.
     * <p>
     * This will queue up the command on the thread pool and return an {@link Future} to get the result once it completes.
     * <p>
     * NOTE: If configured to not run in a separate thread, this will have the same effect as {@link #execute()} and will block.
     * <p>
     * We don't throw an exception but just flip to synchronous execution so code doesn't need to change in order to switch a command from running on a separate thread to the calling thread.
     * 
     * @return {@code Future<R>} Result of {@link #run()} execution or a fallback from {@link #getFallback()} if the command fails for any reason.
     * @throws HystrixRuntimeException
     *             if a fallback does not exist
     *             <p>
     *             <ul>
     *             <li>via {@code Future.get()} in {@link ExecutionException#getCause()} if a failure occurs</li>
     *             <li>or immediately if the command can not be queued (such as short-circuited, thread-pool/semaphore rejected)</li>
     *             </ul>
     * @throws HystrixBadRequestException
     *             via {@code Future.get()} in {@link ExecutionException#getCause()} if invalid arguments or state were used representing a user failure, not a system failure
     * @throws IllegalStateException
     *             if invoked more than once
     */
public Future<R> queue() {
    /*
         * The Future returned by Observable.toBlocking().toFuture() does not implement the
         * interruption of the execution thread when the "mayInterrupt" flag of Future.cancel(boolean) is set to true;
         * thus, to comply with the contract of Future, we must wrap around it.
         */
    final Future<R> delegate = toObservable().toBlocking().toFuture();
    final Future<R> f = new Future<R>() {

        @Override
        public boolean cancel(boolean mayInterruptIfRunning) {
            if (delegate.isCancelled()) {
                return false;
            }
            if (HystrixCommand.this.getProperties().executionIsolationThreadInterruptOnFutureCancel().get()) {
                /*
                     * The only valid transition here is false -> true. If there are two futures, say f1 and f2, created by this command
                     * (which is super-weird, but has never been prohibited), and calls to f1.cancel(true) and to f2.cancel(false) are
                     * issued by different threads, it's unclear about what value would be used by the time mayInterruptOnCancel is checked.
                     * The most consistent way to deal with this scenario is to say that if *any* cancellation is invoked with interruption,
                     * than that interruption request cannot be taken back.
                     */
                interruptOnFutureCancel.compareAndSet(false, mayInterruptIfRunning);
            }
            final boolean res = delegate.cancel(interruptOnFutureCancel.get());
            if (!isExecutionComplete() && interruptOnFutureCancel.get()) {
                final Thread t = executionThread.get();
                if (t != null && !t.equals(Thread.currentThread())) {
                    t.interrupt();
                }
            }
            return res;
        }

        @Override
        public boolean isCancelled() {
            return delegate.isCancelled();
        }

        @Override
        public boolean isDone() {
            return delegate.isDone();
        }

        @Override
        public R get() throws InterruptedException, ExecutionException {
            return delegate.get();
        }

        @Override
        public R get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
            return delegate.get(timeout, unit);
        }
    };
    /* special handling of error states that throw immediately */
    if (f.isDone()) {
        try {
            f.get();
            return f;
        } catch (Exception e) {
            Throwable t = decomposeException(e);
            if (t instanceof HystrixBadRequestException) {
                return f;
            } else if (t instanceof HystrixRuntimeException) {
                HystrixRuntimeException hre = (HystrixRuntimeException) t;
                switch(hre.getFailureType()) {
                    case COMMAND_EXCEPTION:
                    case TIMEOUT:
                        // we don't throw these types from queue() only from queue().get() as they are execution errors
                        return f;
                    default:
                        // these are errors we throw from queue() as they as rejection type errors
                        throw hre;
                }
            } else {
                throw Exceptions.sneakyThrow(t);
            }
        }
    }
    return f;
}
Also used : HystrixBadRequestException(com.netflix.hystrix.exception.HystrixBadRequestException) Future(java.util.concurrent.Future) TimeUnit(java.util.concurrent.TimeUnit) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) TimeoutException(java.util.concurrent.TimeoutException) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) ExecutionException(java.util.concurrent.ExecutionException) HystrixBadRequestException(com.netflix.hystrix.exception.HystrixBadRequestException)

Example 7 with HystrixRuntimeException

use of com.netflix.hystrix.exception.HystrixRuntimeException in project Hystrix by Netflix.

the class HystrixCommandTest method testOnRunStartHookThrowsThreadIsolated.

@Test
public void testOnRunStartHookThrowsThreadIsolated() {
    final AtomicBoolean exceptionEncountered = new AtomicBoolean(false);
    final AtomicBoolean onThreadStartInvoked = new AtomicBoolean(false);
    final AtomicBoolean onThreadCompleteInvoked = new AtomicBoolean(false);
    final AtomicBoolean executionAttempted = new AtomicBoolean(false);
    class FailureInjectionHook extends HystrixCommandExecutionHook {

        @Override
        public <T> void onExecutionStart(HystrixInvokable<T> commandInstance) {
            throw new HystrixRuntimeException(HystrixRuntimeException.FailureType.COMMAND_EXCEPTION, commandInstance.getClass(), "Injected Failure", null, null);
        }

        @Override
        public <T> void onThreadStart(HystrixInvokable<T> commandInstance) {
            onThreadStartInvoked.set(true);
            super.onThreadStart(commandInstance);
        }

        @Override
        public <T> void onThreadComplete(HystrixInvokable<T> commandInstance) {
            onThreadCompleteInvoked.set(true);
            super.onThreadComplete(commandInstance);
        }
    }
    final FailureInjectionHook failureInjectionHook = new FailureInjectionHook();
    class FailureInjectedCommand extends TestHystrixCommand<Integer> {

        public FailureInjectedCommand(ExecutionIsolationStrategy isolationStrategy) {
            super(testPropsBuilder(new TestCircuitBreaker()).setCommandPropertiesDefaults(HystrixCommandPropertiesTest.getUnitTestPropertiesSetter().withExecutionIsolationStrategy(isolationStrategy)), failureInjectionHook);
        }

        @Override
        protected Integer run() throws Exception {
            executionAttempted.set(true);
            return 3;
        }
    }
    TestHystrixCommand<Integer> threadCmd = new FailureInjectedCommand(ExecutionIsolationStrategy.THREAD);
    try {
        int result = threadCmd.execute();
        System.out.println("RESULT : " + result);
    } catch (Throwable ex) {
        ex.printStackTrace();
        exceptionEncountered.set(true);
    }
    assertTrue(exceptionEncountered.get());
    assertTrue(onThreadStartInvoked.get());
    assertTrue(onThreadCompleteInvoked.get());
    assertFalse(executionAttempted.get());
    assertEquals(0, threadCmd.metrics.getCurrentConcurrentExecutionCount());
}
Also used : TestCircuitBreaker(com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker) HystrixCommandExecutionHook(com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) ExecutionIsolationStrategy(com.netflix.hystrix.HystrixCommandProperties.ExecutionIsolationStrategy) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Test(org.junit.Test)

Example 8 with HystrixRuntimeException

use of com.netflix.hystrix.exception.HystrixRuntimeException in project Hystrix by Netflix.

the class HystrixCommandTest method testNoRequestCacheOnTimeoutThrowsException.

@Test
public void testNoRequestCacheOnTimeoutThrowsException() throws Exception {
    TestCircuitBreaker circuitBreaker = new TestCircuitBreaker();
    NoRequestCacheTimeoutWithoutFallback r1 = new NoRequestCacheTimeoutWithoutFallback(circuitBreaker);
    try {
        System.out.println("r1 value: " + r1.execute());
        // we should have thrown an exception
        fail("expected a timeout");
    } catch (HystrixRuntimeException e) {
        assertTrue(r1.isResponseTimedOut());
    // what we want
    }
    NoRequestCacheTimeoutWithoutFallback r2 = new NoRequestCacheTimeoutWithoutFallback(circuitBreaker);
    try {
        r2.execute();
        // we should have thrown an exception
        fail("expected a timeout");
    } catch (HystrixRuntimeException e) {
        assertTrue(r2.isResponseTimedOut());
    // what we want
    }
    NoRequestCacheTimeoutWithoutFallback r3 = new NoRequestCacheTimeoutWithoutFallback(circuitBreaker);
    Future<Boolean> f3 = r3.queue();
    try {
        f3.get();
        // we should have thrown an exception
        fail("expected a timeout");
    } catch (ExecutionException e) {
        e.printStackTrace();
        assertTrue(r3.isResponseTimedOut());
    // what we want
    }
    // timeout on command is set to 200ms
    Thread.sleep(500);
    NoRequestCacheTimeoutWithoutFallback r4 = new NoRequestCacheTimeoutWithoutFallback(circuitBreaker);
    try {
        r4.execute();
        // we should have thrown an exception
        fail("expected a timeout");
    } catch (HystrixRuntimeException e) {
        assertTrue(r4.isResponseTimedOut());
        assertFalse(r4.isResponseFromFallback());
    // what we want
    }
    assertCommandExecutionEvents(r1, HystrixEventType.TIMEOUT, HystrixEventType.FALLBACK_MISSING);
    assertCommandExecutionEvents(r2, HystrixEventType.TIMEOUT, HystrixEventType.FALLBACK_MISSING);
    assertCommandExecutionEvents(r3, HystrixEventType.TIMEOUT, HystrixEventType.FALLBACK_MISSING);
    assertCommandExecutionEvents(r4, HystrixEventType.TIMEOUT, HystrixEventType.FALLBACK_MISSING);
    assertEquals(0, circuitBreaker.metrics.getCurrentConcurrentExecutionCount());
    assertSaneHystrixRequestLog(4);
}
Also used : TestCircuitBreaker(com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) ExecutionException(java.util.concurrent.ExecutionException) Test(org.junit.Test)

Example 9 with HystrixRuntimeException

use of com.netflix.hystrix.exception.HystrixRuntimeException in project Hystrix by Netflix.

the class HystrixCommandTest method testObservableTimeoutNoFallbackThreadContext.

/**
     * See https://github.com/Netflix/Hystrix/issues/212
     */
@Test
public void testObservableTimeoutNoFallbackThreadContext() {
    TestSubscriber<Object> ts = new TestSubscriber<Object>();
    final AtomicReference<Thread> onErrorThread = new AtomicReference<Thread>();
    final AtomicBoolean isRequestContextInitialized = new AtomicBoolean();
    TestHystrixCommand<Integer> command = getCommand(ExecutionIsolationStrategy.THREAD, AbstractTestHystrixCommand.ExecutionResult.SUCCESS, 200, AbstractTestHystrixCommand.FallbackResult.UNIMPLEMENTED, 50);
    command.toObservable().doOnError(new Action1<Throwable>() {

        @Override
        public void call(Throwable t1) {
            System.out.println("onError: " + t1);
            System.out.println("onError Thread: " + Thread.currentThread());
            System.out.println("ThreadContext in onError: " + HystrixRequestContext.isCurrentThreadInitialized());
            onErrorThread.set(Thread.currentThread());
            isRequestContextInitialized.set(HystrixRequestContext.isCurrentThreadInitialized());
        }
    }).subscribe(ts);
    ts.awaitTerminalEvent();
    assertTrue(isRequestContextInitialized.get());
    assertTrue(onErrorThread.get().getName().startsWith("HystrixTimer"));
    List<Throwable> errors = ts.getOnErrorEvents();
    assertEquals(1, errors.size());
    Throwable e = errors.get(0);
    if (errors.get(0) instanceof HystrixRuntimeException) {
        HystrixRuntimeException de = (HystrixRuntimeException) e;
        assertNotNull(de.getFallbackException());
        assertTrue(de.getFallbackException() instanceof UnsupportedOperationException);
        assertNotNull(de.getImplementingClass());
        assertNotNull(de.getCause());
        assertTrue(de.getCause() instanceof TimeoutException);
    } else {
        fail("the exception should be ExecutionException with cause as HystrixRuntimeException");
    }
    assertTrue(command.getExecutionTimeInMilliseconds() > -1);
    assertTrue(command.isResponseTimedOut());
    assertCommandExecutionEvents(command, HystrixEventType.TIMEOUT, HystrixEventType.FALLBACK_MISSING);
    assertNotNull(command.getExecutionException());
    assertEquals(0, command.getBuilder().metrics.getCurrentConcurrentExecutionCount());
    assertSaneHystrixRequestLog(1);
}
Also used : Action1(rx.functions.Action1) AtomicReference(java.util.concurrent.atomic.AtomicReference) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) TestSubscriber(rx.observers.TestSubscriber) TimeoutException(java.util.concurrent.TimeoutException) Test(org.junit.Test)

Example 10 with HystrixRuntimeException

use of com.netflix.hystrix.exception.HystrixRuntimeException in project Hystrix by Netflix.

the class HystrixObservableCommandTest method testObserveFailureWithFallbackFailure.

private void testObserveFailureWithFallbackFailure(ExecutionIsolationStrategy isolationStrategy, boolean asyncFallbackException, boolean asyncConstructException) {
    TestHystrixObservableCommand<Boolean> command = new KnownFailureTestCommandWithFallbackFailure(new TestCircuitBreaker(), isolationStrategy, asyncConstructException, asyncFallbackException);
    try {
        command.observe().toBlocking().single();
        fail("we shouldn't get here");
    } catch (HystrixRuntimeException e) {
        System.out.println("------------------------------------------------");
        e.printStackTrace();
        System.out.println("------------------------------------------------");
        assertNotNull(e.getFallbackException());
    }
    assertTrue(command.getExecutionTimeInMilliseconds() > -1);
    assertTrue(command.isFailedExecution());
    assertFalse(command.isResponseFromFallback());
    assertCommandExecutionEvents(command, HystrixEventType.FAILURE, HystrixEventType.FALLBACK_FAILURE);
    assertEquals(0, command.metrics.getCurrentConcurrentExecutionCount());
    assertSaneHystrixRequestLog(1);
    assertNotNull(command.getExecutionException());
    assertEquals(isolationStrategy.equals(ExecutionIsolationStrategy.THREAD), command.isExecutedInThread());
}
Also used : TestCircuitBreaker(com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean)

Aggregations

HystrixRuntimeException (com.netflix.hystrix.exception.HystrixRuntimeException)24 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)16 Test (org.junit.Test)16 TestCircuitBreaker (com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker)15 ExecutionException (java.util.concurrent.ExecutionException)13 TimeoutException (java.util.concurrent.TimeoutException)12 HystrixBadRequestException (com.netflix.hystrix.exception.HystrixBadRequestException)11 RejectedExecutionException (java.util.concurrent.RejectedExecutionException)8 IOException (java.io.IOException)7 CountDownLatch (java.util.concurrent.CountDownLatch)5 AtomicReference (java.util.concurrent.atomic.AtomicReference)5 CancellationException (java.util.concurrent.CancellationException)4 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)4 Action1 (rx.functions.Action1)3 ExecutionIsolationStrategy (com.netflix.hystrix.HystrixCommandProperties.ExecutionIsolationStrategy)2 HystrixTimeoutException (com.netflix.hystrix.exception.HystrixTimeoutException)2 HystrixContextRunnable (com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable)2 HystrixCommandExecutionHook (com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook)2 Observable (rx.Observable)2 Action0 (rx.functions.Action0)2