Parcourir la source

fix: Cache threading issues
new: assira.ee project

Ranides Atterwim il y a 9 ans
Parent
commit
c70250fe95

+ 36 - 0
assira.enterprise/pom.xml

@@ -0,0 +1,36 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <parent>
+        <groupId>net.ranides</groupId>
+        <artifactId>assira.project</artifactId>
+        <version>2.1.0</version>
+        <relativePath>..</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>assira.enterprise</artifactId>
+    <packaging>jar</packaging>
+
+    <properties>
+        <assira.junit.debug>false</assira.junit.debug>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>net.ranides</groupId>
+            <artifactId>assira</artifactId>
+            <version>2.1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>net.ranides</groupId>
+            <artifactId>assira.junit</artifactId>
+            <version>2.1.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax</groupId>
+            <artifactId>javaee-api</artifactId>
+            <version>7.0</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>

+ 28 - 0
assira.enterprise/src/main/java/net/ranides/assira/ee/CacheMapCleaner.java

@@ -0,0 +1,28 @@
+package net.ranides.assira.ee;
+
+import net.ranides.assira.collection.maps.CacheMap;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.ejb.Singleton;
+import javax.ejb.Startup;
+
+@Singleton
+@Startup
+public class CacheMapCleaner {
+
+    private Thread thread;
+
+    @PostConstruct
+    public void init() {
+        thread = new Thread(() -> CacheMap.cleanup(true), "assira.ee cache cleanup");
+        thread.setDaemon(true);
+        thread.start();
+    }
+
+    @PreDestroy
+    public void destroy() {
+        thread.interrupt();
+    }
+
+}

+ 35 - 7
assira/src/main/java/net/ranides/assira/collection/maps/CacheMap.java

@@ -17,6 +17,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Function;
 import java.util.function.Supplier;
 
+import net.ranides.assira.reflection.util.ClassUtils;
 import net.ranides.assira.system.RuntimeUtils;
 
 /**
@@ -26,11 +27,13 @@ public abstract class CacheMap<K,V> implements Cache<K,V> {
 
     protected static final ReferenceQueue QUEUE = new ReferenceQueue<>();
 
-    protected static final boolean USE_THREAD = RuntimeUtils.getProperty("assira.cache.no-threads", "false").equals("false");
+    protected static final boolean USE_THREAD = isThreadEnabled();
 
     static {
         if(USE_THREAD) {
-            new Thread(CacheMap::cleanupThread, "assira cache cleanup").start();
+            Thread thread = new Thread(CacheMap::cleanupRemove, "assira cache cleanup");
+            thread.setDaemon(true);
+            thread.start();
         }
     }
 
@@ -87,16 +90,28 @@ public abstract class CacheMap<K,V> implements Cache<K,V> {
 
     protected abstract void iclear();
 
+    public static void cleanup(boolean block) {
+        if(block) {
+            cleanupRemove();
+        } else {
+            cleanupPoll();
+        }
+    }
+
     protected static void cleanup() {
         if(!USE_THREAD) {
-            KRef ref;
-            while ( null != (ref = (KRef)QUEUE.poll()) ) {
-                ref.src.iremove(ref.key);
-            }
+            cleanupPoll();
         }
     }
 
-    protected static void cleanupThread() {
+    protected static void cleanupPoll() {
+        KRef ref;
+        while ( null != (ref = (KRef)QUEUE.poll()) ) {
+            ref.src.iremove(ref.key);
+        }
+    }
+
+    protected static void cleanupRemove() {
         try {
             while (true) {
                 KRef ref = (KRef) QUEUE.remove();
@@ -107,6 +122,19 @@ public abstract class CacheMap<K,V> implements Cache<K,V> {
         }
     }
 
+    protected static boolean isThreadEnabled() {
+        if( !RuntimeUtils.getProperty("assira.cache.use-thread", "false").equals("true")) {
+            return false;
+        }
+        // check if there is cleaner for Java EE
+        try {
+            ClassUtils.forName("net.ranides.assira.ee.CacheMapCleaner");
+            return false;
+        } catch (ClassNotFoundException cause) {
+            return true;
+        }
+    }
+
     private static final class SimpleCache<K,V> extends CacheMap<K,V> {
 
         private final Map<K,KRef<K,V>> map = new ConcurrentHashMap<>();

+ 2 - 1
pom.xml

@@ -37,7 +37,8 @@
         <module>assira</module>
         <module>assira.all</module>
         <module>assira.archetype</module>
-  </modules>
+        <module>assira.enterprise</module>
+    </modules>
 
     <distributionManagement>
         <repository>