Skip to content

Commit 4c1e110

Browse files
committed
Add support to ThrottledInputStream for setting a consumer for
ProxyInputStream.afterRead(int)
1 parent 55aa76a commit 4c1e110

3 files changed

Lines changed: 40 additions & 9 deletions

File tree

src/changes/changes.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ The <action> type attribute can be add,update,fix,remove.
7070
<action dev="ggregory" type="add" due-to="Gary Gregory">Add support to BOMInputStream for setting a consumer for ProxyInputStream.afterRead(int).</action>
7171
<action dev="ggregory" type="add" issue="IO-861" due-to="Gary Gregory">Add support to BoundedInputStream for setting a consumer for ProxyInputStream.afterRead(int).</action>
7272
<action dev="ggregory" type="add" due-to="Gary Gregory">Add support to ChecksumInputStream for setting a consumer for ProxyInputStream.afterRead(int).</action>
73+
<action dev="ggregory" type="add" due-to="Gary Gregory">Add support to ThrottledInputStream for setting a consumer for ProxyInputStream.afterRead(int).</action>
7374
<!-- UPDATE -->
7475
<action dev="ggregory" type="update" due-to="Gary Gregory">Bump org.apache.commons:commons-parent from 74 to 78 #670, #676, #679, #688.</action>
7576
<action dev="ggregory" type="update" due-to="Gary Gregory">Bump commons.bytebuddy.version from 1.15.1 to 1.15.10 #672, #673, #685, #686, #694, #696, #698.</action>

src/main/java/org/apache/commons/io/input/ThrottledInputStream.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
import java.time.temporal.ChronoUnit;
2525
import java.util.concurrent.TimeUnit;
2626

27-
import org.apache.commons.io.build.AbstractStreamBuilder;
28-
2927
/**
3028
* Provides bandwidth throttling on a specified InputStream. It is implemented as a wrapper on top of another InputStream instance. The throttling works by
3129
* examining the number of bytes read from the underlying InputStream from the beginning, and sleep()ing for a time interval if the byte-transfer is found
@@ -74,7 +72,7 @@ public final class ThrottledInputStream extends CountingInputStream {
7472
* @see #get()
7573
*/
7674
// @formatter:on
77-
public static class Builder extends AbstractStreamBuilder<ThrottledInputStream, Builder> {
75+
public static class Builder extends AbstractBuilder<ThrottledInputStream, Builder> {
7876

7977
/**
8078
* Effectively not throttled.
@@ -103,7 +101,7 @@ public static class Builder extends AbstractStreamBuilder<ThrottledInputStream,
103101
@SuppressWarnings("resource")
104102
@Override
105103
public ThrottledInputStream get() throws IOException {
106-
return new ThrottledInputStream(getInputStream(), maxBytesPerSecond);
104+
return new ThrottledInputStream(this);
107105
}
108106

109107
/**
@@ -147,12 +145,12 @@ static long toSleepMillis(final long bytesRead, final long maxBytesPerSec, final
147145
private final long startTime = System.currentTimeMillis();
148146
private Duration totalSleepDuration = Duration.ZERO;
149147

150-
private ThrottledInputStream(final InputStream proxy, final long maxBytesPerSecond) {
151-
super(proxy);
152-
if (maxBytesPerSecond <= 0) {
153-
throw new IllegalArgumentException("Bandwidth " + maxBytesPerSecond + " is invalid.");
148+
private ThrottledInputStream(final Builder builder) throws IOException {
149+
super(builder);
150+
if (builder.maxBytesPerSecond <= 0) {
151+
throw new IllegalArgumentException("Bandwidth " + builder.maxBytesPerSecond + " is invalid.");
154152
}
155-
this.maxBytesPerSecond = maxBytesPerSecond;
153+
this.maxBytesPerSecond = builder.maxBytesPerSecond;
156154
}
157155

158156
@Override

src/test/java/org/apache/commons/io/input/ThrottledInputStreamTest.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,16 @@
1818
package org.apache.commons.io.input;
1919

2020
import static org.junit.jupiter.api.Assertions.assertEquals;
21+
import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
22+
import static org.junit.jupiter.api.Assertions.assertTrue;
2123

2224
import java.io.IOException;
25+
import java.io.InputStream;
2326
import java.time.Duration;
27+
import java.util.concurrent.atomic.AtomicBoolean;
2428

29+
import org.apache.commons.io.IOUtils;
30+
import org.apache.commons.io.test.CustomIOException;
2531
import org.junit.jupiter.api.Test;
2632

2733
/**
@@ -35,6 +41,32 @@ protected ThrottledInputStream createFixture() throws IOException {
3541
return ThrottledInputStream.builder().setInputStream(createOriginInputStream()).get();
3642
}
3743

44+
@Test
45+
public void testAfterReadConsumer() throws Exception {
46+
final AtomicBoolean boolRef = new AtomicBoolean();
47+
// @formatter:off
48+
try (InputStream bounded = ThrottledInputStream.builder()
49+
.setCharSequence("Hi")
50+
.setAfterRead(i -> boolRef.set(true))
51+
.get()) {
52+
IOUtils.consume(bounded);
53+
}
54+
// @formatter:on
55+
assertTrue(boolRef.get());
56+
// Throwing
57+
final String message = "test exception message";
58+
// @formatter:off
59+
try (InputStream bounded = ThrottledInputStream.builder()
60+
.setCharSequence("Hi")
61+
.setAfterRead(i -> {
62+
throw new CustomIOException(message);
63+
})
64+
.get()) {
65+
assertEquals(message, assertThrowsExactly(CustomIOException.class, () -> IOUtils.consume(bounded)).getMessage());
66+
}
67+
// @formatter:on
68+
}
69+
3870
@Test
3971
public void testCalSleepTimeMs() {
4072
// case 0: initial - no read, no sleep

0 commit comments

Comments
 (0)