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

com.sun.grizzly.http.jk.common.Shm Maven / Gradle / Ivy

There is a newer version: 1.9.65
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 1997-2008 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.
 *
 *
 * This file incorporates work covered by the following copyright and
 * permission notice:
 *
 * Copyright 2004 The Apache Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.sun.grizzly.http.jk.common;

import java.io.IOException;
import java.util.Vector;

import com.sun.grizzly.http.jk.apr.AprImpl;
import com.sun.grizzly.http.jk.core.Msg;
import com.sun.grizzly.http.jk.core.MsgContext;
import com.sun.grizzly.http.jk.core.WorkerEnv;
import com.sun.grizzly.util.IntrospectionUtils;
import com.sun.grizzly.util.LoggerUtils;
import com.sun.grizzly.util.buf.C2BConverter;

/* The code is a bit confusing at this moment - the class is used as
a Bean, or ant Task, or CLI - i.e. you set properties and call execute.
That's different from the rest of jk handlers wich are stateless ( but
similar with Coyote-http ).
 */
import java.util.logging.Level;
/** Handle the shared memory objects.
 *
 * @author Costin Manolache
 */
public class Shm extends JniHandler {

    String file = "/tmp/shm.file";
    int size;
    String host = "localhost";
    int port = 8009;
    String unixSocket;
    boolean help = false;
    boolean unregister = false;
    boolean reset = false;
    String dumpFile = null;
    Vector groups = new Vector();
    // Will be dynamic ( getMethodId() ) after things are stable 
    static final int SHM_WRITE_SLOT = 2;
    static final int SHM_RESET = 5;
    static final int SHM_DUMP = 6;

    public Shm() {
    }

    /** Scoreboard location
     */
    public void setFile(String f) {
        file = f;
    }

    /** Copy the scoreboard in a file for debugging
     *  Will also log a lot of information about what's in the scoreboard.
     */
    public void setDump(String dumpFile) {
        this.dumpFile = dumpFile;
    }

    /** Size. Used only if the scoreboard is to be created.
     */
    public void setSize(int size) {
        this.size = size;
    }

    /** Set this to get the scoreboard reset.
     *  The shm segment will be destroyed and a new one created,
     *  with the provided size.
     *
     *  Requires "file" and "size".
     */
    public void setReset(boolean b) {
        reset = true;
    }

    /** Ajp13 host
     */
    public void setHost(String host) {
        this.host = host;
    }

    /** Mark this instance as belonging to a group
     */
    public void setGroup(String grp) {
        groups.addElement(grp);
    }

    /** Ajp13 port
     */
    public void setPort(int port) {
        this.port = port;
    }

    /** Unix socket where tomcat is listening.
     *  Use it only if tomcat is on the same host, of course
     */
    public void setUnixSocket(String unixSocket) {
        this.unixSocket = unixSocket;
    }

    /** Set this option to mark the tomcat instance as
    'down', so apache will no longer forward messages to it.
    Note that requests with a session will still try this
    host first.
    This can be used to implement gracefull shutdown.
    Host and port are still required, since they are used
    to identify tomcat.
     */
    public void setUnregister(boolean unregister) {
        this.unregister = true;
    }

    public void init() throws IOException {
        super.initNative("shm");
        if (apr == null) {
            return;
        }
        if (file == null) {
            LoggerUtils.getLogger().log(Level.SEVERE, "No shm file, disabling shared memory");
            apr = null;
            return;
        }

        // Set properties and call init.
        setNativeAttribute("file", file);
        if (size > 0) {
            setNativeAttribute("size", Integer.toString(size));
        }

        initJkComponent();
    }

    public void resetScoreboard() throws IOException {
        if (apr == null) {
            return;
        }
        MsgContext mCtx = createMsgContext();
        Msg msg = (Msg) mCtx.getMsg(0);
        msg.reset();

        msg.appendByte(SHM_RESET);

        this.invoke(msg, mCtx);
    }

    public void dumpScoreboard(String fname) throws IOException {
        if (apr == null) {
            return;
        }
        MsgContext mCtx = createMsgContext();
        Msg msg = (Msg) mCtx.getMsg(0);
        C2BConverter c2b = mCtx.getConverter();
        msg.reset();

        msg.appendByte(SHM_DUMP);

        appendString(msg, fname, c2b);

        this.invoke(msg, mCtx);
    }

