Search in sources :

Example 76 with Action1

use of rx.functions.Action1 in project CustomViews by AndroidStudy233.

the class MainActivity method subscriberImp.

/**
 * 除了 subscribe(Observer) 和 subscribe(Subscriber) ,
 * subscribe() 还支持不完整定义的回调,RxJava 会自动根据定义创建出 Subscriber 。形式如下:
 */
public void subscriberImp() {
    /**
     * 简单解释一下这段代码中出现的 Action1 和 Action0。 Action0 是 RxJava 的一个接口,它只有一个方法 call(),
     * 这个方法是无参无返回值的;由于 onCompleted() 方法也是无参无返回值的,因此 Action0 可以被当成一个包装对象,
     * 将 onCompleted() 的内容打包起来将自己作为一个参数传入 subscribe() 以实现不完整定义的回调。这样其实也可以
     * 看做将 onCompleted() 方法作为参数传进了 subscribe(),相当于其他某些语言中的『闭包』。 Action1 也是一个接口,
     * 它同样只有一个方法 call(T param),这个方法也无返回值,但有一个参数;与 Action0 同理,由于 onNext(T obj) 和
     * onError(Throwable error) 也是单参数无返回值的,因此 Action1 可以将 onNext(obj) 和 onError(error) 打包起来传入
     * subscribe() 以实现不完整定义的回调。事实上,虽然 Action0 和 Action1 在 API 中使用最广泛,
     * 但 RxJava 是提供了多个 ActionX 形式的接口 (例如 Action2, Action3) 的,它们可以被用以包装不同的无返回值的方法
     */
    Action1<String> action1 = new Action1<String>() {

        @Override
        public void call(String s) {
            MyLogUtil.e("onNext" + s);
        }
    };
    Action1<Throwable> error = new Action1<Throwable>() {

        @Override
        public void call(Throwable throwable) {
            MyLogUtil.e("onError");
        }
    };
    Action0 complete = new Action0() {

        @Override
        public void call() {
            MyLogUtil.e("onComplete");
        }
    };
    // onNext
    observable.subscribe(action1);
    // onNext  onError
    observable.subscribe(action1, error);
    // onNext  onError  complete
    observable.subscribe(action1, error, complete);
// 或者直接 observable.subscribe(observer);
}
Also used : Action0(rx.functions.Action0) Action1(rx.functions.Action1)

Example 77 with Action1

use of rx.functions.Action1 in project Hystrix by Netflix.

the class AbstractCommand method applyHystrixSemantics.

private Observable<R> applyHystrixSemantics(final AbstractCommand<R> _cmd) {
    // mark that we're starting execution on the ExecutionHook
    // if this hook throws an exception, then a fast-fail occurs with no fallback.  No state is left inconsistent
    executionHook.onStart(_cmd);
    /* determine if we're allowed to execute */
    if (circuitBreaker.attemptExecution()) {
        final TryableSemaphore executionSemaphore = getExecutionSemaphore();
        final AtomicBoolean semaphoreHasBeenReleased = new AtomicBoolean(false);
        final Action0 singleSemaphoreRelease = new Action0() {

            @Override
            public void call() {
                if (semaphoreHasBeenReleased.compareAndSet(false, true)) {
                    executionSemaphore.release();
                }
            }
        };
        final Action1<Throwable> markExceptionThrown = new Action1<Throwable>() {

            @Override
            public void call(Throwable t) {
                eventNotifier.markEvent(HystrixEventType.EXCEPTION_THROWN, commandKey);
            }
        };
        if (executionSemaphore.tryAcquire()) {
            try {
                /* used to track userThreadExecutionTime */
                executionResult = executionResult.setInvocationStartTime(System.currentTimeMillis());
                return executeCommandAndObserve(_cmd).doOnError(markExceptionThrown).doOnTerminate(singleSemaphoreRelease).doOnUnsubscribe(singleSemaphoreRelease);
            } catch (RuntimeException e) {
                return Observable.error(e);
            }
        } else {
            return handleSemaphoreRejectionViaFallback();
        }
    } else {
        return handleShortCircuitViaFallback();
    }
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Action0(rx.functions.Action0) Action1(rx.functions.Action1) HystrixRuntimeException(com.netflix.hystrix.exception.HystrixRuntimeException)

Example 78 with Action1

use of rx.functions.Action1 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.markEvent(HystrixEventType.SUCCESS, commandKey);
                executionResult = executionResult.addEvent((int) latency, HystrixEventType.SUCCESS);
                eventNotifier.markCommandExecution(getCommandKey(), properties.executionIsolationStrategy().get(), (int) latency, executionResult.getOrderedList());
                circuitBreaker.markSuccess();
            }
        }
    };
    final Action0 markOnCompleted = new Action0() {

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

        @Override
        public Observable<R> call(Throwable t) {
            circuitBreaker.markNonSuccess();
            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) Observable(rx.Observable) 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) Notification(rx.Notification) HystrixBadRequestException(com.netflix.hystrix.exception.HystrixBadRequestException) HystrixRequestContext(com.netflix.hystrix.strategy.concurrency.HystrixRequestContext) Func1(rx.functions.Func1)

Example 79 with Action1

use of rx.functions.Action1 in project Hystrix by Netflix.

the class HystrixCommandTest method testUnsubscribingDownstreamOperatorStillResultsInSuccessEventType.

/**
 * Some RxJava operators like take(n), zip receive data in an onNext from upstream and immediately unsubscribe.
 * When upstream is a HystrixCommand, Hystrix may get that unsubscribe before it gets to its onCompleted.
 * This should still be marked as a HystrixEventType.SUCCESS.
 */
@Test
public void testUnsubscribingDownstreamOperatorStillResultsInSuccessEventType() throws InterruptedException {
    HystrixCommand<Integer> cmd = getCommand(ExecutionIsolationStrategy.THREAD, AbstractTestHystrixCommand.ExecutionResult.SUCCESS, 100, AbstractTestHystrixCommand.FallbackResult.UNIMPLEMENTED);
    Observable<Integer> o = cmd.toObservable().doOnNext(new Action1<Integer>() {

        @Override
        public void call(Integer i) {
            System.out.println(Thread.currentThread().getName() + " : " + System.currentTimeMillis() + " CMD OnNext : " + i);
        }
    }).doOnError(new Action1<Throwable>() {

        @Override
        public void call(Throwable throwable) {
            System.out.println(Thread.currentThread().getName() + " : " + System.currentTimeMillis() + " CMD OnError : " + throwable);
        }
    }).doOnCompleted(new Action0() {

        @Override
        public void call() {
            System.out.println(Thread.currentThread().getName() + " : " + System.currentTimeMillis() + " CMD OnCompleted");
        }
    }).doOnSubscribe(new Action0() {

        @Override
        public void call() {
            System.out.println(Thread.currentThread().getName() + " : " + System.currentTimeMillis() + " CMD OnSubscribe");
        }
    }).doOnUnsubscribe(new Action0() {

        @Override
        public void call() {
            System.out.println(Thread.currentThread().getName() + " : " + System.currentTimeMillis() + " CMD OnUnsubscribe");
        }
    }).take(1).observeOn(Schedulers.io()).map(new Func1<Integer, Integer>() {

        @Override
        public Integer call(Integer i) {
            System.out.println(Thread.currentThread().getName() + " : " + System.currentTimeMillis() + " : Doing some more computation in the onNext!!");
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            return i;
        }
    });
    final CountDownLatch latch = new CountDownLatch(1);
    o.doOnSubscribe(new Action0() {

        @Override
        public void call() {
            System.out.println(Thread.currentThread().getName() + " : " + System.currentTimeMillis() + " : OnSubscribe");
        }
    }).doOnUnsubscribe(new Action0() {

        @Override
        public void call() {
            System.out.println(Thread.currentThread().getName() + " : " + System.currentTimeMillis() + " : OnUnsubscribe");
        }
    }).subscribe(new Subscriber<Integer>() {

        @Override
        public void onCompleted() {
            System.out.println(Thread.currentThread().getName() + " : " + System.currentTimeMillis() + " : OnCompleted");
            latch.countDown();
        }

        @Override
        public void onError(Throwable e) {
            System.out.println(Thread.currentThread().getName() + " : " + System.currentTimeMillis() + " : OnError : " + e);
            latch.countDown();
        }

        @Override
        public void onNext(Integer i) {
            System.out.println(Thread.currentThread().getName() + " : " + System.currentTimeMillis() + " : OnNext : " + i);
        }
    });
    latch.await(1000, TimeUnit.MILLISECONDS);
    System.out.println("ReqLog : " + HystrixRequestLog.getCurrentRequest().getExecutedCommandsAsString());
    assertTrue(cmd.isExecutedInThread());
    assertCommandExecutionEvents(cmd, HystrixEventType.SUCCESS);
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Action0(rx.functions.Action0) Action1(rx.functions.Action1) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.Test)

