Description
A failed DatabaseFactory.open() (e.g. the path does not exist) leaves the engine's global non-daemon "ArcadeDB AsyncFlush" thread (PageManagerFlushThread) running with nothing to stop it, so the JVM never exits: main returns but the process hangs forever in DestroyJavaVM.
Reproduction (pure Java, current main / 26.8.1-SNAPSHOT)
import com.arcadedb.database.DatabaseFactory;
public class HangRepro {
public static void main(String[] args) {
try (DatabaseFactory f = new DatabaseFactory("/tmp/definitely_missing_db")) {
f.open();
} catch (Exception e) {
System.out.println("caught: " + e.getClass().getSimpleName());
}
System.out.println("main returning; JVM should exit now");
}
}
Output: both lines print, then the process hangs indefinitely (verified with timeout 25 java ... HangRepro → exit 124). A thread dump shows the only non-daemon thread besides main is ArcadeDB AsyncFlush.
Analysis
PageManager.INSTANCE starts its flush thread on first storage access during the open attempt; on open failure no code path reaches PageManager.close() (which would flushThread.closeAndJoin()). Successful open/close life-cycles stop it correctly — only the failed-open path leaks the thread.
Possible fixes: stop/never-start the flush thread when the open aborts, make the thread daemon, or ref-count PageManager usage.
Impact
- Any Java application that probes a database path and gets an exception cannot exit cleanly afterwards.
- Found via the Python bindings (a Python process hung the same way); the bindings now carry an
atexit workaround that closes the PageManager on interpreter exit, but the root cause is engine-side.
Description
A failed
DatabaseFactory.open()(e.g. the path does not exist) leaves the engine's global non-daemon "ArcadeDB AsyncFlush" thread (PageManagerFlushThread) running with nothing to stop it, so the JVM never exits:mainreturns but the process hangs forever inDestroyJavaVM.Reproduction (pure Java, current
main/ 26.8.1-SNAPSHOT)Output: both lines print, then the process hangs indefinitely (verified with
timeout 25 java ... HangRepro→ exit 124). A thread dump shows the only non-daemon thread besidesmainisArcadeDB AsyncFlush.Analysis
PageManager.INSTANCEstarts its flush thread on first storage access during the open attempt; on open failure no code path reachesPageManager.close()(which wouldflushThread.closeAndJoin()). Successful open/close life-cycles stop it correctly — only the failed-open path leaks the thread.Possible fixes: stop/never-start the flush thread when the open aborts, make the thread daemon, or ref-count PageManager usage.
Impact
atexitworkaround that closes the PageManager on interpreter exit, but the root cause is engine-side.