Index: presence/presence-impl/impl/.classpath =================================================================== --- presence/presence-impl/impl/.classpath (revision 55474) +++ presence/presence-impl/impl/.classpath (working copy) @@ -5,7 +5,8 @@ - + + - + \ No newline at end of file Index: presence/presence-impl/impl/.project =================================================================== --- presence/presence-impl/impl/.project (revision 55474) +++ presence/presence-impl/impl/.project (working copy) @@ -3,7 +3,6 @@ sakai-presence-api - sakai-privacy-api Index: presence/presence-impl/impl/src/java/org/sakaiproject/presence/impl/BasePresenceService.java =================================================================== --- presence/presence-impl/impl/src/java/org/sakaiproject/presence/impl/BasePresenceService.java (revision 55474) +++ presence/presence-impl/impl/src/java/org/sakaiproject/presence/impl/BasePresenceService.java (working copy) @@ -26,12 +26,14 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.Vector; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.sakaiproject.api.privacy.PrivacyManager; +import org.sakaiproject.component.cover.ComponentManager; import org.sakaiproject.entity.api.Entity; import org.sakaiproject.event.api.Event; import org.sakaiproject.event.api.EventTrackingService; @@ -73,6 +75,10 @@ */ protected abstract Storage newStorage(); + /** The maintenance. */ + protected Maintenance m_maintenance = null; + + /********************************************************************************************************************************************************************************************************************************************************** * Constructors, Dependencies and their setter methods *********************************************************************************************************************************************************************************************************************************************************/ @@ -184,6 +190,10 @@ // storage m_storage = newStorage(); + // start the maintenance thread + m_maintenance = new Maintenance(); + m_maintenance.start(); + M_log.info("init()"); // register a transient notification for resources @@ -510,6 +520,37 @@ } } + /** + * Check all session presences and remove any expired ones + */ + protected void checkAllPresenceForExpiration() + { + Map sessions = m_sessionManager.getSessions(); + + for (Iterator i = sessions.values().iterator(); i.hasNext();) + { + Session session = (Session) i.next(); + ToolSession ts = session.getToolSession(SESSION_KEY); + Enumeration locations = ts.getAttributeNames(); + while (locations.hasMoreElements()) + { + String location = (String) locations.nextElement(); + + Presence p = (Presence) ts.getAttribute(location); + + if (M_log.isDebugEnabled()) M_log.debug("checking expiry of session " + session.getId() + " in location " + location); + + if (p != null && p.isExpired()) + { + ts.removeAttribute(location); + } + } + + } + + } + + /********************************************************************************************************************************************************************************************************************************************************** * Storage *********************************************************************************************************************************************************************************************************************************************************/ @@ -649,4 +690,110 @@ { this.notificationService = notificationService; } + + // Maintenance thread + + protected class Maintenance implements Runnable + { + /** My thread running my timeout checker. */ + protected Thread m_maintenanceChecker = null; + + /** Configuration: how often to check for expired presence */ + protected long m_refresh = 10; + + /** Signal to the timeout checker to stop. */ + protected boolean m_maintenanceCheckerStop = false; + + /** + * Construct. + */ + public Maintenance() + { + } + + /** + * Start the maintenance thread, registering this app server in the cluster table. + */ + public void start() + { + if (m_maintenanceChecker != null) return; + + // register in the cluster table + + m_maintenanceChecker = new Thread(this, "SakaiPresenceService.Maintenance"); + m_maintenanceChecker.setDaemon(true); + m_maintenanceCheckerStop = false; + m_maintenanceChecker.start(); + } + + /** + * Stop the maintenance thread + */ + public void stop() + { + if (m_maintenanceChecker != null) + { + m_maintenanceCheckerStop = true; + m_maintenanceChecker.interrupt(); + try + { + // wait for it to die + m_maintenanceChecker.join(); + } + catch (InterruptedException ignore) + { + } + m_maintenanceChecker = null; + } + + // Nothing to do + + } + + /** + * Run the maintenance thread. Every REFRESH seconds, check for expired presence + */ + public void run() + { + // wait till things are rolling + ComponentManager.waitTillConfigured(); + + if (M_log.isDebugEnabled()) M_log.debug("run()"); + + while (!m_maintenanceCheckerStop) + { + try + { + + if (M_log.isDebugEnabled()) M_log.debug("checking for expired presence..."); + checkAllPresenceForExpiration(); + + } + catch (Throwable e) + { + M_log.warn("exception checking for expired presence: ", e); + } + finally + { + // clear out any current access bindings + // m_threadLocalManager.clear(); + } + + // cycle every REFRESH seconds + if (!m_maintenanceCheckerStop) + { + try + { + Thread.sleep(m_refresh * 1000L); + } + catch (Exception ignore) + { + } + } + } + + if (M_log.isDebugEnabled()) M_log.debug("done"); + } + } + } Index: presence/presence-impl/impl/pom.xml =================================================================== --- presence/presence-impl/impl/pom.xml (revision 55474) +++ presence/presence-impl/impl/pom.xml (working copy) @@ -24,6 +24,10 @@ org.sakaiproject.kernel sakai-kernel-api + + org.sakaiproject.kernel + sakai-component-manager + org.sakaiproject sakai-presence-api @@ -32,11 +36,6 @@ org.sakaiproject sakai-privacy-api - - - - - commons-logging commons-logging