    /** Register a tomcat instance
     *  XXX make it more flexible
     */
    public void registerTomcat(String host, int port, String unixDomain)
            throws IOException {
        String instanceId = host + ":" + port;

        String slotName = "TOMCAT:" + instanceId;
        MsgContext mCtx = createMsgContext();
        Msg msg = (Msg) mCtx.getMsg(0);
        msg.reset();
        C2BConverter c2b = mCtx.getConverter();

        msg.appendByte(SHM_WRITE_SLOT);
        appendString(msg, slotName, c2b);

        int channelCnt = 1;
        if (unixDomain != null) {
            channelCnt++;
        }

        // number of groups. 0 means the default lb.
        msg.appendInt(groups.size());
        for (int i = 0; i < groups.size(); i++) {
            appendString(msg, (String) groups.elementAt(i), c2b);
            appendString(msg, instanceId, c2b);
        }

        // number of channels for this instance
        msg.appendInt(channelCnt);

        // The body:
        appendString(msg, "channel.socket:" + host + ":" + port, c2b);
        msg.appendInt(1);
        appendString(msg, "tomcatId", c2b);
        appendString(msg, instanceId, c2b);

        if (unixDomain != null) {
            appendString(msg, "channel.apr:" + unixDomain, c2b);
            msg.appendInt(1);
            appendString(msg, "tomcatId", c2b);
            appendString(msg, instanceId, c2b);
        }

        if (LoggerUtils.getLogger().isLoggable(Level.FINEST)) {
            LoggerUtils.getLogger().log(Level.FINEST, "Register " + instanceId);
        }
        this.invoke(msg, mCtx);
    }

    public void unRegisterTomcat(String host, int port)
            throws IOException {
        String slotName = "TOMCAT:" + host + ":" + port;
        MsgContext mCtx = createMsgContext();
        Msg msg = (Msg) mCtx.getMsg(0);
        msg.reset();
        C2BConverter c2b = mCtx.getConverter();

        msg.appendByte(SHM_WRITE_SLOT);
        appendString(msg, slotName, c2b);

        // number of channels for this instance
        msg.appendInt(0);
        msg.appendInt(0);

        if (LoggerUtils.getLogger().isLoggable(Level.FINEST)) {
            LoggerUtils.getLogger().log(Level.FINEST, "UnRegister " + slotName);
        }
        this.invoke(msg, mCtx);
    }

    public void destroy() throws IOException {
        destroyJkComponent();
    }

    public int invoke(Msg msg, MsgContext ep)
            throws IOException {
        if (apr == null) {
            return 0;
        }
        LoggerUtils.getLogger().log(Level.FINEST, "ChannelShm.invoke: " + ep);
        super.nativeDispatch(msg, ep, JK_HANDLE_SHM_DISPATCH, 0);
        return 0;
    }
    //-------------------- Main - use the shm functions from ant or CLI ------
    /** Local initialization - for standalone use
     */
    public void initCli() throws IOException {
        WorkerEnv wEnv = new WorkerEnv();
        AprImpl apr = new AprImpl();
        wEnv.addHandler("apr", apr);
        wEnv.addHandler("shm", this);
        apr.init();
        if (!apr.isLoaded()) {
            LoggerUtils.getLogger().log(Level.SEVERE, "No native support. " +
                    "Make sure libapr.so and libjkjni.so are available in LD_LIBRARY_PATH");
            return;
        }
    }

    public void execute() {
        try {
            if (help) {
                return;
            }
            initCli();
            init();

            if (reset) {
                resetScoreboard();
            } else if (dumpFile != null) {
                dumpScoreboard(dumpFile);
            } else if (unregister) {
                unRegisterTomcat(host, port);
            } else {
                registerTomcat(host, port, unixSocket);
            }
        } catch (Exception ex) {
            LoggerUtils.getLogger().log(Level.SEVERE, "Error executing Shm", ex);
        }
    }

    public void setHelp(boolean b) {
        if (LoggerUtils.getLogger().isLoggable(Level.FINEST)) {
            LoggerUtils.getLogger().log(Level.FINEST, "Usage: ");
            LoggerUtils.getLogger().log(Level.FINEST, "  Shm [OPTIONS]");
            LoggerUtils.getLogger().log(Level.FINEST, "");
            LoggerUtils.getLogger().log(Level.FINEST, "  -file SHM_FILE");
            LoggerUtils.getLogger().log(Level.FINEST, "  -group GROUP ( can be specified multiple times )");
            LoggerUtils.getLogger().log(Level.FINEST, "  -host HOST");
            LoggerUtils.getLogger().log(Level.FINEST, "  -port PORT");
            LoggerUtils.getLogger().log(Level.FINEST, "  -unixSocket UNIX_FILE");
        //        LoggerUtils.getLogger().log(Level.FINEST,"  -priority XXX");
        //        LoggerUtils.getLogger().log(Level.FINEST,"  -lbFactor XXX");
        }
        help = true;
        return;
    }

    public static void main(String args[]) {
        try {
            Shm shm = new Shm();

            if (args.length == 0 ||
                    ("-?".equals(args[0]))) {
                shm.setHelp(true);
                return;
            }

            IntrospectionUtils.processArgs(shm, args);
            shm.execute();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy