[ 
https://issues.apache.org/jira/browse/AMQ-9856?focusedWorklogId=1004921&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1004921
 ]

ASF GitHub Bot logged work on AMQ-9856:
---------------------------------------

                Author: ASF GitHub Bot
            Created on: 12/Feb/26 17:33
            Start Date: 12/Feb/26 17:33
    Worklog Time Spent: 10m 
      Work Description: jeanouii commented on code in PR #1654:
URL: https://github.com/apache/activemq/pull/1654#discussion_r2800175557


##########
activemq-broker/src/main/java/org/apache/activemq/util/IOHelper.java:
##########
@@ -28,20 +28,128 @@
 import java.nio.file.StandardCopyOption;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Queue;
 import java.util.Stack;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Collection of File and Folder utility methods.
  */
 public final class IOHelper {
 
+    private static final Logger LOG = LoggerFactory.getLogger(IOHelper.class);
+
     protected static final int MAX_DIR_NAME_LENGTH;
     protected static final int MAX_FILE_NAME_LENGTH;
     private static final int DEFAULT_BUFFER_SIZE = 4096;
+    private static final boolean IS_WINDOWS = System.getProperty("os.name", 
"").toLowerCase().contains("win");
+
+    // Async cleanup for files that couldn't be deleted immediately (Windows 
file locking)
+    private static final Queue<File> PENDING_DELETES = new 
ConcurrentLinkedQueue<>();
+    private static final ScheduledExecutorService CLEANUP_EXECUTOR;
+
+    static {
+        MAX_DIR_NAME_LENGTH = Integer.getInteger("MaximumDirNameLength", 200);
+        MAX_FILE_NAME_LENGTH = Integer.getInteger("MaximumFileNameLength", 64);
+
+        // Only start cleanup thread on Windows where file locking is an issue
+        if (IS_WINDOWS) {
+            CLEANUP_EXECUTOR = Executors.newSingleThreadScheduledExecutor(r -> 
{
+                final Thread t = new Thread(r, "IOHelper-AsyncCleanup");
+                t.setDaemon(true);
+                return t;
+            });
+            
CLEANUP_EXECUTOR.scheduleWithFixedDelay(IOHelper::processAsyncDeletes, 5, 5, 
TimeUnit.SECONDS);
+        } else {
+            CLEANUP_EXECUTOR = null;
+        }
+    }
 
     private IOHelper() {
     }
 
+    /**
+     * Process pending async deletes. Called periodically on Windows.
+     */
+    private static void processAsyncDeletes() {
+        int processed = 0;
+        File file;
+        while ((file = PENDING_DELETES.poll()) != null && processed < 100) {
+            processed++;
+            if (file.exists()) {
+                if (file.delete()) {
+                    LOG.debug("Async cleanup: deleted {}", file);
+                } else {
+                    // Still locked, re-queue for later
+                    PENDING_DELETES.offer(file);
+                }
+            }
+        }
+    }
+
+    /**
+     * Schedule a file for async deletion. Used when immediate deletion fails 
on Windows.
+     * The file will be deleted in the background when it becomes unlocked.
+     */
+    public static void scheduleAsyncDelete(File file) {
+        if (file != null && file.exists()) {
+            if (IS_WINDOWS && CLEANUP_EXECUTOR != null) {
+                PENDING_DELETES.offer(file);
+                LOG.debug("Scheduled async delete for: {}", file);
+            } else {
+                // On non-Windows, just use deleteOnExit
+                file.deleteOnExit();
+            }
+        }

Review Comment:
   Can we test it in both places?
   





Issue Time Tracking
-------------------

    Worklog Id:     (was: 1004921)
    Time Spent: 40m  (was: 0.5h)

> KahaDB Journal move fails on Windows
> ------------------------------------
>
>                 Key: AMQ-9856
>                 URL: https://issues.apache.org/jira/browse/AMQ-9856
>             Project: ActiveMQ
>          Issue Type: Bug
>          Components: KahaDB
>            Reporter: Jean-Louis Monteiro
>            Assignee: Jean-Louis Monteiro
>            Priority: Major
>             Fix For: 6.3.0
>
>          Time Spent: 40m
>  Remaining Estimate: 0h
>
> On Windows, files cannot be renamed/moved while open by another process. The 
> simplest and most appropriate fix is to skip this test on Windows where file 
> locking makes it inherently unreliable.
> {code:java}
> java.io.IOException: Failed to move 
> target\activemq-data\localhost\KahaDB\db-6.log to 
> D:\a\activemq\activemq\activemq-kahadb-store\target\activemq-data\localhost\KahaDB\data-archive
>  - target\activemq-data\localhost\KahaDB\db-6.log -> 
> D:\a\activemq\activemq\activemq-kahadb-store\target\activemq-data\localhost\KahaDB\data-archive\db-6.log:
>  The process cannot access the file because it is being used by another 
> process
>       at org.apache.activemq.util.IOHelper.moveFile(IOHelper.java:200)
>       at 
> org.apache.activemq.store.kahadb.disk.journal.DataFile.move(DataFile.java:107)
>       at 
> org.apache.activemq.store.kahadb.disk.journal.Journal.forceRemoveDataFile(Journal.java:833)
>       at 
> org.apache.activemq.store.kahadb.disk.journal.Journal.removeDataFiles(Journal.java:812)
>       at 
> org.apache.activemq.store.kahadb.MessageDatabase.checkpointUpdate(MessageDatabase.java:1701)
>       at 
> org.apache.activemq.store.kahadb.MessageDatabase.checkpointCleanup(MessageDatabase.java:1035)
>       at 
> org.apache.activemq.store.kahadb.KahaDBStore.checkpoint(KahaDBStore.java:1481)
>  {code}
>  
>  



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

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information, visit: https://activemq.apache.org/contact


Reply via email to