@Override public Subscription onSubscribe(Observer<? super TResult> t1) { VirtualList<TIntermediate> values; Throwable error; state.lock(); try { if (!state.done) { state.onSubscription.call(); return state.addReplayer(t1); } values = state.values; error = state.error; } finally { state.unlock(); } // fully replay the subject for (int i = values.start(); i < values.end(); i++) { try { t1.onNext(state.resultSelector.call(values.get(i))); } catch (Throwable t) { t1.onError(t); return Subscriptions.empty(); } } if (error != null) { t1.onError(error); } else { t1.onCompleted(); } return Subscriptions.empty(); }
@Override public void onCompleted() { parentCompleted = true; // this *can* occur before the children are done, so if it does we won't send onCompleted // but will let the child worry about it // if however this completes and there are no children processing, then we will send // onCompleted if (childObservers.size() == 0) { if (!stopped.get()) { if (ourSubscription.stop()) { if (onErrorReceived.size() == 1) { // an onError was received from 1 ChildObserver so we now send it as a delayed error actualObserver.onError(onErrorReceived.peek()); } else if (onErrorReceived.size() > 1) { // an onError was received from more than 1 ChildObserver so we now send it as a // delayed error actualObserver.onError(new CompositeException(onErrorReceived)); } else { // no delayed error so send onCompleted actualObserver.onCompleted(); } } } } }
@Override public void onCompleted() { /* * Cancel previous subscription if it has not already executed. * Expected that some race-condition will occur as this is crossing over thread boundaries * We are using SynchronizedObserver around 'observer' to handle interleaving and out-of-order calls. */ lastScheduledNotification.get().unsubscribe(); observer.onCompleted(); }
@Override public Subscription subscribe(Observer<String> observer) { observer.onNext("hello"); observer.onCompleted(); return new Subscription() { @Override public void unsubscribe() { // unregister ... will never be called here since we are executing synchronously } }; }
@Override public void onNext(T args) { final int count = counter.incrementAndGet(); if (count <= num) { observer.onNext(args); if (count == num) { observer.onCompleted(); } } if (count >= num) { // this will work if the sequence is asynchronous, it will have no effect on a synchronous // observable subscription.unsubscribe(); } }
@Override public void onCompleted() { parentCompleted = true; // this *can* occur before the children are done, so if it does we won't send onCompleted // but will let the child worry about it // if however this completes and there are no children processing, then we will send // onCompleted if (childObservers.size() == 0) { if (!stopped.get()) { if (ourSubscription.stop()) { actualObserver.onCompleted(); } } } }
@Override public void onCompleted() { // remove self from map of Observers childObservers.remove(this); // if there are now 0 Observers left, so if the parent is also completed we send the // onComplete to the actualObserver // if the parent is not complete that means there is another sequence (and child Observer) // to come if (!stopped.get()) { if (childObservers.size() == 0 && parentCompleted) { if (ourSubscription.stop()) { // this thread 'won' the race to unsubscribe/stop so let's send onCompleted actualObserver.onCompleted(); } } } }
/** * onComplete and onError when called need to check for the parent being complete and if so * send the onCompleted or onError to the actualObserver. * * <p>This does NOT get invoked if synchronous execution occurs, but will when asynchronously * executing. * * <p>TestCase testErrorDelayed4WithThreading specifically tests this use case. */ private void finishObserver() { if (childObservers.size() == 0 && parentCompleted) { if (ourSubscription.stop()) { // this thread 'won' the race to unsubscribe/stop so let's send onError or onCompleted if (onErrorReceived.size() == 1) { // an onError was received from 1 ChildObserver so we now send it as a delayed error actualObserver.onError(onErrorReceived.peek()); } else if (onErrorReceived.size() > 1) { // an onError was received from more than 1 ChildObserver so we now send it as a // delayed error actualObserver.onError(new CompositeException(onErrorReceived)); } else { // no delayed error so send onCompleted actualObserver.onCompleted(); } } } }
@Override public Subscription subscribe(Observer<String> observer) { for (String s : valuesToReturn) { if (s == null) { System.out.println("throwing exception"); observer.onError(new NullPointerException()); } else { observer.onNext(s); } } observer.onCompleted(); return new Subscription() { @Override public void unsubscribe() { // unregister ... will never be called here since we are executing synchronously } }; }
@Override public Subscription call(Observer<T> observer) { if (num < 1) { items .subscribe( new Observer<T>() { @Override public void onCompleted() {} @Override public void onError(Throwable e) {} @Override public void onNext(T args) {} }) .unsubscribe(); observer.onCompleted(); return Subscriptions.empty(); } return subscription.wrap(items.subscribe(new ItemObserver(observer))); }
/** * Replay up to the given index * * @param limit */ void replayTill(int limit) { int si = values.start(); if (index < si) { index = si; } while (index < limit) { TIntermediate value = values.get(index); index++; try { wrapped.onNext(resultSelector.call(value)); } catch (Throwable t) { replayers.remove(cancel); wrapped.onError(t); return; } } if (done) { if (error != null) { wrapped.onError(error); } else { wrapped.onCompleted(); } } }
/* used to simulate subscription */ public void sendOnCompleted() { observer.onCompleted(); }
@Override public void onCompleted() { observer.onCompleted(); }
protected static <T> void emitValueToObserver(Notification<T> n, Observer<? super T> o) { n.accept(o); if (n.isOnNext()) { o.onCompleted(); } }
@Override public void onCompleted() { drainIfNeededAndSwitchToActual(); actual.onCompleted(); }
@Override public void onCompleted() { if (counter.getAndSet(num) < num) { observer.onCompleted(); } }