You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by re...@apache.org on 2025/03/13 21:34:03 UTC

(cxf) 02/02: CXF-9118: DelayedCachedOutputStreamCleaner may expire streams prematurely (#2317)

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

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

commit 3717ebbb75cf30fffcfb7608dd75394d62363b79
Author: Andriy Redko <dr...@gmail.com>
AuthorDate: Thu Mar 13 17:24:33 2025 -0400

    CXF-9118: DelayedCachedOutputStreamCleaner may expire streams prematurely (#2317)
    
    (cherry picked from commit f70c8a7de9c49c25ebd610721d22fa2a206d7f41)
---
 .../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 4d76b65425..77721d115f 100644
--- a/core/src/main/java/org/apache/cxf/io/DelayedCachedOutputStreamCleaner.java
+++ b/core/src/main/java/org/apache/cxf/io/DelayedCachedOutputStreamCleaner.java
@@ -144,7 +144,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);