Package com.sun.enterprise.ee.web.sessmgmt

Source Code of com.sun.enterprise.ee.web.sessmgmt.ReplicationResponseRepository

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.  If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
/*
* ReplicationResponseRepository.java
*
* Created on January 4, 2006, 12:42 PM
*
*/

package com.sun.enterprise.ee.web.sessmgmt;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import com.sun.logging.LogDomains;
import java.util.logging.Logger;
import java.util.logging.Level;

/**
*
* @author Larry White
*/
public class ReplicationResponseRepository implements Runnable {
    private static final Logger _logger = LogDomains.getLogger(LogDomains.WEB_LOGGER);
    private static final Logger _salogger = ReplicationUtil.getSALogger();
   
   
    /**
     * The sleep interval in seconds
     */   
    private static int _sleepIntervalSeconds = 10;
   
    /**
     * The singleton instance of ReplicationResponseRepository
     */   
    private static ReplicationResponseRepository _soleInstance
        = new ReplicationResponseRepository();   
   
    /** Creates a new instance of ReplicationResponseRepository */
    public ReplicationResponseRepository() {
        _repository = new ConcurrentHashMap();
        _queueForQueues = new ConcurrentLinkedQueue();
        _federatedQueryRepository = new ConcurrentHashMap();
    }  

    /**
     *  the map of ReplicationState responses to queries
     *  key is id, value is associated ReplicationState
     */   
    private ConcurrentHashMap getRepository() {
        return _repository;
    }
   
    public static LinkedBlockingQueue putEmptyQueueEntry(ReplicationState state) {
        return putEmptyQueueEntry(state, null);
    }   
   
    public static LinkedBlockingQueue putEmptyQueueEntry(ReplicationState state, String command) {
        String id = (String)state.getId();
        //prepend command to id if it exists
        if(command != null) {
            id = command + ":" + id;
        }
        ReplicationResponseRepository repos = getInstance();
  ReplicationResponseRepositoryEntry entry;
  synchronized(repos._repository) {
      entry = (ReplicationResponseRepositoryEntry) repos._repository.get(id);
      if (entry == null) {
          LinkedBlockingQueue aQueue =
                repos.getQueue();
    entry = new ReplicationResponseRepositoryEntry(aQueue);
    repos._repository.put(id, entry);
      }
      entry.addRequest();
  }
        return entry.getQueue();
    }
   
    public static FederatedQueryProcessor putWrappedEmptyQueueEntry(ReplicationState state, FederatedQueryProcessor aWrapper) {
        LinkedBlockingQueue aQueue = putEmptyQueueEntry(state);
        //FederatedRequestProcessor aWrapper = new FederatedRequestProcessor(1, 500);
        ReplicationResponseRepository repos = getInstance();
        repos.getFederatedQueryWrapperMap().put(state.getId(), aWrapper);
        return aWrapper;
    }
   
    public static FederatedQueryProcessor removeWrappedEmptyQueueEntry(ReplicationState state, FederatedQueryProcessor aWrapper) {
        ReplicationResponseRepository repos = getInstance();
        repos.getFederatedQueryWrapperMap().remove(state.getId());
        return aWrapper;
    }   
   
    public static void returnQueueEntry(String id, LinkedBlockingQueue aQueue) {
        ReplicationResponseRepository repos = getInstance();
        ConcurrentHashMap reposMap = repos.getMap();
        reposMap.remove(id);
        //put queue back in _queueForQueues
        if(aQueue != null) {
            aQueue.clear();
            repos.getQueueForQueues().offer(aQueue);
        }
    }

    public static void putEntry(ReplicationState state, String command) {
        if(command != null) {
            putEntry(command + ":" + state.getId(), state);
        } else {
            putEntry(state);
        }
    }

    public static void putEntry(String key, ReplicationState state) {
        ReplicationResponseRepository repos = getInstance();
        ConcurrentHashMap reposMap = repos.getMap();
        ReplicationResponseRepositoryEntry entry
            = (ReplicationResponseRepositoryEntry) reposMap.get(key);
        if(entry == null) {
            return;
        }
        LinkedBlockingQueue aQueue = entry.getQueue();
        if(aQueue == null) {
            return;
        }
        aQueue.add(state);
    }
   
    public static void putEntry(ReplicationState state) {
        putEntry((String)state.getId(), state);
    }
   
    public static void putFederatedEntry(ReplicationState state) {
        ReplicationResponseRepository repos = getInstance();
        ConcurrentHashMap wrapperMap = repos.getFederatedQueryWrapperMap();
        FederatedQueryProcessor aWrapper = (FederatedQueryProcessor) wrapperMap.get(state.getId());
        //FIXME for testing and might leave in for safety
        if(aWrapper == null) {
            if (_salogger.isLoggable(Level.FINER)) {
                _salogger.finer("received late findsession response for appId=" + state.getAppId() + " id=" + state.getId() + "[vers:" + state.getVersion() + "]" +
                        " cmd=" + state.getCommand() + " from instance " + state.getInstanceName() + " isNack=" + state.isNack());
            }
            return;
        }
        aWrapper.processQueryResponse(state);
    }
   
    public static ReplicationState getEntry(String id) {
        return getEntry(id, 1000L);
    }
   
