All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alachisoft.ncache.web.session.RegionalCache Maven / Gradle / Ivy

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.alachisoft.ncache.web.session;

import Alachisoft.NCache.Common.Util.ReaderWriterLock;
import com.alachisoft.ncache.runtime.CacheItemPriority;
import com.alachisoft.ncache.runtime.exceptions.AggregateException;
import com.alachisoft.ncache.runtime.exceptions.ConfigurationException;
import com.alachisoft.ncache.runtime.exceptions.ConnectionException;
import com.alachisoft.ncache.runtime.exceptions.GeneralFailureException;
import com.alachisoft.ncache.runtime.exceptions.OperationFailedException;
import com.alachisoft.ncache.runtime.util.TimeSpan;
import com.alachisoft.ncache.web.CacheSession;
import com.alachisoft.ncache.web.EmptySession;
import com.alachisoft.ncache.web.LockException;
import com.alachisoft.ncache.client.Cache;
import com.alachisoft.ncache.client.CacheItem;
import com.alachisoft.ncache.client.LockHandle;
import com.alachisoft.ncache.client.CacheManager;
import com.alachisoft.ncache.web.config.dom.MultiSiteConfig;
import com.alachisoft.ncache.web.config.dom.PrimaryCache;
import com.alachisoft.ncache.web.config.dom.SecondaryCache;
//import com.alachisoft.jvcache.web.config.dom.SessionStateSettings;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
//import java.util.Hashtable; - sajid
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.log4j.Logger;

/**
 *
 * @author huma_kauser
 */
public class RegionalCache extends NCacheManager {

    protected static MultiSiteConfig _settings;
    protected static Thread _connectionRecycler;
    protected HashMap _caches;
    //protected String _primaryCache;
    protected static String _sid;
//    protected String _currentSessionCache;
    protected String _oldSessionID;
    //--------------------------------------------------------------------------------------------------------

    public RegionalCache(String cacheId, boolean lockRemoteSession, int lockTimeOut, int numberOfRetries, int retryInterval, boolean emptySessions, String configPath, MultiSiteConfig settings) throws Exception {
        super(cacheId, lockRemoteSession, lockTimeOut, numberOfRetries, retryInterval, emptySessions, configPath, settings);
        this._settings = settings;
        if (_settings != null) {
            if (_settings.getRecycleInterval() != -1) {
                _connectionRecycler = new Thread(new Runnable() {
                    public long interval = _settings.getRecycleInterval() * 60 * 1000; // 12 hour interval.

                    @Override
                    public void run() {
                        while (true) {
                            try {
                                Thread.sleep(interval);
                                RecycleCacheConnection();
                            } catch (InterruptedException interruptedException) {
                                RecycleCacheConnection();
                            }
                        }
                    }
                });
            }
        }
        //this.initializeCache(cacheId, configPath);
    }
    //--------------------------------------------------------------------------------------------------------

    public String getPrimaryPrefix() {
        return this._sid;
    }
    //--------------------------------------------------------------------------------------------------------

    public boolean initializeCache(String cacheId, String configPath, MultiSiteConfig settings) throws Exception {
        try {
            super.initializeCache(cacheId, configPath, settings);
            _caches = new HashMap();
            //initializing primary and secondary caches
            _settings = settings;
            if (_settings != null) {
                if (_settings.getPrimaryCache() != null && _settings.getPrimaryCache().length > 0) {
                    for (PrimaryCache cache : _settings.getPrimaryCache()) {
                        if (!_caches.containsKey(cache.getId())) {
                            try {
                                logger.debug("Initializing cache: " + cache.getId());
                                _caches.put(cache.getId(), CacheManager.getCache(cache.getId()));
                                _primaryCache = cache.getId();
                                this._sid = cache.getPrefix();
                            } catch (Exception e) {
                                throw e;
                            }
                            break;
                        }
                    }
                }
                if (_settings.getSecondaryCache() != null && _settings.getSecondaryCache().length > 0) {
                    for (SecondaryCache cache : _settings.getSecondaryCache()) {
                        if (!_caches.containsKey(cache.getId())) {
                            try {
                                _caches.put(cache.getId(), CacheManager.getCache(cache.getId()));
                            } catch (Exception e) {
                                if (logger != null) {
                                    logger.error("RegionalCache.InitializeCache:Failed to initialize secondary cache \"" + cache.toString() + "\". Exception: " + e.toString(), e);
                                }
                            }
                        }
                    }
                }
            }
            return true;
        } catch (Exception ex) {
            if (logger != null) {
                logger.error("Unable to initialize the cache [" + _cacheId + "]. See log for more details.", ex);
            }//return false;
            throw ex;
        }
    }
    //--------------------------------------------------------------------------------------------------------

    public void disconnect() {
        if (_caches == null) {
            logger.debug("No valid cache instance to disconnect with.");
            //--- no need to stop. Cache not initialized
            return;
        }
        try {
            Iterator caches = _caches.entrySet().iterator();
            Map.Entry entry;
            while (caches.hasNext()) {
                entry = (Map.Entry) caches.next();
                Cache cache = entry.getValue() instanceof Cache ? (Cache) entry.getValue() : null;
                if (cache != null) {
                    logger.debug("Disconnecting with cache: " + this._cacheId.toString());
                    cache.close();
                }
                logger.debug("Successfully disconnected with cache: " + this._cacheId);
            }
        } catch (Exception ex) {
            logger.error("Could not disconnect with cache [" + this._cacheId + "]. See log for more details.", ex);
        }
    }
    //--------------------------------------------------------------------------------------------------------

    public CacheSession findSessionById(String sessionId) throws LockException, Exception {
        logger.debug("Trying to find session by id: " + sessionId);
        Object obj = getItem(sessionId);
        if (obj != null && obj instanceof CacheSession) {
            logger.debug("Found valid session object.");
            return (CacheSession) obj;
        }
        if (obj instanceof EmptySession) {
            return (EmptySession) obj;
        }
        //logger.debug("Could not find a valid session object. Returning null.");
        logger.debug("Could not find session [" + sessionId + "] in cache [" + this._cacheId + "]. Returning null."); // - sajid

        return null;
    }
    //--------------------------------------------------------------------------------------------------------

    private void RecycleCacheConnection() {
        _sync.AcquireWriterLock();
        try {
            DisposeSecondaryCaches();
            InitializeSecondaryCaches();
        } finally {
            _sync.ReleaseWriterLock();
        }
    }
//--------------------------------------------------------------------------------------------------------

    /**
     * disposes the secondary cache connections after
     * secondary-connection-recycle-interval.
     */
    private void DisposeSecondaryCaches() {
        if (_caches != null) {
            Iterator ide = _caches.entrySet().iterator();
            Map.Entry entry;
            while (ide.hasNext()) {
                entry = (Map.Entry) ide.next();
                if (!((String) entry.getKey()).toLowerCase().equals(_primaryCache.toLowerCase())) {
                    try {
                        ((Cache) entry.getValue()).close();
                    } catch (Exception e) {
                        if (logger != null) {
                            logger.error("RegionalCache.RecycleSecondaryConnections:Failed to dispose \"" + entry.getKey() + "\". Exception: " + e.toString(), e);
                        }
                    }
                }
            }
        }
    }
//--------------------------------------------------------------------------------------------------------

    /**
     * initializes the secondary cache connections after the
     * secondary-connection-recycle-interval.
     */
    private void InitializeSecondaryCaches() {
        if (_settings.getSecondaryCache() != null && _settings.getSecondaryCache().length > 0) {
            for (SecondaryCache cacheId : _settings.getSecondaryCache()) {
                try {
                    _caches.put(cacheId.getId(), CacheManager.getCache(cacheId.getId()));
                } catch (Exception e) {
                    if (logger != null) {
                        logger.error("RegionalCache.RecycleSecondaryConnections:Failed to initialize \"" + cacheId + "\". Exception: " + e.toString(), e);
                    }
                }
            }
            //setExceptionsEnabled(true);
        }
    }

    //--------------------------------------------------------------------------------------------------------
    private String getCacheID(String sessionId) {
        String sidPrefix = "";
        String cacheId = "";

        if (sessionId != null) {
            sidPrefix = sessionId.substring(0, 4);
        }
        if (_settings.getPrimaryPrefixes().containsKey(sidPrefix)) {
            cacheId = (String) _settings.getPrimaryPrefixes().get(sidPrefix);
        } else if (_settings.getSecondaryPrefixes().containsKey(sidPrefix)) {
            cacheId = (String) _settings.getSecondaryPrefixes().get(sidPrefix);
        }

        return cacheId;
    }
    //--------------------------------------------------------------------------------------------------------

    private Object getItem(String sessionId) throws GeneralFailureException, OperationFailedException, AggregateException, com.alachisoft.ncache.runtime.exceptions.SecurityException, ConfigurationException, ConnectionException, Exception {
        Object obj = null;
        Cache cache = (Cache) ((_caches.get(getCacheID(sessionId)) instanceof Cache) ? _caches.get(getCacheID(sessionId)) : null);

        if (cache != null) {
            obj = getCacheItem(sessionId, cache, 0);
        } else {
            if (_currentSessionCache == null || _currentSessionCache.equals("")) {
                Iterator cacheDic = _caches.entrySet().iterator();
                Map.Entry entry;
                while (cacheDic.hasNext() && obj == null) {
                    entry = (Map.Entry) cacheDic.next();
                    //traverse primary cache
                    if (cache == null) {
                        cache = (Cache) ((_caches.get(_primaryCache) instanceof Cache) ? _caches.get(_primaryCache) : null);
                    } else {
                        cache = (Cache) entry.getValue();
                        // primary cache is already traversed so no need to do it again.
                        if (cache.toString().equals(_primaryCache)) {
                            continue;
                        }
                    }

                    obj = getCacheItem(sessionId, cache, 0);
                }

                if (obj != null) // value was found from one of the caches. so use that cache for all further operations during this HTTP request.
                {
                    _currentSessionCache = cache.toString();
                } else // value wasn't found from any of the caches. thus use primary cache for all further operations.
                {
                    _currentSessionCache = _primaryCache;
                }
            } else {
                cache = (Cache) ((_caches.get(_currentSessionCache) instanceof Cache) ? _caches.get(_currentSessionCache) : null);
                obj = getCacheItem(sessionId, cache, lockTimeOut);
            }
        }
        //mainitaining old session id
        if (obj != null && !cache.toString().equalsIgnoreCase(_primaryCache)) {
            //means obj is not fetched from primary cache
            _oldSessionID = sessionId;
            //_currentSessionCache = cache.toString();
        }
        return obj;
    }

    @Override
    public Cache getCache() {
        Cache cacheHandle = cache;
        //in case of item removal from old primary cache
        if (_oldSessionID != null) {
            cacheHandle = (Cache) ((_caches.get(getCacheID(_oldSessionID)) instanceof Cache) ? _caches.get(getCacheID(_oldSessionID)) : null);
            _oldSessionID = null;
        }
        return cacheHandle;
    }

    @Override
    public boolean isEmptySession() {
        return this._emptySessionWhenLocked;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy