alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Glassfish example source code file (DelegatedTimeoutManager.java)

This example Glassfish source code file (DelegatedTimeoutManager.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Glassfish tags/keywords

delegatedtimeoutinfo, delegatedtimeoutinfo, delegatedtimeoutmanager, delegatedtimeoutmanager, delegatedtimeoutthread, enumeration, enumeration, hashtable, log, logging, throwable, timeout_interval=10000, topcoordinator, util, vector, vector, xid

The Glassfish DelegatedTimeoutManager.java source code

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2010 Oracle and/or its affiliates. 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_1_1.html
 * or packager/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 packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [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.
 */

package com.sun.jts.CosTransactions;

import java.util.*;

import org.omg.CosTransactions.*;
import com.sun.jts.jtsxa.XID;

import com.sun.jts.trace.*;

import java.util.logging.Logger;
import java.util.logging.Level;
import com.sun.logging.LogDomains;
import com.sun.jts.utils.LogFormatter;

/**
 * This class records state for timing out transactions, and runs a thread
 * which performs occasional checks to time out transactions. For each log
 * location, which requires delegated recovery, an instance of this will be
 * created. Done as part of delegated recovery support.
 * th
 *
 * @version 0.01
 *
 *
 * @see
 */

class DelegatedTimeoutManager {
    /**
     * Constants which define the types of timeout possible.
     */
    static final int CANCEL_TIMEOUT   = 0;
    static final int NO_TIMEOUT       = 0;
    static final int ACTIVE_TIMEOUT   = 1;
    static final int IN_DOUBT_TIMEOUT = 2;
    
    /**
     * this attribute indicates whether initialisation has been started.
     */
    private static boolean initialised = false;
    
    private Hashtable     pendingTimeouts = new Hashtable();
    private Hashtable     indoubtTimeouts = new Hashtable();
    private DelegatedTimeoutThread timeoutThread = null;
    private boolean       timeoutActive = false;
    private boolean       quiescing = false;
    private boolean       isSetTimeout = false;
    private String        logPath = null;
    
        /*
                Logger to log transaction messages
         */
    static Logger _logger = LogDomains.getLogger(DelegatedTimeoutManager.class, LogDomains.TRANSACTION_LOGGER);
    /**
     * Initialises the static state of the TimeoutManager class.
     *
     * @param
     *
     * @return
     *
     * @see
     */
    /**
     * synchronized static void initialise() {
     *
     * // If already initialised, return immediately.
     *
     * if (initialised) {
     * return;
     * }
     *
     * initialised = true;
     *
     * // Start the timeout thread.
     *
     * if (!timeoutActive && timeoutThread == null) {
     * //  timeoutThread = new TimeoutThread();
     * //  timeoutThread.start();
     * timeoutActive = true;
     * }
     * }
     **/
    
    DelegatedTimeoutManager() {
    }
    
    DelegatedTimeoutManager(String logPath) {
        this.logPath = logPath;
    }
    
    
    synchronized void initSetTimeout() {
        if (isSetTimeout)
            return;
        isSetTimeout = true;
        timeoutThread = new DelegatedTimeoutThread(this);
        timeoutThread.start();
    }
    
    /**
     * Sets the timeout for the transaction to the specified type and time in
     * seconds.
     * <p>
     * If the type is none, the timeout for the transaction is
     * cancelled, otherwise the current timeout for the transaction is modified
     * to be of the new type and duration.
     *
     * @param localTID     The local identifier for the transaction.
     * @param timeoutType  The type of timeout to establish.
     * @param seconds      The length of the timeout.
     *
     * @return  Indicates success of the operation.
     *
     * @see
     */
    boolean setTimeout(Long localTID, int timeoutType,
    int seconds) {
        
        boolean result = true;
        
        // Modify the timeout to the required type and value.
        
        DelegatedTimeoutInfo timeoutInfo = null;
        
        switch (timeoutType) {
            
            // If the new type is active or in_doubt, then create a
            // new TimeoutInfo if necessary, and set up the type and interval.
            
            case DelegatedTimeoutManager.ACTIVE_TIMEOUT :
                if (!isSetTimeout) {
                    initSetTimeout();
                }
                timeoutInfo = new DelegatedTimeoutInfo();
                timeoutInfo.expireTime  =
                new Date().getTime() + seconds * 1000L;
                timeoutInfo.localTID    = localTID;
                timeoutInfo.timeoutType = timeoutType;
                pendingTimeouts.put(localTID,timeoutInfo);
                break;
            case TimeoutManager.IN_DOUBT_TIMEOUT :
                if (!isSetTimeout) {
                    initSetTimeout();
                    // isSetTimeout = true;
                }
                timeoutInfo = new DelegatedTimeoutInfo();
                timeoutInfo.expireTime  =
                new Date().getTime() + seconds * 1000L;
                timeoutInfo.localTID    = localTID;
                timeoutInfo.timeoutType = timeoutType;
                indoubtTimeouts.put(localTID,timeoutInfo);
                break;
                
                // For any other type, remove the timeout if there is one.
                
            default:
                if (!isSetTimeout)
                    break;
                result = (pendingTimeouts.remove(localTID) != null);
                if (!result)
                    result = (indoubtTimeouts.remove(localTID) != null);
                
                // If the transaction service is quiescing and
                // there are no more pending timeouts,
                // deactivate timeout and stop the timeout thread.
                
                if (quiescing && pendingTimeouts.isEmpty() && indoubtTimeouts.isEmpty()) {
                    timeoutThread.stop();
                    timeoutActive = false;
                    // pendingTimeouts = null;
                }
                break;
        }
        return result;
    }
    
    /**
     * Takes appropriate action for a timeout.
     * <p>
     * The type fo timeout is given, and the transaction represented by the
     * Coordinator and its local identifier.
     * <p>
     * This method does not reference the TimeoutManager's state directly
     * and so does not need to be synchronized.
     *
     * @param localTID     The local identifier for the transaction.
     * @param timeoutType  The type of timeout.
     *
     * @return
     *
     * @see
     */
    void timeoutCoordinator(Long localTID, int  timeoutType) {
        
        // Look up the Coordinator for the transaction.
        // If there is none, then the transaction has already gone.
        // Otherwise do something with the transaction.
        
        
        CoordinatorImpl coord = DelegatedRecoveryManager.getLocalCoordinator(localTID, logPath);
        if (coord == null) {
            if(_logger.isLoggable(Level.FINER)) {
                _logger.logp(Level.FINER,"DelegatedTimeoutManager","timeoutCoordinator()",
                "DelegatedRecoveryManager.getLocalCoordinator() returned null,"+
                "which means txn is done. Setting timeout type to CANCEL_TIMEOUT");
            }
            setTimeout(localTID, TimeoutManager.CANCEL_TIMEOUT, 0);
        } else {
            synchronized (coord) {
                boolean[] isRoot = new boolean[1];
                
                switch (timeoutType) {
                    
                    // If active, then attempt to roll the transaction back.
                    
                    case DelegatedTimeoutManager.ACTIVE_TIMEOUT :
                        if(_logger.isLoggable(Level.FINER)) {
                            _logger.logp(Level.FINER,"DelegatedTimeoutManager","timeoutCoordinator()",
                            "DelegatedTimeoutManager.timeoutCoordinator():case ACTIVE_TIMEOUT"+
                            "DelegatedRecoveryManager.getLocalCoordinator() returned non-null,"+
                            "which means txn is still around. Rolling back the"+
                            "transaction...: GTID is : " +
                            ((TopCoordinator)coord).superInfo.globalTID.toString());
                        }
                        try {
                            // coord.rollback(true);
                            coord.rollback_only();
                        } catch (Throwable exc) {}
                        break;
                        
                        // If in doubt, it must be a TopCoordinator.
                        // In that case replay_completion needs to be driven.
                        // This is done by telling the TopCoordinator to act as
                        // if in recovery.  The result is then used to
                        // determine what to do with the Coordinator.
                        
                    case DelegatedTimeoutManager.IN_DOUBT_TIMEOUT :
                        if(_logger.isLoggable(Level.FINER)) {
                            _logger.logp(Level.FINER,"DelegatedTimeoutManager","timeoutCoordinator()",
                            "DelegatedTimeoutManager.timeoutCoordinator():case IN_DOUBT_TIMEOUT"+
                            "DelegatedRecoveryManager.getLocalCoordinator() returned non-null,"+
                            "which means txn is still around. Invoking recover(boolean)"+
                            "on TopCoordinator...: GTID is: "+
                            ((TopCoordinator)coord).superInfo.globalTID.toString());
                        }
                        Status state = ((TopCoordinator) coord).recover(isRoot);
                        
                        if (state == Status.StatusUnknown) {
                            
                            // If the outcome is not currently known, we do
                            // nothing with the transaction, as we expect to
                            // eventually get an outcome from the parent.
                            
                            // GDH put out warning in case this state
                            // continues for a long time.
                            _logger.log(Level.WARNING, "jts.transaction_resync_from_orginator_failed");
                            
                        } else if (state == Status.StatusCommitted) {
                            
                            // For committed or rolled back, proceed with
                            // completion of the transaction, regardless of whether
                            // it is the root or a subordinate. This will
                            // result in the removal of the in-doubt timeout.
                            
                            try {
                                ((TopCoordinator)coord).commit();
                                if (isRoot[0]) {
                                    ((TopCoordinator) coord).
                                    afterCompletion(state);
                                }
                            } catch (Throwable exc) {}
                        } else {
                            // By default, roll the transaction back.
                            try {
                                ((TopCoordinator) coord).rollback(true);
                                if (isRoot[0]) {
                                    ((TopCoordinator) coord).
                                    afterCompletion(Status.StatusRolledBack);
                                }
                            } catch (Throwable exc) {}
                        }
                        
                        break;
                        
                    default:
                        // Otherwise do nothing.
                        break;
                }
            }
        }
    }
    
    /**
     * Periodically checks the existing timeouts.
     * <p>
     * This is done to discover if any transactions have overrun their allotted
     * time.  Those which have are returned as an Enumeration.
     * <p>
     * Note that this method should not do anything that will cause a
     * synchronized method in the RecoveryManager to be called, as this could
     * cause a deadlock when RecoveryManager methods on other threads call
     * setTimeout.
     *
     * @param
     *
     * @return  The information for transactions which have timed out.
     *
     * @see
     */
    Enumeration checkTimeouts() {
        if (!isSetTimeout)
            return null;
        
        Enumeration result = null;
        
        // When woken up, go through all current timeouts and identify those
        // which have expired.
        
        if (timeoutActive && ((pendingTimeouts.size() != 0) || (indoubtTimeouts.size() != 0))) {
            Vector timedOut = null;
            
            Enumeration timeouts = null;
            
            synchronized (pendingTimeouts) {
                timeouts = pendingTimeouts.elements();
                
                while (timeouts.hasMoreElements()) {
                    
                    DelegatedTimeoutInfo timeoutInfo = (DelegatedTimeoutInfo)timeouts.nextElement();
                    
                    // For each timeout in the list, check whether it has expired.
                    // If so, look up the Coordinator and roll it back.
                    
                    if (new Date().getTime() > timeoutInfo.expireTime) {
                        
                        // Add the TimeoutInfo to the queue of
                        //those that have timed out.
                        
                        if (timedOut == null) {
                            timedOut = new Vector();
                        }
                        
                        timedOut.addElement(timeoutInfo);
                    }
                }
            }
            
            synchronized (indoubtTimeouts) {
                
                timeouts = indoubtTimeouts.elements();
                
                while (timeouts.hasMoreElements()) {
                    
                    DelegatedTimeoutInfo timeoutInfo = (DelegatedTimeoutInfo)timeouts.nextElement();
                    
                    // For each timeout in the list, check whether it has expired.
                    // If so, look up the Coordinator and roll it back.
                    
                    if (new Date().getTime() > timeoutInfo.expireTime) {
                        
                        // Add the TimeoutInfo to the queue of
                        //those that have timed out.
                        
                        if (timedOut == null) {
                            timedOut = new Vector();
                        }
                        
                        timedOut.addElement(timeoutInfo);
                    }
                }
                
            }
            // Enumerate the transactions which have timed out.
            
            if (timedOut != null) {
                result = timedOut.elements();
            }
        }
        
        // The remainder of the timeout processing is not carried out here
        // because we would get deadlocked with addCoordinator or
        // removeCoordinator that also update the timeout list.  Hence the
        // returned enumeration, which may be processed with
        // no concurrency control.
        
        return result;
    }
    
    /**
     * @return a set of in-doubt transaction ids.
     */
    XID[] getInDoubtXids() {
        
        synchronized (indoubtTimeouts) {
            Vector inDoubtList = new Vector();
            
            Enumeration timeouts = indoubtTimeouts.elements();
            
            while (timeouts.hasMoreElements()) {
                
                DelegatedTimeoutInfo timeoutInfo = (DelegatedTimeoutInfo) timeouts.nextElement();
                
                // Look up the Coordinator for the transaction.
                // If there is none, then the transaction has already gone.
                // Otherwise do something with the transaction.
                
                CoordinatorImpl coord =
                DelegatedRecoveryManager.getLocalCoordinator(timeoutInfo.localTID, logPath);
                
                if (coord != null) {
                    XID xid = new XID();
                    xid.copy(coord.getGlobalTID());
                    inDoubtList.addElement(xid);
                }
            }
            
            return (XID[]) inDoubtList.toArray(new XID[] {});
        }
    }
    
    /**
     * Returns the amount of time left before the given transaction times out.
     *
     * @param localTID  The local identifier for the transaction.
     *
     * @return  The time left.  If there is no timeout for the transaction,
     *          this value will be negative.  If the timeout period has been
     *          exceeded, this value will be zero.
     *
     * @see
     */
    long timeLeft(Long localTID) {
        
        DelegatedTimeoutInfo timeoutInfo = (DelegatedTimeoutInfo) pendingTimeouts.get(localTID);
        if (timeoutInfo == null)
            timeoutInfo = (DelegatedTimeoutInfo) indoubtTimeouts.get(localTID);
        long result = -1;
        if (timeoutInfo != null) {
            result = timeoutInfo.expireTime - new Date().getTime();
            if (result < 0) {
                result = 0;
            }
        }
        
        return result;
    }
    
    /**
     * Informs the TimeoutManager that the transaction service
     * is being shut down. For immediate shutdown, the timeout thread is
     * stopped and all timeout information discarded.
     *
     * For quiesce, the timeout thread is stopped when there are no running
     * transactions left.
     *
     * @param immediate  Indicates whether to stop immediately.
     *
     * @return
     *
     * @see
     */
    void shutdown(boolean immediate) {
        
        // For immediate, kill the timeout thread and throw
        // away all information. Also, if there are no pending
        // timeouts, there is nothing to quiesce so
        // shutdown immediately regardless.
        
        if (immediate ||
        pendingTimeouts == null || pendingTimeouts.isEmpty()) {
            if (timeoutThread != null) {
                timeoutThread.stop();
            }
            
            if (pendingTimeouts != null) {
                pendingTimeouts.clear();
            }
            
            pendingTimeouts = null;
            timeoutThread = null;
            timeoutActive = false;
        } else {
            quiescing = true;
        }
    }
    
}

/**
 * This class records information for a timeout for a transaction.
 *
 * @version 0.1
 *
 * @author Simon Holdsworth, IBM Corporation
 *
 * @see
 */

//----------------------------------------------------------------------------
// CHANGE HISTORY
//
// Version By     Change Description
//   0.1   SAJH   Initial implementation.
//----------------------------------------------------------------------------

class DelegatedTimeoutInfo extends Object {
    Long localTID = null;
    long expireTime = 0;
    int  timeoutType = TimeoutManager.NO_TIMEOUT;
}

/**
 * This class represents a thread on which the TimeoutManager can perform
 * timeout checking.
 *
 * @version 0.01
 *
 *
 * @see
 */


class DelegatedTimeoutThread extends Thread {
    
    private int TIMEOUT_INTERVAL ;
    private DelegatedTimeoutManager tmoutMgr = null;
    
    static Logger _logger = LogDomains.getLogger(DelegatedTimeoutThread.class, LogDomains.TRANSACTION_LOGGER);
    /**
     * TimeoutThread constructor.
     * <p>
     * This sets the thread name, and sets the thread to be a daemon thread so
     * that it does not prevent the process from terminating.
     *
     * @param
     *
     * @return
     *
     * @see
     */
    DelegatedTimeoutThread(DelegatedTimeoutManager timeoutMgr) {
        setName("Delegated JTS Timeout Thread"/*#Frozen*/);
        setDaemon(true);
        tmoutMgr = timeoutMgr;
        try{
            String timeout_interval = Configuration.getPropertyValue(Configuration.TIMEOUT_INTERVAL);
            if(timeout_interval!=null){
                TIMEOUT_INTERVAL= Integer.parseInt(timeout_interval);
                TIMEOUT_INTERVAL*=1000;
                if(TIMEOUT_INTERVAL<10000)
                    TIMEOUT_INTERVAL=10000;
            }
            else{
                TIMEOUT_INTERVAL=10000;
            }
        }catch(Exception e){
            TIMEOUT_INTERVAL=10000;
        }
    }
    
    /**
     * Performs timeout checking on a regular basis (every ten seconds or so).
     *
     * @param
     *
     * @return
     *
     * @see
     */
    public void run() {
        try {
            while (true) {
                
                // Sleep for a while between checks.
                
                Thread.sleep(TIMEOUT_INTERVAL);
                
                // Perform timeout checks, getting a list of timed-out
                // transactions.
                
                Enumeration timedOut = tmoutMgr.checkTimeouts();
                
                // Now we must go through the list, telling each
                // timed-out Coordinator to do something appropriate.
                
                if (timedOut != null) {
                    while (timedOut.hasMoreElements()) {
                        DelegatedTimeoutInfo timeoutInfo =
                        (DelegatedTimeoutInfo) timedOut.nextElement();
                        
                        // Look up the Coordinator and tell it to roll back
                        // if it still exists. Note that we rely on the
                        // Coordinator calling removeCoordinator when it
                        // has finished, which will remove the timeout from
                        // the list, and remove other associations as well.
                        
                        tmoutMgr.
                        timeoutCoordinator(timeoutInfo.localTID,
                        timeoutInfo.timeoutType);
                    }
                }
            }
        } catch (InterruptedException exc) {
            _logger.log(Level.INFO,"jts.time_out_thread_stopped");
        }
    }
}

Other Glassfish examples (source code examples)

Here is a short list of links related to this Glassfish DelegatedTimeoutManager.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.