    public static ReplicationState getEntry(String id, long waitTime) {      
        ReplicationState result = null;
        ReplicationResponseRepository repos = getInstance();
        ConcurrentHashMap reposMap = repos.getMap();
        ReplicationResponseRepositoryEntry entry
            = (ReplicationResponseRepositoryEntry) reposMap.get(id);
        if(entry == null) {
            return result;
        }
        LinkedBlockingQueue aQueue = entry.getQueue();
        //block and wait for result until timeout
        try {
            result = (ReplicationState)aQueue.poll(waitTime, TimeUnit.MILLISECONDS);
        } catch (InterruptedException ex) {
            // FIXME evaluate logging level
            if (_logger.isLoggable(Level.FINE)){
                _logger.log(Level.FINE, "ReplicationResponseRepository>>getEntry timed out", ex);
            }
        } finally {
            //clear entry from map
          if (entry.removeRequest()) {
                reposMap.remove(id);
                if(aQueue != null) {
                    aQueue.clear();
                    repos.getQueueForQueues().offer(aQueue);
                }
          }
        }
        return result;
    }
   
    public static ReplicationState getEntry(String id, String command, long waitTime) {
        if(command != null) {
            return getEntry(command + ":" + id, waitTime);
        } else {
            return getEntry(id, waitTime);
        }
    }    
   
    private LinkedBlockingQueue getQueue() {
        LinkedBlockingQueue result = null;      
        result = (LinkedBlockingQueue)_queueForQueues.poll();
        if (result == null) {
            //if none in _queueForQueues, create new queue
            result = getNewQueue();
        }
        return result;
    }
   
    private LinkedBlockingQueue getNewQueue() {
        return new LinkedBlockingQueue();
    }   
   
    private ConcurrentHashMap getMap() {
        return _repository;
    }
   
    private ConcurrentHashMap getFederatedQueryWrapperMap() {
        return _federatedQueryRepository;
    }   
   
    private ConcurrentLinkedQueue getQueueForQueues() {
        return _queueForQueues;
    }   
   
    /** 
     *  Return the singleton instance of ReplicationResponseRepository
     */
    public static ReplicationResponseRepository getInstance() {
        return _soleInstance;
    }
   
    /**
     * The background thread that cleans up
     * unused ReplicationResponseRepositoryEntries
     */
    public void run() {
        // Loop until the termination semaphore is set
        while (!threadDone) {
            threadSleep();
            doCleanup();
        }
    }
   
    /**
     * find and remove stale ReplicationResponseRepositoryEntries
     */
    protected void doCleanup() {
        ArrayList idsToRemove = new ArrayList(100);
        ConcurrentHashMap myMap = this.getRepository();
        Set entries = myMap.entrySet();
        //if (_logger.isLoggable(Level.FINEST)) {
        //    _logger.finest("doCleanup:entries count = " + entries.size());
        //}
        Iterator it = entries.iterator();
        while(it.hasNext()) {
            Map.Entry nextEntry = (Map.Entry)it.next();
            Object nextValue = (Object) nextEntry.getValue();
            if(nextValue instanceof ReplicationResponseRepositoryEntry) {
                ReplicationResponseRepositoryEntry nextReposEntry
                    = (ReplicationResponseRepositoryEntry)nextValue;
                if(nextReposEntry.mayBeRemoved()) {
                    //if (_logger.isLoggable(Level.FINEST)) {
                    //    _logger.finest("next id to remove is: " + nextEntry.getKey());
                    //}
                    nextReposEntry.cleanAndReturn(getQueueForQueues());
                    idsToRemove.add(nextEntry.getKey());
                }
            }
        }
        //if (_logger.isLoggable(Level.FINEST)) {
        //    _logger.finest("removing " + idsToRemove.size() + " ReplicationResponseRepositoryEntries");
        //}
        for(int i=0; i<idsToRemove.size(); i++) {
            myMap.remove((String)idsToRemove.get(i));
        }
       
    }
   
    /**
     * Sleep for the duration specified by the <code>_sleepIntervalSeconds</code>
     * property.
     */
    protected void threadSleep() {
        try {
            Thread.sleep(_sleepIntervalSeconds * 1000L);           
        } catch (InterruptedException e) {
            ;
        }
    }
   
    /**
     * Prepare for the beginning of active use of the public methods of this
     * component.  This method should be called after <code>configure()</code>,
     * and before any of the public methods of the component are utilized.
     *
     */
    public void start() {
        if(started) {
            return;
        }       
        // Start the background cleanup thread
        threadStart();
        started = true;
    }
   
    /**
     * Gracefully terminate the active use of the public methods of this
     * component.  This method should be the last one called on a given
     * instance of this component.
     */
    public void stop() {
        if(!started) {
            return;
        }      
        threadStop();
        started = false;
    }       
   
    /**
     * Start the background thread that will periodically check
     * the health of replication.
     */
    protected void threadStart() {
        if (thread != null)
            return;

        threadDone = false;
        thread = new Thread(this, getThreadName());
        thread.setDaemon(true);
        thread.start();
    }
   
    /**
     * Stop the background thread that is periodically doing cleanup
     */
    protected void threadStop() {
        if (thread == null)
            return;

        threadDone = true;
        thread.interrupt();
        try {
            thread.join();
        } catch (InterruptedException e) {
            ;
        }

        thread = null;
    }    
   
    /**
     * Return the thread name for this Store.
     */
    public String getThreadName() {
        return(_threadName);
    }    
   
    /**
     * The background thread.
     */
    protected Thread thread = null;
   
    /**
     * The background thread completion semaphore.
     */
    protected volatile boolean threadDone = false;    
   
    /**
     * Name to register for the background thread.
     */
    protected String _threadName = "ReplicationResponseRepository";
   
    /**
     * Has this component been started yet?
     */
    protected boolean started = false;    
   
    private ConcurrentHashMap _repository = null;
    private ConcurrentLinkedQueue _queueForQueues = null;
    private ConcurrentHashMap _federatedQueryRepository = null;
   
}
TOP

Related Classes of com.sun.enterprise.ee.web.sessmgmt.ReplicationResponseRepository

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.