[
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