📄 remoteholdercache.java
字号:
/** * Copyright (C) 2003-2004 Funambol * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package sync4j.transport.http.server;import java.util.Iterator;import java.util.ArrayList;import java.util.logging.Logger;import java.util.logging.Level;import javax.servlet.ServletConfig;import sync4j.framework.transport.http.SyncHolder;import sync4j.transport.http.server.Constants;import org.apache.commons.lang.StringUtils;import org.jgroups.JChannelFactory;import org.jgroups.blocks.DistributedHashtable;import org.jgroups.log.Trace;/** * This class implements the remote reference cache. <br> * It holds the DistributedHashtable in its instance parameter cache. * <p> * Another optimization performed in this object is about avoiding memory eating * due to missing SyncHolders removing. This problem is solved with the * following actions: * <ul> * <li> each SyncHolder stores a creation timestamp that is set in the * constructor to the current system time millis; * <li> HolderCache stores in the lastCleaningTimestamp static field the last * time the cache was cleared; * <li> If the the difference between the current time millis and the * lastCleaningTimestamp is greater then the configured sessionTimeToLive, * the cleaner process is executed; * <li> the cleaner process iterates the sync holders in the cache and closes and removes the expired ones; * </ul> * <p> * NOTES: * <p> * 1. The cleaning process is deliberately not synchronized, since * synchronization reduces concurrency and trace conditions do not have bad * effects on the functioning of the system.<br> * 2. The cleaning process could be moved to a separate thread and executed * asynchronously respect to the execution of servlet execution. * * @author Stefano Fornari * @version $Id: RemoteHolderCache.java,v 1.3 2004/04/13 09:32:08 luigia Exp $ */public class RemoteHolderCache implements Constants { // --------------------------------------------------------------- Constants public static final long CLEANING_PERIOD = 300000; // 5 mins private static final Logger log = Logger.getLogger(LOG_NAME); // ------------------------------------------------------------ Private data private long holderTimeToLive = DEFAULT_TTL; private long lastCleaningTimestamp = 0; private String channelProps; private DistributedHashtable cache; // ------------------------------------------------------------ Constructors public RemoteHolderCache(ServletConfig config) { try { String group = config.getInitParameter(PARAM_GROUP); String props = config.getInitParameter(PARAM_CHANNEL_PROPERTIES); if (StringUtils.isEmpty(group)) { group = DEFAULT_GROUP; } // // Consitionally enable tracing (if the logging level includes // Level.FINE, enable it, otherwise not) // if (log.isLoggable(Level.FINE)) { Trace.init(); } if (log.isLoggable(Level.FINE)) { log.fine("Multicast group: " + group); log.fine("Multicast properties: " + props); } JChannelFactory cf = new JChannelFactory(); cache = new DistributedHashtable(group, cf, props, DEFAULT_TIMEOUT); } catch (Exception e) { log.severe(e.getMessage()); log.throwing(getClass().getName(), "configure", e); } lastCleaningTimestamp = System.currentTimeMillis(); holderTimeToLive = Long.parseLong(config.getInitParameter(PARAM_SESSION_TTL)); } // ------------------------------------------- Implementation of HolderCache public void put(SyncHolder holder) { clean(); if (log.isLoggable(Level.FINE)) { log.fine("Caching " + holder.getSessionId() + '(' + holder + ')'); } cache.put(holder.getSessionId(), holder); } public SyncHolder get(String sessionId) { return (SyncHolder)cache.get(sessionId); } public void remove(String sessionId) { if (log.isLoggable(Level.FINE)) { log.fine("Removing holder for " + sessionId); } cache.remove(sessionId); } // ---------------------------------------------------- Other public methods public String toString() { return String.valueOf(cache); } // --------------------------------------------------------- Private methods /** * If System.currentTimeMillis() - lastCleaningTimestamp is greater than * holderTimeToLive, purge old holders. * * @returns true if cleaning was performed, false otherwise */ private boolean clean() { long now = System.currentTimeMillis(); if (log.isLoggable(Level.FINE)) { log.fine("Cleaning procedure..." ); log.fine("now: " + now ); log.fine("CLEANING_PERIOD: " + CLEANING_PERIOD ); log.fine("lastCleaningTimestamp: " + lastCleaningTimestamp); log.fine("holderTimeToLive: " + holderTimeToLive ); } if ((now - lastCleaningTimestamp) <= CLEANING_PERIOD) { log.fine("No purging required"); return false; } log.fine("Performing purging..."); ArrayList toBeRemoved = new ArrayList(); RemoteEJBSyncHolder h; Object key, value; Iterator i = cache.keySet().iterator(); while (i.hasNext()) { key = i.next(); value = cache.get(key); if (!(value instanceof RemoteEJBSyncHolder)) { // You shouldn't be here matey!!! log.fine("Found unexpected object:" + key + " will be removed!"); toBeRemoved.add(key); continue; } h = (RemoteEJBSyncHolder)value; if ((now - h.getCreationTimestamp()) > holderTimeToLive) { log.fine("Purging holder for session " + key); try { h.close(); } catch (Exception e) { log.severe(e.getMessage()); log.throwing(getClass().getName(), "clean", e); } toBeRemoved.add(key); } } // // Now remove the purged objects // i = toBeRemoved.iterator(); while(i.hasNext()) { cache.remove(i.next()); } return true; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -