Search in sources :

Example 6 with HystrixRequestContext

use of com.netflix.hystrix.strategy.concurrency.HystrixRequestContext in project Hystrix by Netflix.

the class HystrixCollapserTest method testRequestVariableLifecycle2.

@Test
public void testRequestVariableLifecycle2() throws Exception {
    final HystrixRequestContext reqContext = HystrixRequestContext.initializeContext();
    final TestCollapserTimer timer = new TestCollapserTimer();
    final ConcurrentLinkedQueue<Future<String>> responses = new ConcurrentLinkedQueue<Future<String>>();
    ConcurrentLinkedQueue<Thread> threads = new ConcurrentLinkedQueue<Thread>();
    // kick off work (simulating a single request with multiple threads)
    for (int t = 0; t < 5; t++) {
        final int outerLoop = t;
        Thread th = new Thread(new HystrixContextRunnable(HystrixPlugins.getInstance().getConcurrencyStrategy(), new Runnable() {

            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    int uniqueInt = (outerLoop * 100) + i;
                    responses.add(new TestRequestCollapser(timer, uniqueInt).queue());
                }
            }
        }));
        threads.add(th);
        th.start();
    }
    for (Thread th : threads) {
        // wait for each thread to finish
        th.join();
    }
    // we expect 5 threads * 100 responses each
    assertEquals(500, responses.size());
    for (Future<String> f : responses) {
        // they should not be done yet because the counter hasn't incremented
        assertFalse(f.isDone());
    }
    timer.incrementTime(5);
    HystrixCollapser<List<String>, String, String> collapser1 = new TestRequestCollapser(timer, 2);
    Future<String> response2 = collapser1.queue();
    timer.incrementTime(8);
    // should execute here
    Future<String> response3 = new TestRequestCollapser(timer, 3).queue();
    timer.incrementTime(6);
    Future<String> response4 = new TestRequestCollapser(timer, 4).queue();
    timer.incrementTime(8);
    // should execute here
    Future<String> response5 = new TestRequestCollapser(timer, 5).queue();
    timer.incrementTime(10);
    // wait for all tasks to complete
    for (Future<String> f : responses) {
        f.get(1000, TimeUnit.MILLISECONDS);
    }
    assertEquals("2", response2.get(1000, TimeUnit.MILLISECONDS));
    assertEquals("3", response3.get(1000, TimeUnit.MILLISECONDS));
    assertEquals("4", response4.get(1000, TimeUnit.MILLISECONDS));
    assertEquals("5", response5.get(1000, TimeUnit.MILLISECONDS));
    // each task should have been executed 3 times
    for (TestCollapserTimer.ATask t : timer.tasks) {
        assertEquals(3, t.task.count.get());
    }
    Iterator<HystrixInvokableInfo<?>> cmdIterator = HystrixRequestLog.getCurrentRequest().getAllExecutedCommands().iterator();
    assertEquals(500, cmdIterator.next().getNumberCollapsed());
    assertEquals(2, cmdIterator.next().getNumberCollapsed());
    assertEquals(1, cmdIterator.next().getNumberCollapsed());
    HystrixRequestVariableHolder<RequestCollapser<?, ?, ?>> rv = RequestCollapserFactory.getRequestVariable(new TestRequestCollapser(timer, 1).getCollapserKey().name());
    reqContext.close();
    assertNotNull(rv);
    // they should have all been removed as part of ThreadContext.remove()
    assertEquals(0, timer.tasks.size());
}
Also used : HystrixContextRunnable(com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable) HystrixContextRunnable(com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable) Future(java.util.concurrent.Future) RequestCollapser(com.netflix.hystrix.collapser.RequestCollapser) HystrixRequestContext(com.netflix.hystrix.strategy.concurrency.HystrixRequestContext) ArrayList(java.util.ArrayList) List(java.util.List) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) Test(org.junit.Test)

Example 7 with HystrixRequestContext

use of com.netflix.hystrix.strategy.concurrency.HystrixRequestContext in project Hystrix by Netflix.

the class AbstractCommand method executeCommandAndObserve.

/**
     * This decorates "Hystrix" functionality around the run() Observable.
     *
     * @return R
     */
private Observable<R> executeCommandAndObserve(final AbstractCommand<R> _cmd) {
    final HystrixRequestContext currentRequestContext = HystrixRequestContext.getContextForCurrentThread();
    final Action1<R> markEmits = new Action1<R>() {

        @Override
        public void call(R r) {
            if (shouldOutputOnNextEvents()) {
                executionResult = executionResult.addEvent(HystrixEventType.EMIT);
                eventNotifier.markEvent(HystrixEventType.EMIT, commandKey);
            }
            if (commandIsScalar()) {
                long latency = System.currentTimeMillis() - executionResult.getStartTimestamp();
                eventNotifier.markCommandExecution(getCommandKey(), properties.executionIsolationStrategy().get(), (int) latency, executionResult.getOrderedList());
                eventNotifier.markEvent(HystrixEventType.SUCCESS, commandKey);
                executionResult = executionResult.addEvent((int) latency, HystrixEventType.SUCCESS);
                circuitBreaker.markSuccess();
            }
        }
    };
    final Action0 markOnCompleted = new Action0() {

        @Override
        public void call() {
            if (!commandIsScalar()) {
                long latency = System.currentTimeMillis() - executionResult.getStartTimestamp();
                eventNotifier.markCommandExecution(getCommandKey(), properties.executionIsolationStrategy().get(), (int) latency, executionResult.getOrderedList());
                eventNotifier.markEvent(HystrixEventType.SUCCESS, commandKey);
                executionResult = executionResult.addEvent((int) latency, HystrixEventType.SUCCESS);
                circuitBreaker.markSuccess();
            }
        }
    };
    final Func1<Throwable, Observable<R>> handleFallback = new Func1<Throwable, Observable<R>>() {

        @Override
        public Observable<R> call(Throwable t) {
            Exception e = getExceptionFromThrowable(t);
            executionResult = executionResult.setExecutionException(e);
            if (e instanceof RejectedExecutionException) {
                return handleThreadPoolRejectionViaFallback(e);
            } else if (t instanceof HystrixTimeoutException) {
                return handleTimeoutViaFallback();
            } else if (t instanceof HystrixBadRequestException) {
                return handleBadRequestByEmittingError(e);
            } else {
                /*
                     * Treat HystrixBadRequestException from ExecutionHook like a plain HystrixBadRequestException.
                     */
                if (e instanceof HystrixBadRequestException) {
                    eventNotifier.markEvent(HystrixEventType.BAD_REQUEST, commandKey);
                    return Observable.error(e);
                }
                return handleFailureViaFallback(e);
            }
        }
    };
    final Action1<Notification<? super R>> setRequestContext = new Action1<Notification<? super R>>() {

        @Override
        public void call(Notification<? super R> rNotification) {
            setRequestContextIfNeeded(currentRequestContext);
        }
    };
    Observable<R> execution;
    if (properties.executionTimeoutEnabled().get()) {
        execution = executeCommandWithSpecifiedIsolation(_cmd).lift(new HystrixObservableTimeoutOperator<R>(_cmd));
    } else {
        execution = executeCommandWithSpecifiedIsolation(_cmd);
    }
    return execution.doOnNext(markEmits).doOnCompleted(markOnCompleted).onErrorResumeNext(handleFallback).doOnEach(setRequestContext);
}
Also used : Action0(rx.functions.Action0) Action1(rx.functions.Action1) HystrixTimeoutException(com.netflix.hystrix.exception.HystrixTimeoutException) TimeoutException(java.util.concurrent.TimeoutException) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) HystrixBadRequestException(com.netflix.hystrix.exception.HystrixBadRequestException) HystrixTimeoutException(com.netflix.hystrix.exception.HystrixTimeoutException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) Observable(rx.Observable) Notification(rx.Notification) HystrixBadRequestException(com.netflix.hystrix.exception.HystrixBadRequestException) HystrixRequestContext(com.netflix.hystrix.strategy.concurrency.HystrixRequestContext) Func1(rx.functions.Func1)

