Align OutputStreamPublisher's

Update constructors to match and drop unnecessary factory methods.

See gh-33592
This commit is contained in:
rstoyanchev
2024-09-24 16:01:22 +01:00
parent 113b430fab
commit f6c31bb6c3
6 changed files with 58 additions and 151 deletions

View File

@@ -68,8 +68,6 @@ public abstract class DataBufferUtils {
private static final Consumer<DataBuffer> RELEASE_CONSUMER = DataBufferUtils::release;
private static final int DEFAULT_CHUNK_SIZE = 1024;
//---------------------------------------------------------------------
// Reading
@@ -442,48 +440,17 @@ public abstract class DataBufferUtils {
public static Publisher<DataBuffer> outputStreamPublisher(Consumer<OutputStream> outputStreamConsumer,
DataBufferFactory bufferFactory, Executor executor) {
return outputStreamPublisher(outputStreamConsumer, bufferFactory, executor, DEFAULT_CHUNK_SIZE);
return new OutputStreamPublisher(outputStreamConsumer, bufferFactory, executor, null);
}
/**
* Creates a new {@code Publisher<DataBuffer>} based on bytes written to a
* {@code OutputStream}.
* <ul>
* <li>The parameter {@code outputStreamConsumer} is invoked once per
* subscription of the returned {@code Publisher}, when the first
* item is
* {@linkplain Subscription#request(long) requested}.</li>
* <li>{@link OutputStream#write(byte[], int, int) OutputStream.write()}
* invocations made by {@code outputStreamHandler} are buffered until they
* reach or exceed {@code chunkSize}, or when the stream is
* {@linkplain OutputStream#flush() flushed} and then result in a
* {@linkplain Subscriber#onNext(Object) published} item
* if there is {@linkplain Subscription#request(long) demand}.</li>
* <li>If there is <em>no demand</em>, {@code OutputStream.write()} will block
* until there is.</li>
* <li>If the subscription is {@linkplain Subscription#cancel() cancelled},
* {@code OutputStream.write()} will throw a {@code IOException}.</li>
* <li>The subscription is
* {@linkplain Subscriber#onComplete() completed} when
* {@code outputStreamHandler} completes.</li>
* <li>Any exceptions thrown from {@code outputStreamHandler} will
* be dispatched to the {@linkplain Subscriber#onError(Throwable) Subscriber}.
* </ul>
* @param outputStreamConsumer invoked when the first buffer is requested
* @param executor used to invoke the {@code outputStreamHandler}
* @param chunkSize minimum size of the buffer produced by the publisher
* @return a {@code Publisher<DataBuffer>} based on bytes written by
* {@code outputStreamHandler}
* Variant of {@link #outputStreamPublisher(Consumer, DataBufferFactory, Executor)}
* providing control over the chunk sizes to be produced by the publisher.
* @since 6.1
*/
public static Publisher<DataBuffer> outputStreamPublisher(Consumer<OutputStream> outputStreamConsumer,
DataBufferFactory bufferFactory, Executor executor, int chunkSize) {
Assert.notNull(outputStreamConsumer, "OutputStreamConsumer must not be null");
Assert.notNull(bufferFactory, "BufferFactory must not be null");
Assert.notNull(executor, "Executor must not be null");
Assert.isTrue(chunkSize > 0, "Chunk size must be > 0");
return new OutputStreamPublisher(outputStreamConsumer, bufferFactory, executor, chunkSize);
}

View File

@@ -31,10 +31,10 @@ import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Bridges between {@link OutputStream} and
* {@link Publisher Publisher&lt;DataBuffer&gt;}.
* Bridges between {@link OutputStream} and {@link Publisher Publisher&lt;DataBuffer&gt;}.
*
* <p>Note that this class has a near duplicate in
* {@link org.springframework.http.client.OutputStreamPublisher}.
@@ -45,6 +45,9 @@ import org.springframework.lang.Nullable;
*/
final class OutputStreamPublisher implements Publisher<DataBuffer> {
private static final int DEFAULT_CHUNK_SIZE = 1024;
private final Consumer<OutputStream> outputStreamConsumer;
private final DataBufferFactory bufferFactory;
@@ -54,14 +57,26 @@ final class OutputStreamPublisher implements Publisher<DataBuffer> {
private final int chunkSize;
/**
* Create an instance.
* @param outputStreamConsumer invoked when the first buffer is requested
* @param bufferFactory to create data buffers with
* @param executor used to invoke the {@code outputStreamHandler}
* @param chunkSize the chunk sizes to be produced by the publisher
*/
OutputStreamPublisher(
Consumer<OutputStream> outputStreamConsumer, DataBufferFactory bufferFactory,
Executor executor, int chunkSize) {
Executor executor, @Nullable Integer chunkSize) {
Assert.notNull(outputStreamConsumer, "OutputStreamConsumer must not be null");
Assert.notNull(bufferFactory, "BufferFactory must not be null");
Assert.notNull(executor, "Executor must not be null");
Assert.isTrue(chunkSize == null || chunkSize > 0, "ChunkSize must be larger than 0");
this.outputStreamConsumer = outputStreamConsumer;
this.bufferFactory = bufferFactory;
this.executor = executor;
this.chunkSize = chunkSize;
this.chunkSize = (chunkSize != null ? chunkSize : DEFAULT_CHUNK_SIZE);
}