[ 
https://issues.apache.org/jira/browse/IO-867?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17927542#comment-17927542
 ] 

Constantin Stropsa commented on IO-867:
---------------------------------------

[~ggregory] 

I assume [~nielsm5] wanted to say that after the threshold is reached and the 
threshold consumer is called, on next write to the underlying stream, the 
threshold consumer will not be called again. 
This is because the `thresholdExceeded` instance variable, once set to true in 
the `checkThreshold` method when reaching the threshold, remain in `true` 
state. Any further call for `checkThreshold(..)` method will not do anything 
because `thresholdExceeded` is set to true.
A unit test to show this:
{code:java}
        @Test
        public void 
testThresholdConsumerNotTriggeredWhenStreamExceededThreshold() throws Exception 
{
                final AtomicInteger counter = new AtomicInteger(0);
                final int initCount = 0;
                final int threshold = 1;

                try (final ByteArrayOutputStream os = new 
ByteArrayOutputStream(4);
                                ThresholdingOutputStream out = new 
ThresholdingOutputStream(threshold, t -> {
                                        counter.incrementAndGet();
                                }, o -> os)) {
                        out.write('a');
                        assertFalse(out.isThresholdExceeded());
                        out.write('a');
                        assertTrue(out.isThresholdExceeded());
                        assertFalse(counter.get() == 2);
                }
        }
{code}
As I can understand from the code, this is an expected behavior and can be 
reset by calling `resetByteCount()` method if needed.
{code:java}
        @Test
        public void 
testThresholdConsumerTriggeredThoTimesWhenStreamExceededThreshold() throws 
Exception {
                final AtomicInteger counter = new AtomicInteger(0);
                final int initCount = 0;
                final int threshold = 1;
                
                try (final ByteArrayOutputStream os = new 
ByteArrayOutputStream(4);
                                ThresholdingOutputStream out = new 
ThresholdingOutputStream(threshold, t -> {
                                        counter.incrementAndGet();
                                        t.resetByteCount();
                                }, o -> os)) {
                        out.write('a');
                        assertFalse(out.isThresholdExceeded());
                        out.write('a');
                        assertFalse(out.isThresholdExceeded());
                        out.write('a');
                        out.write('a');
                        assertFalse(counter.get() == 2);
                }
        }
{code}
 
----

Your assumption is correct, but we get to quicksand here.
If write fails, it does not mean that it did not write anything to the channel, 
it could be it was a partial success and some data still went through...

> Fix ThresholdingOutputStream#isThresholdExceeded
> ------------------------------------------------
>
>                 Key: IO-867
>                 URL: https://issues.apache.org/jira/browse/IO-867
>             Project: Commons IO
>          Issue Type: Bug
>          Components: Streams/Writers
>    Affects Versions: 2.18.0
>         Environment: Java
>            Reporter: Niels
>            Priority: Critical
>
> The ThresholdingOutputStream has a beautiful boolean field called 
> thresholdExceeded, yet the corresponding getter returns `written > threshold`.
> This means after `#thresholdReached()`, the next time `#getStream()` is 
> called the 'threshold getter' returns false!
> This causes very inconsistent behavior...



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to