Example 8 with HystrixRequestContext

use of com.netflix.hystrix.strategy.concurrency.HystrixRequestContext in project Hystrix by Netflix.

the class HystrixCommandTestWithCustomConcurrencyStrategy method testCommandDoesNotRequireContextConcurrencyStrategyProvidesItContextSetUpCorrectly.

/**
     * HystrixConcurrencyStrategy
     ** useDefaultRequestContext : true
     * HystrixCommand
     ** useRequestCache   : false
     ** useRequestLog     : false
     *
     * OUTCOME: RequestLog not set up in command, static access works properly
     */
@Test
public void testCommandDoesNotRequireContextConcurrencyStrategyProvidesItContextSetUpCorrectly() {
    HystrixConcurrencyStrategy strategy = new CustomConcurrencyStrategy(true);
    HystrixPlugins.getInstance().registerConcurrencyStrategy(strategy);
    //context is set up properly
    HystrixRequestContext context = HystrixRequestContext.initializeContext();
    HystrixCommand<Boolean> cmd = new TestCommand(false, false);
    assertTrue(cmd.execute());
    printRequestLog();
    assertNotNull(HystrixRequestLog.getCurrentRequest());
    assertNotNull(HystrixRequestLog.getCurrentRequest(strategy));
    assertNull(cmd.currentRequestLog);
    context.shutdown();
}
Also used : HystrixConcurrencyStrategy(com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy) HystrixRequestContext(com.netflix.hystrix.strategy.concurrency.HystrixRequestContext) Test(org.junit.Test)

Example 9 with HystrixRequestContext

use of com.netflix.hystrix.strategy.concurrency.HystrixRequestContext in project Hystrix by Netflix.

the class HystrixCommandTestWithCustomConcurrencyStrategy method testCommandDoesNotRequireContextConcurrencyStrategyDoesNotProvideItContextSetUpCorrectly.

/**
     * HystrixConcurrencyStrategy
     ** useDefaultRequestContext : false
     * HystrixCommand
     ** useRequestCache   : false
     ** useRequestLog     : false
     *
     * OUTCOME: RequestLog not set up in command, not available statically
     */
@Test
public void testCommandDoesNotRequireContextConcurrencyStrategyDoesNotProvideItContextSetUpCorrectly() {
    HystrixConcurrencyStrategy strategy = new CustomConcurrencyStrategy(false);
    HystrixPlugins.getInstance().registerConcurrencyStrategy(strategy);
    //context is set up properly
    HystrixRequestContext context = HystrixRequestContext.initializeContext();
    HystrixCommand<Boolean> cmd = new TestCommand(true, true);
    assertTrue(cmd.execute());
    printRequestLog();
    assertNull(HystrixRequestLog.getCurrentRequest());
    assertNull(HystrixRequestLog.getCurrentRequest(strategy));
    assertNull(cmd.currentRequestLog);
    context.shutdown();
}
Also used : HystrixConcurrencyStrategy(com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy) HystrixRequestContext(com.netflix.hystrix.strategy.concurrency.HystrixRequestContext) Test(org.junit.Test)

Example 10 with HystrixRequestContext

use of com.netflix.hystrix.strategy.concurrency.HystrixRequestContext in project Hystrix by Netflix.

the class HystrixObservableCollapserTest method testCollapserUnderConcurrency.

