Package fr.dyade.aaa.jndi2.ha

Source Code of fr.dyade.aaa.jndi2.ha.HARequestManager

/*
* JORAM: Java(TM) Open Reliable Asynchronous Messaging
* Copyright (C) 2001 - 2008 ScalAgent Distributed Technologies
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
* USA.
*
* Initial developer(s): David Feliot
*/
package fr.dyade.aaa.jndi2.ha;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Hashtable;

import org.objectweb.util.monolog.api.BasicLevel;

import fr.dyade.aaa.agent.AgentServer;
import fr.dyade.aaa.agent.BagSerializer;
import fr.dyade.aaa.jndi2.msg.JndiReply;
import fr.dyade.aaa.jndi2.server.LifeCycleListener;
import fr.dyade.aaa.jndi2.server.RequestManager;
import fr.dyade.aaa.jndi2.server.TcpRequestNot;
import fr.dyade.aaa.jndi2.server.Trace;

public class HARequestManager
    implements LifeCycleListener, BagSerializer, java.io.Serializable {

  /**
   *
   */
  private static final long serialVersionUID = 1L;
  public static final int IDEMPOTENT = -2;
  public static final int NOT_IDEMPOTENT = -1;

  public static final String HA_REQUEST_COUNTER = "haRequestCounter";

  private transient int requestCounter;

  private transient Hashtable requests;

  private RequestManager manager;

  public void setRequestManager(RequestManager manager) {
    this.manager = manager;
  }

  public void agentInitialize(boolean firstTime) throws Exception {
    if (Trace.logger.isLoggable(BasicLevel.DEBUG))
      Trace.logger.log(BasicLevel.DEBUG,
                       "HARequestManager.agentInitialize(" + firstTime + ')');
    Integer counter = (Integer)AgentServer.getTransaction().load(
      HA_REQUEST_COUNTER);
    if (counter == null) {
      requestCounter = 0;
    } else {
      requestCounter = counter.intValue();
    }
    requests = new Hashtable();
    manager.agentInitialize(firstTime);
  }

  public void agentFinalize(boolean lastTime) {
    manager.agentFinalize(lastTime);
  }

  void doReact(GetRequestIdNot not) {
    if (Trace.logger.isLoggable(BasicLevel.DEBUG))
      Trace.logger.log(BasicLevel.DEBUG,
                       "HARequestManager.doReact((GetRequestIdNot)" +
                       not + ')');
    int id = requestCounter;
    requestCounter++;
    saveRequestCounter();

    // Notice that the counter is actually saved
    // at the end of the reaction. If a failure occurs
    // before the end of the reaction, the id may have been
    // delivered whereas the counter is not saved. So after
    // a recovery, the same identifier may be given again.
    // But a HA server cannot be recovered (it is transient).
    // If it is recoverable then the counter storage must
    // be synchronous.
    not.Return(id);
  }

  void doReact(TcpRequestNot not) throws Exception {
    if (Trace.logger.isLoggable(BasicLevel.DEBUG))
      Trace.logger.log(BasicLevel.DEBUG,
                       "HARequestManager.doReact((TcpRequestNot)" +
                       not + ')');
    HARequestContext reqCtx =
      (HARequestContext)not.getRequestContext();
    if (Trace.logger.isLoggable(BasicLevel.DEBUG))
      Trace.logger.log(BasicLevel.DEBUG,
                       " -> request id = " + reqCtx.getId());
    if (reqCtx.getId() == IDEMPOTENT) {
      JndiReply reply = manager.invoke(reqCtx);
      reqCtx.reply(reply);
    } else {
      Integer reqId = new Integer(reqCtx.getId());
      HARequestContext recoveredReqCtx =
        (HARequestContext)requests.get(reqId);
      if (recoveredReqCtx == null) {       
        requests.put(new Integer(requestCounter), reqCtx);
        JndiReply reply = manager.invoke(reqCtx);
        reqCtx.reply(reply);
      } else {
        JndiReply reply = recoveredReqCtx.getReply();
        if (reply == null) {
          recoveredReqCtx.recover(
            reqCtx);
        } else {
          reqCtx.reply(reply);
        }
      }
    }
  }

  void removeContext(int id) {
    requests.remove(new Integer(id));
  }

  private void saveRequestCounter() {
    try {
      AgentServer.getTransaction().save(
        new Integer(requestCounter), HA_REQUEST_COUNTER);
    } catch (IOException exc) {
      throw new Error(exc.toString());
    }
  }

  public void writeBag(ObjectOutputStream out)
    throws IOException {
    out.writeInt(requestCounter);
    out.writeObject(requests);
    manager.writeBag(out);
  }

  public void readBag(ObjectInputStream in)
    throws IOException, ClassNotFoundException {
    requestCounter = in.readInt();
    requests = (Hashtable)in.readObject();
    manager.readBag(in);
  }
}
TOP

Related Classes of fr.dyade.aaa.jndi2.ha.HARequestManager

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.