Package org.jboss.fresh.shell.impl

Source Code of org.jboss.fresh.shell.impl.SystemShellImpl

package org.jboss.fresh.shell.impl;

import org.jboss.beans.metadata.api.annotations.Inject;
import org.jboss.fresh.deployer.RegistryNamingBinder;
import org.jboss.fresh.registry.RegistryContext;
import org.jboss.fresh.shell.*;
import org.jboss.fresh.vfs.UserCtx;
import org.jboss.fresh.vfs.VFS;
import org.jboss.util.threadpool.ThreadPool;

import javax.naming.NamingException;
import java.util.*;

/**
* // This class is a server. It has a set of Shell instances.
* // These instances have to timeout if inactive.
* // Like jboss does with sessions we could persist the inactive ones out of memory.
* // And load them in if accessed after a long time.
* // We can also time them out ... we could specify a pretty high timeout ...
* // When they timeout we kill the processes and remove the Shell objects.
* // Since we need to be able to do an id based lookup, we will contain them in HashMap
*/

//@Bean(name = "SystemShell")
//@JndiBinding(name = "java:/FRESH/SystemShell")
public class SystemShellImpl extends RegistryNamingBinder implements SystemShell {
    protected static org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(SystemShellImpl.class);

    HashMap shellmap = new HashMap();
    HashMap procmap = new HashMap();

    //private String threadPoolName;
    private String vfsName;

    private Date startTime;

    private ExecutableRegistry registry;

    @Inject(bean = "jboss.system:service=ThreadPool")
    private ThreadPool threadPool;

    //  GCThread gc;
    Timer gc;
    long gcPeriod = 10000L;


    public SystemShellImpl(String vfsname) throws Exception {
        this.vfsName = vfsname;
        log.info("calling do start!");
        startTime = new Date();
        doStart();
        reinitGC();

    }

    public void setThreadPool(ThreadPool threadPool) {
        this.threadPool = threadPool;
    }

    protected String getBindClass() {
        return SystemShell.class.getName();
    }

    protected Object classToInstance(Class c) {
        return this;
    }

    /*public void setThreadPoolName(String threadPoolName) {
        this.threadPoolName = threadPoolName;
    }*/

    /*public SystemShellImpl(String tpname, String vfsname) {
        threadPoolName = tpname;
        vfsName = vfsname;
        startTime = new Date();
        reinitGC();
    }*/

    public void setExecutableRegistry(ExecutableRegistry registry) {
        this.registry = registry;
    }

    public void reinitGC() {

        if (gc != null) gc.cancel();

        gc = new Timer(true);
        TimerTask tt = new TimerTask() {
            public void run() {
                doGC();
            }
        };

        gc.scheduleAtFixedRate(tt, gcPeriod, gcPeriod);
    }

    public void setGCInterval(long val) {
        //gc.setInterval(val);
        if (val == gcPeriod) return;
        gcPeriod = val;
        reinitGC();
    }

    public long getGCInterval() {
        //return gc.getInterval();
        return gcPeriod;
    }

    synchronized private String newID() {
        return org.jboss.fresh.util.UniqueNumberGenerator.getGUID();
    }

    private String newProcessID() {
        return newID();
    }


    public VFS getVFS() {
        VFS vfs = null;
        try {
            RegistryContext ctx = new RegistryContext();
            vfs = (VFS) ctx.lookup(vfsName);
        } catch (NamingException ex) {
            log.error(ex.getMessage(), ex);
            throw new RuntimeException("org.jboss.fresh.shell.impl.SystemShellImpl: startSession: " + vfsName + " not bound.");
        }

        return vfs;
    }

    public Shell startSession(UserCtx uctx, boolean interactive) {
        // create new shell object
        // assign id to it
        // assign uctx to it
        String id = newID();
        VFS vfs = getVFS();
        ShellImpl shell = new ShellImpl(id, interactive, this, uctx, vfs);
        shell.setRegistry(registry);

        // put it in shellmap
        shellmap.put(id, shell);

        // return it
        return shell;
    }

    public Shell continueSession(String sessid) {
        // lookup shell in the shellmap
        Shell shell = (Shell) shellmap.get(sessid);

        // return it
        return shell;
    }

    public void closeSession(String sessid) {
        // remove shell from map
        //log.debug("### removing session: " + sessid);
        log.debug("Removing session: " + sessid);
        ShellImpl shell = (ShellImpl) shellmap.remove(sessid);

        // kill all jobs that are active on this shell
        // call dispose on ShellImpl
        //log.debug("### disposing... " + shell);
        log.debug("Disposing: " + shell);
        if (shell != null) shell.dispose();
    }

    public Process findProcess(String id) throws ShellException {
        return (Process) procmap.get(id);
    }

    public Process createProcess(Shell shell) throws ShellException {
        // take PoolRunner from pool
        try {
            if (!"SINGLE".equals(shell.getEnvProperty("TMODE"))) {
                //Object ob = threadPool.


                if (threadPool == null)
                    throw new ShellException("No thread available. Either you have a thread leak on client side (you closing resources when finished with them?) or you should increase the max size of connection pool.");

            }

            String id = newProcessID();
            Process parent = Process.getThreadParent();
            Process p = new Process(id, parent, this, shell, threadPool);
            if (parent == null)
                p.setEnv(new EnvProperties(shell.getEnv()));
            else
                p.setEnv(new EnvProperties(parent.getEnv()));

            procmap.put(id, p);
            return p;
        } catch (Exception ex) {
            throw new ShellException(ex);
        }
    }

    public Process createProcess(Shell shell, boolean useThreadPool) throws ShellException {
        // take PoolRunner from pool
        if (useThreadPool) return createProcess(shell);

        String id = newProcessID();
        Process parent = Process.getThreadParent();
        Process p = new Process(id, parent, this, shell, threadPool);
        if (parent == null)
            p.setEnv(new EnvProperties(shell.getEnv()));
        else
            p.setEnv(new EnvProperties(parent.getEnv()));

        procmap.put(id, p);
        return p;
    }

    public ProcessGroup createProcessGroup(LinkedList procs) throws ShellException {
        String id = newProcessID();
        Process parent = Process.getThreadParent();
        ProcessGroup pc = new ProcessGroup(id, parent, procs);
        if (parent == null)
            pc.setEnv(new EnvProperties(((Process) procs.getFirst()).getShell().getEnv()));
        else
            pc.setEnv(new EnvProperties(parent.getEnv()));

        Iterator it = procs.iterator();
        while (it.hasNext()) {
            Process p = (Process) it.next();
            p.setGroup(pc);
        }

        procmap.put(id, pc);
        return pc;
    }

    public synchronized void endProcess(String id) {
        // remove this id - nothing else
        //log.debug("### SystemShellImpl : endProcess : " + id);
        Process p = (Process) procmap.remove(id);
        if (p == null) return;
        //log.debug("SystemShellImpl : endProcess : 1");
        p.getShell().removeProcess(id);
        //log.debug("SystemShellImpl : endProcess : 2");
        // All the following code only makes sure the ProcessGroup is removed when
        // none of the Processes it contains is active any more.
        ProcessGroup p2 = (ProcessGroup) p.getGroup();
        //log.debug("SystemShellImpl : endProcess : 3");
        if (p2 == null) return;
        //log.debug("SystemShellImpl : endProcess : 4");
        Iterator it = p2.getProcessList().iterator();
        //log.debug("SystemShellImpl : endProcess : 5");
        boolean keep = false;
        //log.debug("SystemShellImpl : endProcess : 6");
        while (it.hasNext()) {
            Process p3 = (Process) it.next();
            if (p3 == p) {
                it.remove();
            } else {
                Process p4 = (Process) procmap.get(p3.getID());
                if (p4 != null) {
                    keep = true;
                    break;
                }
            }
        }
        //log.debug("SystemShellImpl : endProcess : 7");
        if (!keep) {
            //log.debug("SystemShellImpl : endProcess : 8 (" + p2.getID() + ")");
            procmap.remove(p2.getID());
            if (p2 != p) p.getShell().removeProcess(p2.getID());
        }
        //log.debug("SystemShellImpl : endProcess : 9");
    }

    public Map getProcMap() {
        return new HashMap(procmap);
    }

    public Map getShellMap() {
        return new HashMap(shellmap);
    }


    public void shutdown() {
        //gc.interrupt();
        gc.cancel();
    }

    // we simply call doGC on every session we have
    public void doGC() {
        Map m = new HashMap(shellmap);
        Iterator it = m.values().iterator();
        // Commented out by boky (it's annoying!)
        //log.debug("\n####\n#### GC: ");
        while (it.hasNext()) {
            ShellImpl sh = (ShellImpl) it.next();
            sh.doGC();
        }
    }


/*  class GCThread extends Thread {

    private long ms=10000L; // 10 sec default
    private SystemShellImpl sshell;

    GCThread(SystemShellImpl sshell, String name) {
      super(name);
      GCThread.this.sshell=sshell;
    }

    public void setInterval(long val) {
      ms=val;
    }

    public long getInterval() {
      return ms;
    }

    public void run() {
      // go to sleep for 10 sec
      try {
        while(true) {
//log.debug("[SystemShellImpl] GC: Going to sleep for " + (ms/1000) + " secs.");
          Thread.sleep(ms);
//log.debug("[SystemShellImpl] GC: doing garbage collection ...");
          sshell.doGC();
        }
      } catch(InterruptedException ex) {
      }
//log.debug("[SystemShellImpl] GC: exiting");
    }
  }
*/


    public Date getStartTime() {
        return startTime;
    }
}
TOP

Related Classes of org.jboss.fresh.shell.impl.SystemShellImpl

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.