@Test
public void testCollapserUnderConcurrency() throws InterruptedException {
    final CollapserTimer timer = new RealCollapserTimer();
    final int NUM_THREADS_SUBMITTING_WORK = 8;
    final int NUM_REQUESTS_PER_THREAD = 8;
    final CountDownLatch latch = new CountDownLatch(NUM_THREADS_SUBMITTING_WORK);
    List<Runnable> runnables = new ArrayList<Runnable>();
    final ConcurrentLinkedQueue<TestSubscriber<String>> subscribers = new ConcurrentLinkedQueue<TestSubscriber<String>>();
    HystrixRequestContext context = HystrixRequestContext.initializeContext();
    final AtomicInteger uniqueInt = new AtomicInteger(0);
    for (int i = 0; i < NUM_THREADS_SUBMITTING_WORK; i++) {
        runnables.add(new Runnable() {

            @Override
            public void run() {
                try {
                    for (int j = 0; j < NUM_REQUESTS_PER_THREAD; j++) {
                        HystrixObservableCollapser<String, String, String, String> collapser = new TestCollapserWithMultipleResponses(timer, uniqueInt.getAndIncrement(), 3, false);
                        Observable<String> o = collapser.toObservable();
                        TestSubscriber<String> subscriber = new TestSubscriber<String>();
                        o.subscribe(subscriber);
                        subscribers.offer(subscriber);
                    }
                //System.out.println("Runnable done on thread : " + Thread.currentThread().getName());
                } finally {
                    latch.countDown();
                }
            }
        });
    }
    for (Runnable r : runnables) {
        threadPool.submit(new HystrixContextRunnable(r));
    }
    assertTrue(latch.await(1000, TimeUnit.MILLISECONDS));
    for (TestSubscriber<String> subscriber : subscribers) {
        subscriber.awaitTerminalEvent();
        if (subscriber.getOnErrorEvents().size() > 0) {
            System.out.println("ERROR : " + subscriber.getOnErrorEvents());
            for (Throwable ex : subscriber.getOnErrorEvents()) {
                ex.printStackTrace();
            }
        }
        subscriber.assertCompleted();
        subscriber.assertNoErrors();
        System.out.println("Received : " + subscriber.getOnNextEvents());
        subscriber.assertValueCount(3);
    }
    context.shutdown();
}
Also used : RealCollapserTimer(com.netflix.hystrix.collapser.RealCollapserTimer) CollapserTimer(com.netflix.hystrix.collapser.CollapserTimer) TestCollapserTimer(com.netflix.hystrix.HystrixCollapserTest.TestCollapserTimer) RealCollapserTimer(com.netflix.hystrix.collapser.RealCollapserTimer) ArrayList(java.util.ArrayList) CountDownLatch(java.util.concurrent.CountDownLatch) Observable(rx.Observable) HystrixContextRunnable(com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) HystrixContextRunnable(com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable) TestSubscriber(rx.observers.TestSubscriber) HystrixRequestContext(com.netflix.hystrix.strategy.concurrency.HystrixRequestContext) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) Test(org.junit.Test)

Aggregations

HystrixRequestContext (com.netflix.hystrix.strategy.concurrency.HystrixRequestContext)14 Test (org.junit.Test)11 HystrixConcurrencyStrategy (com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy)6 ArrayList (java.util.ArrayList)4 Observable (rx.Observable)4 RequestCollapser (com.netflix.hystrix.collapser.RequestCollapser)2 HystrixBadRequestException (com.netflix.hystrix.exception.HystrixBadRequestException)2 HystrixRuntimeException (com.netflix.hystrix.exception.HystrixRuntimeException)2 HystrixTimeoutException (com.netflix.hystrix.exception.HystrixTimeoutException)2 HystrixContextRunnable (com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable)2 List (java.util.List)2 ConcurrentLinkedQueue (java.util.concurrent.ConcurrentLinkedQueue)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 RejectedExecutionException (java.util.concurrent.RejectedExecutionException)2 TimeoutException (java.util.concurrent.TimeoutException)2 Notification (rx.Notification)2 Action0 (rx.functions.Action0)2 Action1 (rx.functions.Action1)2 Func1 (rx.functions.Func1)2 MockResponse (com.google.mockwebserver.MockResponse)1