Added a worker thread to cleanup expired artifacts from the memory artifact mapper.
authorwassa <wassa@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Thu, 24 Mar 2005 04:25:35 +0000 (04:25 +0000)
committerwassa <wassa@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Thu, 24 Mar 2005 04:25:35 +0000 (04:25 +0000)
git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/trunk@1335 ab3bd59b-922f-494d-bb5f-6f0a3c29deca

src/edu/internet2/middleware/shibboleth/artifact/provider/MemoryArtifactMapper.java

index dbea5f3..46a7f3c 100644 (file)
@@ -27,7 +27,11 @@ package edu.internet2.middleware.shibboleth.artifact.provider;
 
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
 
 import org.apache.log4j.Logger;
 import org.opensaml.artifact.Artifact;
@@ -44,20 +48,20 @@ import edu.internet2.middleware.shibboleth.common.ShibbolethConfigurationExcepti
  */
 public class MemoryArtifactMapper extends BaseArtifactMapper implements ArtifactMapper {
 
+       private MemoryArtifactCleaner cleaner = new MemoryArtifactCleaner();
+       private static Logger log = Logger.getLogger(MemoryArtifactMapper.class.getName());
+       private static Map mappings = Collections.synchronizedMap(new HashMap());
+
        public MemoryArtifactMapper() throws ShibbolethConfigurationException {
 
                super();
        }
-       
+
        public MemoryArtifactMapper(Element config) throws ShibbolethConfigurationException {
 
                super(config);
        }
 
-       // TODO need to cleanup stale artifacts
-       private static Logger log = Logger.getLogger(MemoryArtifactMapper.class.getName());
-       private static Map mappings = Collections.synchronizedMap(new HashMap());
-
        public ArtifactMapping recoverAssertion(Artifact artifact) {
 
                ArtifactMapping mapping = (ArtifactMapping) mappings.get(artifact);
@@ -71,4 +75,82 @@ public class MemoryArtifactMapper extends BaseArtifactMapper implements Artifact
                mappings.put(artifact, mapping);
        }
 
+       protected void destroy() {
+
+               synchronized (cleaner) {
+                       if (cleaner != null) {
+                               cleaner.shutdown = true;
+                               cleaner.interrupt();
+                       }
+               }
+       }
+
+       protected void finalize() throws Throwable {
+
+               super.finalize();
+               destroy();
+       }
+
+       private class MemoryArtifactCleaner extends Thread {
+
+               private boolean shutdown = false;
+               private Thread master;
+
+               public MemoryArtifactCleaner() {
+
+                       super("edu.internet2.middleware.shibboleth.idp.provider.MemoryArtifactMapper..MemoryArtifactCleaner");
+                       this.master = Thread.currentThread();
+                       setDaemon(true);
+                       if (getPriority() > Thread.MIN_PRIORITY) {
+                               setPriority(getPriority() - 1);
+                       }
+                       log.debug("Starting memory-based artifact mapper cleanup thread.");
+                       start();
+               }
+
+               public void run() {
+
+                       try {
+                               sleep(60 * 1000); // one minute
+                       } catch (InterruptedException e) {
+                               log.debug("Memory-based artifact mapper cleanup interrupted.");
+                       }
+                       while (true) {
+                               try {
+                                       if (!master.isAlive()) {
+                                               shutdown = true;
+                                               log.debug("Memory-based artifact mapper cleaner is orphaned.");
+                                       }
+                                       if (shutdown) {
+                                               log.debug("Stopping Memory-based artifact mapper cleanup thread.");
+                                               return;
+                                       }
+                                       log.debug("Memory cartifact mapper cleanup thread searching for stale entries.");
+                                       Set needsDeleting = new HashSet();
+                                       synchronized (mappings) {
+                                               Iterator iterator = mappings.entrySet().iterator();
+                                               while (iterator.hasNext()) {
+                                                       Entry entry = (Entry) iterator.next();
+                                                       ArtifactMapping mapping = (ArtifactMapping) entry.getValue();
+                                                       if (mapping.isExpired()) {
+                                                               needsDeleting.add(entry.getKey());
+                                                       }
+                                               }
+                                               // release the lock to be friendly
+                                               Iterator deleteIterator = needsDeleting.iterator();
+                                               while (deleteIterator.hasNext()) {
+                                                       synchronized (mappings) {
+                                                               log.debug("Expiring an Artifact from the memory cache.");
+                                                               mappings.remove(deleteIterator.next());
+                                                       }
+                                               }
+                                       }
+                                       sleep(60 * 1000); // one minute
+                               } catch (InterruptedException e) {
+                                       log.debug("Memory-based artifact mapper cleanup interrupted.");
+                               }
+                       }
+               }
+       }
+
 }
\ No newline at end of file