Example 80 with Action1

use of rx.functions.Action1 in project Hystrix by Netflix.

the class HystrixObservableCommandTest method testObservableTimeoutFallbackThreadContext.

/**
 * See https://github.com/Netflix/Hystrix/issues/212
 */
@Test
public void testObservableTimeoutFallbackThreadContext() {
    TestSubscriber<Object> ts = new TestSubscriber<Object>();
    final AtomicReference<Thread> onErrorThread = new AtomicReference<Thread>();
    final AtomicBoolean isRequestContextInitialized = new AtomicBoolean();
    TestHystrixObservableCommand<Integer> command = getCommand(ExecutionIsolationStrategy.SEMAPHORE, AbstractTestHystrixCommand.ExecutionResult.SUCCESS, 200, AbstractTestHystrixCommand.FallbackResult.SUCCESS, 100);
    command.toObservable().doOnNext(new Action1<Object>() {

        @Override
        public void call(Object t1) {
            System.out.println("onNext: " + t1);
            System.out.println("onNext Thread: " + Thread.currentThread());
            System.out.println("ThreadContext in onNext: " + HystrixRequestContext.isCurrentThreadInitialized());
            onErrorThread.set(Thread.currentThread());
            isRequestContextInitialized.set(HystrixRequestContext.isCurrentThreadInitialized());
        }
    }).subscribe(ts);
    ts.awaitTerminalEvent();
    System.out.println("events: " + ts.getOnNextEvents());
    assertTrue(isRequestContextInitialized.get());
    assertTrue(onErrorThread.get().getName().startsWith("HystrixTimer"));
    List<Object> onNexts = ts.getOnNextEvents();
    assertEquals(1, onNexts.size());
    // assertFalse( onNexts.get(0));
    assertTrue(command.getExecutionTimeInMilliseconds() > -1);
    assertTrue(command.isResponseTimedOut());
    assertNotNull(command.getExecutionException());
    assertCommandExecutionEvents(command, HystrixEventType.TIMEOUT, HystrixEventType.FALLBACK_EMIT, HystrixEventType.FALLBACK_SUCCESS);
    assertEquals(0, command.metrics.getCurrentConcurrentExecutionCount());
    assertSaneHystrixRequestLog(1);
    assertFalse(command.isExecutedInThread());
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Action1(rx.functions.Action1) TestSubscriber(rx.observers.TestSubscriber) AtomicReference(java.util.concurrent.atomic.AtomicReference) Test(org.junit.Test)

Aggregations

Action1 (rx.functions.Action1)106 Test (org.junit.Test)33 Action0 (rx.functions.Action0)28 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)24 UiThreadTest (android.support.test.annotation.UiThreadTest)20 Observable (rx.Observable)18 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)12 HystrixRuntimeException (com.netflix.hystrix.exception.HystrixRuntimeException)11 ArrayList (java.util.ArrayList)11 CountDownLatch (java.util.concurrent.CountDownLatch)11 TestSubscriber (rx.observers.TestSubscriber)10 AllTypes (io.realm.entities.AllTypes)9 List (java.util.List)9 TestCircuitBreaker (com.netflix.hystrix.HystrixCircuitBreakerTest.TestCircuitBreaker)7 OnSubscribe (rx.Observable.OnSubscribe)7 RunTestInLooperThread (io.realm.rule.RunTestInLooperThread)6 IOException (java.io.IOException)6 PluginTestVerifier (com.navercorp.pinpoint.bootstrap.plugin.test.PluginTestVerifier)5 Method (java.lang.reflect.Method)5 AtomicReference (java.util.concurrent.atomic.AtomicReference)5