|
78 | 78 | import rx.plugins.RxJavaObservableExecutionHook;
|
79 | 79 | import rx.plugins.RxJavaPlugins;
|
80 | 80 | import rx.subjects.PublishSubject;
|
| 81 | +import rx.subjects.ReplaySubject; |
81 | 82 | import rx.subjects.Subject;
|
82 | 83 | import rx.subscriptions.BooleanSubscription;
|
83 | 84 | import rx.subscriptions.Subscriptions;
|
@@ -1666,6 +1667,17 @@ public static <T> Observable<T> onErrorReturn(final Observable<T> that, Func1<Ex
|
1666 | 1667 | return create(OperationOnErrorReturn.onErrorReturn(that, resumeFunction));
|
1667 | 1668 | }
|
1668 | 1669 |
|
| 1670 | + /** |
| 1671 | + * Returns a connectable observable sequence that shares a single subscription to the underlying sequence replaying all notifications. |
| 1672 | + * |
| 1673 | + * @param that |
| 1674 | + * the source Observable |
| 1675 | + * @return a connectable observable sequence that upon connection causes the source sequence to push results into the specified subject. |
| 1676 | + */ |
| 1677 | + public static <T> ConnectableObservable<T> replay(final Observable<T> that) { |
| 1678 | + return OperationMulticast.multicast(that, ReplaySubject.<T> create()); |
| 1679 | + } |
| 1680 | + |
1669 | 1681 | /**
|
1670 | 1682 | * Returns a connectable observable sequence that shares a single subscription to the underlying sequence.
|
1671 | 1683 | *
|
@@ -3239,13 +3251,22 @@ public Observable<T> reduce(Func2<T, T, T> accumulator) {
|
3239 | 3251 | return reduce(this, accumulator);
|
3240 | 3252 | }
|
3241 | 3253 |
|
| 3254 | + /** |
| 3255 | + * Returns a connectable observable sequence that shares a single subscription to the underlying sequence replaying all notifications. |
| 3256 | + * |
| 3257 | + * @return a connectable observable sequence that upon connection causes the source sequence to push results into the specified subject. |
| 3258 | + */ |
| 3259 | + public ConnectableObservable<T> replay() { |
| 3260 | + return replay(this); |
| 3261 | + } |
| 3262 | + |
3242 | 3263 | /**
|
3243 | 3264 | * Returns a connectable observable sequence that shares a single subscription to the underlying sequence.
|
3244 | 3265 | *
|
3245 | 3266 | * @return a connectable observable sequence that upon connection causes the source sequence to push results into the specified subject.
|
3246 | 3267 | */
|
3247 | 3268 | public ConnectableObservable<T> publish() {
|
3248 |
| - return OperationMulticast.multicast(this, PublishSubject.<T> create()); |
| 3269 | + return publish(this); |
3249 | 3270 | }
|
3250 | 3271 |
|
3251 | 3272 | /**
|
@@ -4245,10 +4266,10 @@ public Subscription call(final Observer<String> observer) {
|
4245 | 4266 |
|
4246 | 4267 | @Override
|
4247 | 4268 | public void run() {
|
| 4269 | + counter.incrementAndGet(); |
4248 | 4270 | System.out.println("published observable being executed");
|
4249 | 4271 | observer.onNext("one");
|
4250 | 4272 | observer.onCompleted();
|
4251 |
| - counter.incrementAndGet(); |
4252 | 4273 | }
|
4253 | 4274 | }).start();
|
4254 | 4275 | return subscription;
|
@@ -4290,6 +4311,66 @@ public void call(String v) {
|
4290 | 4311 | }
|
4291 | 4312 | }
|
4292 | 4313 |
|
| 4314 | + @Test |
| 4315 | + public void testReplay() throws InterruptedException { |
| 4316 | + final AtomicInteger counter = new AtomicInteger(); |
| 4317 | + ConnectableObservable<String> o = Observable.create(new Func1<Observer<String>, Subscription>() { |
| 4318 | + |
| 4319 | + @Override |
| 4320 | + public Subscription call(final Observer<String> observer) { |
| 4321 | + final BooleanSubscription subscription = new BooleanSubscription(); |
| 4322 | + new Thread(new Runnable() { |
| 4323 | + |
| 4324 | + @Override |
| 4325 | + public void run() { |
| 4326 | + System.out.println("published observable being executed"); |
| 4327 | + observer.onNext("one"); |
| 4328 | + observer.onCompleted(); |
| 4329 | + counter.incrementAndGet(); |
| 4330 | + } |
| 4331 | + }).start(); |
| 4332 | + return subscription; |
| 4333 | + } |
| 4334 | + }).replay(); |
| 4335 | + |
| 4336 | + // we connect immediately and it will emit the value |
| 4337 | + Subscription s = o.connect(); |
| 4338 | + try { |
| 4339 | + |
| 4340 | + // we then expect the following 2 subscriptions to get that same value |
| 4341 | + final CountDownLatch latch = new CountDownLatch(2); |
| 4342 | + |
| 4343 | + // subscribe once |
| 4344 | + o.subscribe(new Action1<String>() { |
| 4345 | + |
| 4346 | + @Override |
| 4347 | + public void call(String v) { |
| 4348 | + assertEquals("one", v); |
| 4349 | + System.out.println("v: " + v); |
| 4350 | + latch.countDown(); |
| 4351 | + } |
| 4352 | + }); |
| 4353 | + |
| 4354 | + // subscribe again |
| 4355 | + o.subscribe(new Action1<String>() { |
| 4356 | + |
| 4357 | + @Override |
| 4358 | + public void call(String v) { |
| 4359 | + assertEquals("one", v); |
| 4360 | + System.out.println("v: " + v); |
| 4361 | + latch.countDown(); |
| 4362 | + } |
| 4363 | + }); |
| 4364 | + |
| 4365 | + if (!latch.await(1000, TimeUnit.MILLISECONDS)) { |
| 4366 | + fail("subscriptions did not receive values"); |
| 4367 | + } |
| 4368 | + assertEquals(1, counter.get()); |
| 4369 | + } finally { |
| 4370 | + s.unsubscribe(); |
| 4371 | + } |
| 4372 | + } |
| 4373 | + |
4293 | 4374 | private static class TestException extends RuntimeException {
|
4294 | 4375 | private static final long serialVersionUID = 1L;
|
4295 | 4376 | }
|
|
0 commit comments