diff --git a/src/main/java/io/reactivex/rxjava3/core/Flowable.java b/src/main/java/io/reactivex/rxjava3/core/Flowable.java
index e55b808633..04f98a2aa2 100644
--- a/src/main/java/io/reactivex/rxjava3/core/Flowable.java
+++ b/src/main/java/io/reactivex/rxjava3/core/Flowable.java
@@ -19,7 +19,7 @@
import io.reactivex.rxjava3.annotations.*;
import io.reactivex.rxjava3.disposables.Disposable;
-import io.reactivex.rxjava3.exceptions.Exceptions;
+import io.reactivex.rxjava3.exceptions.*;
import io.reactivex.rxjava3.flowables.*;
import io.reactivex.rxjava3.functions.*;
import io.reactivex.rxjava3.internal.functions.*;
@@ -10421,13 +10421,16 @@ public final Disposable forEachWhile(final Predicate super T> onNext, final Co
*
*
*
Backpressure:
- *
Both the returned and its inner {@code Publisher}s honor backpressure and the source {@code Publisher}
- * is consumed in a bounded mode (i.e., requested a fixed amount upfront and replenished based on
- * downstream consumption). Note that both the returned and its inner {@code Publisher}s use
- * unbounded internal buffers and if the source {@code Publisher} doesn't honor backpressure, that may
- * lead to {@code OutOfMemoryError}.
+ *
The consumer of the returned {@code Flowable} has to be ready to receive new {@code GroupedFlowable}s or else
+ * this operator will signal {@link MissingBackpressureException}. To avoid this exception, make
+ * sure a combining operator (such as {@code flatMap}) has adequate amount of buffering/prefetch configured.
+ * The inner {@code GroupedFlowable}s honor backpressure but due to the single-source multiple consumer
+ * nature of this operator, each group must be consumed so the whole operator can make progress and not hang.
*
Scheduler:
*
{@code groupBy} does not operate by default on a particular {@link Scheduler}.
+ *
Error handling:
+ *
If the upstream signals or the callback(s) throw an exception, the returned {@code Flowable} and
+ * all active inner {@code GroupedFlowable}s will signal the same exception.
*
*
* @param keySelector
@@ -10438,9 +10441,11 @@ public final Disposable forEachWhile(final Predicate super T> onNext, final Co
* unique key value and each of which emits those items from the source Publisher that share that
* key value
* @see ReactiveX operators documentation: GroupBy
+ * @see #groupBy(Function, boolean)
+ * @see #groupBy(Function, Function)
*/
@CheckReturnValue
- @BackpressureSupport(BackpressureKind.FULL)
+ @BackpressureSupport(BackpressureKind.ERROR)
@SchedulerSupport(SchedulerSupport.NONE)
public final Flowable> groupBy(Function super T, ? extends K> keySelector) {
return groupBy(keySelector, Functions.identity(), false, bufferSize());
@@ -10474,13 +10479,16 @@ public final Flowable> groupBy(Function super T, ? e
*
*
*
Backpressure:
- *
Both the returned and its inner {@code Publisher}s honor backpressure and the source {@code Publisher}
- * is consumed in a bounded mode (i.e., requested a fixed amount upfront and replenished based on
- * downstream consumption). Note that both the returned and its inner {@code Publisher}s use
- * unbounded internal buffers and if the source {@code Publisher} doesn't honor backpressure, that may
- * lead to {@code OutOfMemoryError}.
+ *
The consumer of the returned {@code Flowable} has to be ready to receive new {@code GroupedFlowable}s or else
+ * this operator will signal {@link MissingBackpressureException}. To avoid this exception, make
+ * sure a combining operator (such as {@code flatMap}) has adequate amount of buffering/prefetch configured.
+ * The inner {@code GroupedFlowable}s honor backpressure but due to the single-source multiple consumer
+ * nature of this operator, each group must be consumed so the whole operator can make progress and not hang.
*
Scheduler:
*
{@code groupBy} does not operate by default on a particular {@link Scheduler}.
+ *
Error handling:
+ *
If the upstream signals or the callback(s) throw an exception, the returned {@code Flowable} and
+ * all active inner {@code GroupedFlowable}s will signal the same exception.
*
*
* @param keySelector
@@ -10496,7 +10504,7 @@ public final Flowable> groupBy(Function super T, ? e
* @see ReactiveX operators documentation: GroupBy
*/
@CheckReturnValue
- @BackpressureSupport(BackpressureKind.FULL)
+ @BackpressureSupport(BackpressureKind.ERROR)
@SchedulerSupport(SchedulerSupport.NONE)
public final Flowable> groupBy(Function super T, ? extends K> keySelector, boolean delayError) {
return groupBy(keySelector, Functions.identity(), delayError, bufferSize());
@@ -10530,13 +10538,16 @@ public final Flowable> groupBy(Function super T, ? e
*
*
*
Backpressure:
- *
Both the returned and its inner {@code Publisher}s honor backpressure and the source {@code Publisher}
- * is consumed in a bounded mode (i.e., requested a fixed amount upfront and replenished based on
- * downstream consumption). Note that both the returned and its inner {@code Publisher}s use
- * unbounded internal buffers and if the source {@code Publisher} doesn't honor backpressure, that may
- * lead to {@code OutOfMemoryError}.
+ *
The consumer of the returned {@code Flowable} has to be ready to receive new {@code GroupedFlowable}s or else
+ * this operator will signal {@link MissingBackpressureException}. To avoid this exception, make
+ * sure a combining operator (such as {@code flatMap}) has adequate amount of buffering/prefetch configured.
+ * The inner {@code GroupedFlowable}s honor backpressure but due to the single-source multiple consumer
+ * nature of this operator, each group must be consumed so the whole operator can make progress and not hang.
*
Scheduler:
*
{@code groupBy} does not operate by default on a particular {@link Scheduler}.
+ *
Error handling:
+ *
If the upstream signals or the callback(s) throw an exception, the returned {@code Flowable} and
+ * all active inner {@code GroupedFlowable}s will signal the same exception.
*
*
* @param keySelector
@@ -10551,9 +10562,12 @@ public final Flowable> groupBy(Function super T, ? e
* unique key value and each of which emits those items from the source Publisher that share that
* key value
* @see ReactiveX operators documentation: GroupBy
+ * @see #groupBy(Function, Function, boolean)
+ * @see #groupBy(Function, Function, boolean, int)
+ * @see #groupBy(Function, Function, boolean, int, Function)
*/
@CheckReturnValue
- @BackpressureSupport(BackpressureKind.FULL)
+ @BackpressureSupport(BackpressureKind.ERROR)
@SchedulerSupport(SchedulerSupport.NONE)
public final Flowable> groupBy(Function super T, ? extends K> keySelector,
Function super T, ? extends V> valueSelector) {
@@ -10588,13 +10602,16 @@ public final Flowable> groupBy(Function super T,
*
*
*
Backpressure:
- *
Both the returned and its inner {@code Publisher}s honor backpressure and the source {@code Publisher}
- * is consumed in a bounded mode (i.e., requested a fixed amount upfront and replenished based on
- * downstream consumption). Note that both the returned and its inner {@code Publisher}s use
- * unbounded internal buffers and if the source {@code Publisher} doesn't honor backpressure, that may
- * lead to {@code OutOfMemoryError}.
+ *
The consumer of the returned {@code Flowable} has to be ready to receive new {@code GroupedFlowable}s or else
+ * this operator will signal {@link MissingBackpressureException}. To avoid this exception, make
+ * sure a combining operator (such as {@code flatMap}) has adequate amount of buffering/prefetch configured.
+ * The inner {@code GroupedFlowable}s honor backpressure but due to the single-source multiple consumer
+ * nature of this operator, each group must be consumed so the whole operator can make progress and not hang.
*
Scheduler:
*
{@code groupBy} does not operate by default on a particular {@link Scheduler}.
+ *
Error handling:
+ *
If the upstream signals or the callback(s) throw an exception, the returned {@code Flowable} and
+ * all active inner {@code GroupedFlowable}s will signal the same exception.
*
*
* @param keySelector
@@ -10612,9 +10629,10 @@ public final Flowable> groupBy(Function super T,
* unique key value and each of which emits those items from the source Publisher that share that
* key value
* @see ReactiveX operators documentation: GroupBy
+ * @see #groupBy(Function, Function, boolean, int)
*/
@CheckReturnValue
- @BackpressureSupport(BackpressureKind.FULL)
+ @BackpressureSupport(BackpressureKind.ERROR)
@SchedulerSupport(SchedulerSupport.NONE)
public final Flowable> groupBy(Function super T, ? extends K> keySelector,
Function super T, ? extends V> valueSelector, boolean delayError) {
@@ -10649,13 +10667,16 @@ public final Flowable> groupBy(Function super T,
*
*
*
Backpressure:
- *
Both the returned and its inner {@code Publisher}s honor backpressure and the source {@code Publisher}
- * is consumed in a bounded mode (i.e., requested a fixed amount upfront and replenished based on
- * downstream consumption). Note that both the returned and its inner {@code Publisher}s use
- * unbounded internal buffers and if the source {@code Publisher} doesn't honor backpressure, that may
- * lead to {@code OutOfMemoryError}.
+ *
The consumer of the returned {@code Flowable} has to be ready to receive new {@code GroupedFlowable}s or else
+ * this operator will signal {@link MissingBackpressureException}. To avoid this exception, make
+ * sure a combining operator (such as {@code flatMap}) has adequate amount of buffering/prefetch configured.
+ * The inner {@code GroupedFlowable}s honor backpressure but due to the single-source multiple consumer
+ * nature of this operator, each group must be consumed so the whole operator can make progress and not hang.
*
Scheduler:
*
{@code groupBy} does not operate by default on a particular {@link Scheduler}.
+ *
Error handling:
+ *
If the upstream signals or the callback(s) throw an exception, the returned {@code Flowable} and
+ * all active inner {@code GroupedFlowable}s will signal the same exception.
*
*
* @param keySelector
@@ -10678,7 +10699,7 @@ public final Flowable> groupBy(Function super T,
*/
@CheckReturnValue
@NonNull
- @BackpressureSupport(BackpressureKind.FULL)
+ @BackpressureSupport(BackpressureKind.SPECIAL)
@SchedulerSupport(SchedulerSupport.NONE)
public final Flowable> groupBy(Function super T, ? extends K> keySelector,
Function super T, ? extends V> valueSelector,
@@ -10759,13 +10780,16 @@ public final Flowable> groupBy(Function super T,
*
*
*
Backpressure:
- *
Both the returned and its inner {@code GroupedFlowable}s honor backpressure and the source {@code Publisher}
- * is consumed in a bounded mode (i.e., requested a fixed amount upfront and replenished based on
- * downstream consumption). Note that both the returned and its inner {@code GroupedFlowable}s use
- * unbounded internal buffers and if the source {@code Publisher} doesn't honor backpressure, that may
- * lead to {@code OutOfMemoryError}.
+ *
The consumer of the returned {@code Flowable} has to be ready to receive new {@code GroupedFlowable}s or else
+ * this operator will signal {@link MissingBackpressureException}. To avoid this exception, make
+ * sure a combining operator (such as {@code flatMap}) has adequate amount of buffering/prefetch configured.
+ * The inner {@code GroupedFlowable}s honor backpressure but due to the single-source multiple consumer
+ * nature of this operator, each group must be consumed so the whole operator can make progress and not hang.
*
Scheduler:
*
{@code groupBy} does not operate by default on a particular {@link Scheduler}.
+ *
Error handling:
+ *
If the upstream signals or the callback(s) throw an exception, the returned {@code Flowable} and
+ * all active inner {@code GroupedFlowable}s will signal the same exception.
*
*
History: 2.1.10 - beta
* @param keySelector
@@ -10796,7 +10820,7 @@ public final Flowable> groupBy(Function super T,
*/
@CheckReturnValue
@NonNull
- @BackpressureSupport(BackpressureKind.FULL)
+ @BackpressureSupport(BackpressureKind.SPECIAL)
@SchedulerSupport(SchedulerSupport.NONE)
public final Flowable> groupBy(Function super T, ? extends K> keySelector,
Function super T, ? extends V> valueSelector,
diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableGroupBy.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableGroupBy.java
index 6b76558a5e..85c7d08289 100644
--- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableGroupBy.java
+++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/FlowableGroupBy.java
@@ -21,7 +21,7 @@
import io.reactivex.rxjava3.annotations.Nullable;
import io.reactivex.rxjava3.core.*;
-import io.reactivex.rxjava3.exceptions.Exceptions;
+import io.reactivex.rxjava3.exceptions.*;
import io.reactivex.rxjava3.flowables.GroupedFlowable;
import io.reactivex.rxjava3.functions.*;
import io.reactivex.rxjava3.internal.queue.SpscLinkedArrayQueue;
@@ -74,8 +74,8 @@ protected void subscribeActual(Subscriber super GroupedFlowable> s) {
}
public static final class GroupBySubscriber
- extends BasicIntQueueSubscription>
- implements FlowableSubscriber {
+ extends AtomicLong
+ implements FlowableSubscriber, Subscription {
private static final long serialVersionUID = -3688291656102519502L;
@@ -83,9 +83,9 @@ public static final class GroupBySubscriber
final Function super T, ? extends K> keySelector;
final Function super T, ? extends V> valueSelector;
final int bufferSize;
+ final int limit;
final boolean delayError;
final Map