diff --git a/src/main/java/rx/Observable.java b/src/main/java/rx/Observable.java
index 27a97b4b3d..70a5655011 100644
--- a/src/main/java/rx/Observable.java
+++ b/src/main/java/rx/Observable.java
@@ -15,12 +15,12 @@
import java.util.*;
import java.util.concurrent.*;
+import rx.annotations.Experimental;
import rx.exceptions.*;
import rx.functions.*;
import rx.internal.operators.*;
import rx.internal.util.ScalarSynchronousObservable;
import rx.internal.util.UtilityFunctions;
-
import rx.observables.*;
import rx.observers.SafeSubscriber;
import rx.plugins.*;
@@ -182,6 +182,7 @@ public void call(Subscriber super R> o) {
* @return the source Observable, transformed by the transformer function
* @see RxJava wiki: Implementing Your Own Operators
*/
+ @SuppressWarnings("unchecked")
public Observable compose(Transformer super T, ? extends R> transformer) {
return ((Transformer) transformer).call(this);
}
@@ -5054,6 +5055,47 @@ public final Observable onBackpressureDrop() {
return lift(new OperatorOnBackpressureDrop());
}
+ /**
+ * Instructs an Observable that is emitting items faster than its observer can consume them is to
+ * block the producer thread.
+ *
+ * The producer side can emit up to {@code maxQueueLength} onNext elements without blocking, but the
+ * consumer side considers the amount its downstream requested through {@code Producer.request(n)}
+ * and doesn't emit more than requested even if more is available. For example, using
+ * {@code onBackpressureBlock(384).observeOn(Schedulers.io())} will not throw a MissingBackpressureException.
+ *
+ * Note that if the upstream Observable does support backpressure, this operator ignores that capability
+ * and doesn't propagate any backpressure requests from downstream.
+ *
+ * @param maxQueueLength the maximum number of items the producer can emit without blocking
+ * @return the source Observable modified to block {@code onNext} notifications on overflow
+ * @see RxJava wiki: Backpressure
+ * @Experimental The behavior of this can change at any time.
+ */
+ @Experimental
+ public final Observable onBackpressureBlock(int maxQueueLength) {
+ return lift(new OperatorOnBackpressureBlock(maxQueueLength));
+ }
+ /**
+ * Instructs an Observable that is emitting items faster than its observer can consume them is to
+ * block the producer thread if the number of undelivered onNext events reaches the system-wide ring buffer size.
+ *
+ * The producer side can emit up to the system-wide ring buffer size onNext elements without blocking, but the
+ * consumer side considers the amount its downstream requested through {@code Producer.request(n)}
+ * and doesn't emit more than requested even if available.
+ *
+ * Note that if the upstream Observable does support backpressure, this operator ignores that capability
+ * and doesn't propagate any backpressure requests from downstream.
+ *
+ * @return the source Observable modified to block {@code onNext} notifications on overflow
+ * @see RxJava wiki: Backpressure
+ * @Experimental The behavior of this can change at any time.
+ */
+ @Experimental
+ public final Observable onBackpressureBlock() {
+ return onBackpressureBlock(rx.internal.util.RxRingBuffer.SIZE);
+ }
+
/**
* Instructs an Observable to pass control to another Observable rather than invoking
* {@link Observer#onError onError} if it encounters an error.
diff --git a/src/main/java/rx/internal/operators/OperatorOnBackpressureBlock.java b/src/main/java/rx/internal/operators/OperatorOnBackpressureBlock.java
new file mode 100644
index 0000000000..bb328788e9
--- /dev/null
+++ b/src/main/java/rx/internal/operators/OperatorOnBackpressureBlock.java
@@ -0,0 +1,157 @@
+/**
+ * Copyright 2014 Netflix, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package rx.internal.operators;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+
+import rx.Observable.Operator;
+import rx.Producer;
+import rx.Subscriber;
+
+/**
+ * Operator that blocks the producer thread in case a backpressure is needed.
+ */
+public class OperatorOnBackpressureBlock implements Operator {
+ final int max;
+ public OperatorOnBackpressureBlock(int max) {
+ this.max = max;
+ }
+ @Override
+ public Subscriber super T> call(Subscriber super T> child) {
+ BlockingSubscriber s = new BlockingSubscriber(max, child);
+ s.init();
+ return s;
+ }
+
+ static final class BlockingSubscriber extends Subscriber {
+ final NotificationLite nl = NotificationLite.instance();
+ final BlockingQueue