This is an automated email from the ASF dual-hosted git repository.

reta pushed a commit to branch 3.5.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git

commit 9a3018b2e1d18e6bb0fd3ba1b5e9877dd4ddbbbc
Author: Andriy Redko <[email protected]>
AuthorDate: Thu Mar 13 17:24:33 2025 -0400

    CXF-9118: DelayedCachedOutputStreamCleaner may expire streams prematurely 
(#2317)
    
    (cherry picked from commit f70c8a7de9c49c25ebd610721d22fa2a206d7f41)
    (cherry picked from commit 3717ebbb75cf30fffcfb7608dd75394d62363b79)
    (cherry picked from commit d13c085ee5d68576baba192f61c74e88263c691c)
---
 .../cxf/io/DelayedCachedOutputStreamCleaner.java   |  2 +-
 .../io/DelayedCachedOutputStreamCleanerTest.java   | 25 ++++++++++++++++++++++
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git 
a/core/src/main/java/org/apache/cxf/io/DelayedCachedOutputStreamCleaner.java 
b/core/src/main/java/org/apache/cxf/io/DelayedCachedOutputStreamCleaner.java
index 524adc0a69..b52d82b71d 100644
--- a/core/src/main/java/org/apache/cxf/io/DelayedCachedOutputStreamCleaner.java
+++ b/core/src/main/java/org/apache/cxf/io/DelayedCachedOutputStreamCleaner.java
@@ -145,7 +145,7 @@ public final class DelayedCachedOutputStreamCleaner 
implements CachedOutputStrea
         
         DelayedCloseable(final Closeable closeable, final long delay) {
             this.closeable = closeable;
-            this.expireAt = System.nanoTime() + delay;
+            this.expireAt = System.nanoTime() + 
TimeUnit.NANOSECONDS.convert(delay, TimeUnit.MILLISECONDS);
         }
 
         @Override
diff --git 
a/core/src/test/java/org/apache/cxf/io/DelayedCachedOutputStreamCleanerTest.java
 
b/core/src/test/java/org/apache/cxf/io/DelayedCachedOutputStreamCleanerTest.java
index 3c6c6a82f7..562b3a18f2 100644
--- 
a/core/src/test/java/org/apache/cxf/io/DelayedCachedOutputStreamCleanerTest.java
+++ 
b/core/src/test/java/org/apache/cxf/io/DelayedCachedOutputStreamCleanerTest.java
@@ -206,6 +206,31 @@ public class DelayedCachedOutputStreamCleanerTest {
 
         assertNoopCleaner(cleaner);
     }
+    
+    @Test
+    public void testDelayedClean() throws InterruptedException {
+        final AtomicInteger latch = new AtomicInteger();
+        final Closeable closeable1 = () -> latch.incrementAndGet();
+        final Closeable closeable2 = () -> latch.incrementAndGet();
+
+        /* Delay of 5 seconds */
+        final Map<String, Object> properties = 
Collections.singletonMap(CachedConstants.CLEANER_DELAY_BUS_PROP, 2500);
+        bus = new ExtensionManagerBus(new HashMap<>(), properties);
+
+        final CachedOutputStreamCleaner cleaner = 
bus.getExtension(CachedOutputStreamCleaner.class);
+        cleaner.register(closeable1);
+
+        Thread.sleep(2000);
+        cleaner.register(closeable2);
+
+        // Await for Closeable::close to be called on schedule
+        await().atMost(3, TimeUnit.SECONDS).untilAtomic(latch, equalTo(1));
+
+        // Await for Closeable::close to be called on schedule
+        await().atMost(5, TimeUnit.SECONDS).untilAtomic(latch, equalTo(2));
+
+        assertThat(cleaner, 
instanceOf(DelayedCachedOutputStreamCleaner.class));
+    }
 
     private void assertNoopCleaner(final CachedOutputStreamCleaner cleaner) {
         final AtomicBoolean latch = new AtomicBoolean(false);

Reply via email to