Skip to content

Commit

Permalink
Replay operator on Observable
Browse files Browse the repository at this point in the history
  • Loading branch information
benjchristensen committed May 7, 2013
1 parent 16879eb commit 5de471a
Showing 1 changed file with 83 additions and 2 deletions.
85 changes: 83 additions & 2 deletions rxjava-core/src/main/java/rx/Observable.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
import rx.plugins.RxJavaObservableExecutionHook;
import rx.plugins.RxJavaPlugins;
import rx.subjects.PublishSubject;
import rx.subjects.ReplaySubject;
import rx.subjects.Subject;
import rx.subscriptions.BooleanSubscription;
import rx.subscriptions.Subscriptions;
Expand Down Expand Up @@ -1666,6 +1667,17 @@ public static <T> Observable<T> onErrorReturn(final Observable<T> that, Func1<Ex
return create(OperationOnErrorReturn.onErrorReturn(that, resumeFunction));
}

/**
* Returns a connectable observable sequence that shares a single subscription to the underlying sequence replaying all notifications.
*
* @param that
* the source Observable
* @return a connectable observable sequence that upon connection causes the source sequence to push results into the specified subject.
*/
public static <T> ConnectableObservable<T> replay(final Observable<T> that) {
return OperationMulticast.multicast(that, ReplaySubject.<T> create());
}

/**
* Returns a connectable observable sequence that shares a single subscription to the underlying sequence.
*
Expand Down Expand Up @@ -3199,13 +3211,22 @@ public Observable<T> reduce(Func2<T, T, T> accumulator) {
return reduce(this, accumulator);
}

/**
* Returns a connectable observable sequence that shares a single subscription to the underlying sequence replaying all notifications.
*
* @return a connectable observable sequence that upon connection causes the source sequence to push results into the specified subject.
*/
public ConnectableObservable<T> replay() {
return replay(this);
}

/**
* Returns a connectable observable sequence that shares a single subscription to the underlying sequence.
*
* @return a connectable observable sequence that upon connection causes the source sequence to push results into the specified subject.
*/
public ConnectableObservable<T> publish() {
return OperationMulticast.multicast(this, PublishSubject.<T> create());
return publish(this);
}

/**
Expand Down Expand Up @@ -4174,10 +4195,10 @@ public Subscription call(final Observer<String> observer) {

@Override
public void run() {
counter.incrementAndGet();
System.out.println("published observable being executed");
observer.onNext("one");
observer.onCompleted();
counter.incrementAndGet();
}
}).start();
return subscription;
Expand Down Expand Up @@ -4219,6 +4240,66 @@ public void call(String v) {
}
}

@Test
public void testReplay() throws InterruptedException {
final AtomicInteger counter = new AtomicInteger();
ConnectableObservable<String> o = Observable.create(new Func1<Observer<String>, Subscription>() {

@Override
public Subscription call(final Observer<String> observer) {
final BooleanSubscription subscription = new BooleanSubscription();
new Thread(new Runnable() {

@Override
public void run() {
System.out.println("published observable being executed");
observer.onNext("one");
observer.onCompleted();
counter.incrementAndGet();
}
}).start();
return subscription;
}
}).replay();

// we connect immediately and it will emit the value
Subscription s = o.connect();
try {

// we then expect the following 2 subscriptions to get that same value
final CountDownLatch latch = new CountDownLatch(2);

// subscribe once
o.subscribe(new Action1<String>() {

@Override
public void call(String v) {
assertEquals("one", v);
System.out.println("v: " + v);
latch.countDown();
}
});

// subscribe again
o.subscribe(new Action1<String>() {

@Override
public void call(String v) {
assertEquals("one", v);
System.out.println("v: " + v);
latch.countDown();
}
});

if (!latch.await(1000, TimeUnit.MILLISECONDS)) {
fail("subscriptions did not receive values");
}
assertEquals(1, counter.get());
} finally {
s.unsubscribe();
}
}

private static class TestException extends RuntimeException {
private static final long serialVersionUID = 1L;
}
Expand Down

0 comments on commit 5de471a

Please sign in to comment.