Package railo.runtime.engine

Source Code of railo.runtime.engine.Controler

package railo.runtime.engine;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;

import railo.commons.io.IOUtil;
import railo.commons.io.res.Resource;
import railo.commons.io.res.filter.ExtensionResourceFilter;
import railo.commons.io.res.filter.ResourceFilter;
import railo.commons.io.res.util.ResourceUtil;
import railo.commons.lang.SystemOut;
import railo.commons.lang.types.RefBoolean;
import railo.runtime.CFMLFactoryImpl;
import railo.runtime.Mapping;
import railo.runtime.MappingImpl;
import railo.runtime.PageSource;
import railo.runtime.PageSourcePool;
import railo.runtime.config.ConfigImpl;
import railo.runtime.config.ConfigServer;
import railo.runtime.config.ConfigWeb;
import railo.runtime.config.ConfigWebAdmin;
import railo.runtime.config.DeployHandler;
import railo.runtime.lock.LockManagerImpl;
import railo.runtime.net.smtp.SMTPConnectionPool;
import railo.runtime.op.Caster;
import railo.runtime.type.scope.ScopeContext;
import railo.runtime.type.scope.client.ClientFile;
import railo.runtime.type.util.ArrayUtil;

/**
* own thread how check the main thread and his data
*/
public final class Controler extends Thread {

  private int interval;
  private long lastMinuteInterval=System.currentTimeMillis();
  private long lastHourInterval=System.currentTimeMillis();
 
    private final Map contextes;
    private final RefBoolean run;
  //private ScheduleThread scheduleThread;
  private final ConfigServer configServer;

  /**
   * @param contextes
   * @param interval
   * @param run
   */
  public Controler(ConfigServer configServer,Map contextes,int interval, RefBoolean run) {   
        this.contextes=contextes;
    this.interval=interval;
        this.run=run;
        this.configServer=configServer;
       
        Runtime.getRuntime().addShutdownHook(new ShutdownHook(configServer));
       
        // Register Memory Notification Listener
        //MemoryControler.init(configServer);
       
  }
 
  @Override
  public void run() {
    //scheduleThread.start();
    boolean firstRun=true;
   
    CFMLFactoryImpl factories[]=null;
    while(run.toBooleanValue()) {
          try {
        sleep(interval);
      }
            catch (InterruptedException e) {
        e.printStackTrace();
      }
            long now = System.currentTimeMillis();
            //print.out("now:"+new Date(now));
            boolean doMinute=lastMinuteInterval+60000<now;
            if(doMinute)lastMinuteInterval=now;
            boolean doHour=(lastHourInterval+(1000*60*60))<now;
            if(doHour)lastHourInterval=now;
           
            // broadcast cluster scope
            factories=toFactories(factories,contextes);
            try {
        ScopeContext.getClusterScope(configServer,true).broadcast();
      }
            catch (Throwable t) {
        t.printStackTrace();
      }
           

            // every minute
            if(doMinute) {
              // deploy extensions, archives ...
        try{DeployHandler.deploy(configServer);}catch(Throwable t){t.printStackTrace();}
                try{ConfigWebAdmin.checkForChangesInConfigFile(configServer);}catch(Throwable t){}
            }
            // every hour
            if(doHour) {
              try{configServer.checkPermGenSpace(true);}catch(Throwable t){}
            }
           
            for(int i=0;i<factories.length;i++) {
              run(factories[i], doMinute, doHour,firstRun);
          }
          if(factories.length>0)
        firstRun=false;
      }   
  }

  private CFMLFactoryImpl[] toFactories(CFMLFactoryImpl[] factories,Map contextes) {
    if(factories==null || factories.length!=contextes.size())
      factories=(CFMLFactoryImpl[]) contextes.values().toArray(new CFMLFactoryImpl[contextes.size()]);
   
    return factories;
  }

  private void run(CFMLFactoryImpl cfmlFactory, boolean doMinute, boolean doHour, boolean firstRun) {
    try {
        boolean isRunning=cfmlFactory.getUsedPageContextLength()>0;  
          if(isRunning) {
          cfmlFactory.checkTimeout();
          }
        ConfigWeb config = null;
       
        if(firstRun) {
          config = cfmlFactory.getConfig();
          ThreadLocalConfig.register(config);
         
          config.reloadTimeServerOffset();
          checkOldClientFile(config);
         
          //try{checkStorageScopeFile(config,Session.SCOPE_CLIENT);}catch(Throwable t){}
          //try{checkStorageScopeFile(config,Session.SCOPE_SESSION);}catch(Throwable t){}
          try{config.reloadTimeServerOffset();}catch(Throwable t){}
          try{checkTempDirectorySize(config);}catch(Throwable t){}
          try{checkCacheFileSize(config);}catch(Throwable t){}
          try{cfmlFactory.getScopeContext().clearUnused();}catch(Throwable t){}
        }
       
        if(config==null) {
          config = cfmlFactory.getConfig();
          ThreadLocalConfig.register(config);
        }
       
       
        //every Minute
        if(doMinute) {
          if(config==null) {
            config = cfmlFactory.getConfig();
            ThreadLocalConfig.register(config);
          }
         
          // deploy extensions, archives ...
          try{DeployHandler.deploy(config);}catch(Throwable t){t.printStackTrace();}
         
          // clear unused DB Connections
          try{((ConfigImpl)config).getDatasourceConnectionPool().clear();}catch(Throwable t){}
          // clear all unused scopes
          try{cfmlFactory.getScopeContext().clearUnused();}catch(Throwable t){}
          // Memory usage
          // clear Query Cache
          try{cfmlFactory.getDefaultQueryCache().clearUnused(null);}catch(Throwable t){}
          // contract Page Pool
          //try{doClearPagePools((ConfigWebImpl) config);}catch(Throwable t){}
          //try{checkPermGenSpace((ConfigWebImpl) config);}catch(Throwable t){}
          try{doCheckMappings(config);}catch(Throwable t){}
          try{doClearMailConnections();}catch(Throwable t){}
          // clean LockManager
          if(cfmlFactory.getUsedPageContextLength()==0)try{((LockManagerImpl)config.getLockManager()).clean();}catch(Throwable t){}
         
          try{ConfigWebAdmin.checkForChangesInConfigFile(config);}catch(Throwable t){}
               
        }
        // every hour
        if(doHour) {
          if(config==null) {
            config = cfmlFactory.getConfig();
            ThreadLocalConfig.register(config);
          }
          // time server offset
          try{config.reloadTimeServerOffset();}catch(Throwable t){}
          // check file based client/session scope
          //try{checkStorageScopeFile(config,Session.SCOPE_CLIENT);}catch(Throwable t){}
          //try{checkStorageScopeFile(config,Session.SCOPE_SESSION);}catch(Throwable t){}
          // check temp directory
          try{checkTempDirectorySize(config);}catch(Throwable t){}
          // check cache directory
          try{checkCacheFileSize(config);}catch(Throwable t){}
        }
      }
      catch(Throwable t){
       
      }
      finally{
        ThreadLocalConfig.release();
      }
  }

  private void doClearMailConnections() {
    SMTPConnectionPool.closeSessions();
  }

  private void checkOldClientFile(ConfigWeb config) {
    ExtensionResourceFilter filter = new ExtensionResourceFilter(".script",false);
   
    // move old structured file in new structure
    try {
      Resource dir = config.getClientScopeDir(),trgres;
      Resource[] children = dir.listResources(filter);
      String src,trg;
      int index;
      for(int i=0;i<children.length;i++) {
        src=children[i].getName();
        index=src.indexOf('-');

        trg=ClientFile.getFolderName(src.substring(0,index), src.substring(index+1),false);
        trgres=dir.getRealResource(trg);
        if(!trgres.exists()){
          trgres.createFile(true);
          ResourceUtil.copy(children[i],trgres);
        }
          //children[i].moveTo(trgres);
        children[i].delete();
       
      }
    } catch (Throwable t) {}
  }

  private void checkCacheFileSize(ConfigWeb config) {
    checkSize(config,config.getCacheDir(),config.getCacheDirSize(),new ExtensionResourceFilter(".cache"));
  }
 
  private void checkTempDirectorySize(ConfigWeb config) {
    checkSize(config,config.getTempDirectory(),1024*1024*1024,null);
  }
 
  private void checkSize(ConfigWeb config,Resource dir,long maxSize, ResourceFilter filter) {
    if(!dir.exists()) return;
    Resource res=null;
    int count=ArrayUtil.size(filter==null?dir.list():dir.list(filter));
    long size=ResourceUtil.getRealSize(dir,filter);
    PrintWriter out = config.getOutWriter();
    SystemOut.printDate(out,"check size of directory ["+dir+"]");
    SystemOut.printDate(out,"- current size  ["+size+"]");
    SystemOut.printDate(out,"- max size   ["+maxSize+"]");
    int len=-1;
    while(count>100000 || size>maxSize) {
      Resource[] files = filter==null?dir.listResources():dir.listResources(filter);
      if(len==files.length) break;// protect from inifinti loop
      len=files.length;
      for(int i=0;i<files.length;i++) {
        if(res==null || res.lastModified()>files[i].lastModified()) {
          res=files[i];
        }
      }
      if(res!=null) {
        size-=res.length();
        try {
          res.remove(true);
          count--;
        } catch (IOException e) {
          SystemOut.printDate(out,"cannot remove resource "+res.getAbsolutePath());
          break;
        }
      }
      res=null;
    }
   
  }

  private void doCheckMappings(ConfigWeb config) {
        Mapping[] mappings = config.getMappings();
        for(int i=0;i<mappings.length;i++) {
            Mapping mapping = mappings[i];
            mapping.check();
        }
    }

  private PageSourcePool[] getPageSourcePools(ConfigWeb config) {
    return getPageSourcePools(config.getMappings());
  }

  private PageSourcePool[] getPageSourcePools(Mapping... mappings) {
        PageSourcePool[] pools=new PageSourcePool[mappings.length];
        //int size=0;
       
        for(int i=0;i<mappings.length;i++) {
            pools[i]=((MappingImpl)mappings[i]).getPageSourcePool();
            //size+=pools[i].size();
        }
        return pools;
    }
    private int getPageSourcePoolSize(PageSourcePool[] pools) {
        int size=0;
        for(int i=0;i<pools.length;i++)size+=pools[i].size();
        return size;
    }
    private void removeOldest(PageSourcePool[] pools) {
        PageSourcePool pool=null;
        Object key=null;
        PageSource ps=null;
       
        long date=-1;
        for(int i=0;i<pools.length;i++) {
          try {
              Object[] keys=pools[i].keys();
              for(int y=0;y<keys.length;y++) {
                  ps = pools[i].getPageSource(keys[y],false);
                  if(date==-1 || date>ps.getLastAccessTime()) {
                      pool=pools[i];
                      key=keys[y];
                      date=ps.getLastAccessTime();
                  }
              }
          }
          catch(Throwable t) {
            pools[i].clear();
          }
         
        }
        if(pool!=null)pool.remove(key);
    }
    private void clear(PageSourcePool[] pools) {
        for(int i=0;i<pools.length;i++) {
          pools[i].clear();
        }
    }

    /*private void doLogMemoryUsage(ConfigWeb config) {
    if(config.logMemoryUsage()&& config.getMemoryLogger()!=null)
      config.getMemoryLogger().write();
  }*/
   
   
    static class ExpiresFilter implements ResourceFilter {

    private long time;
    private boolean allowDir;

    public ExpiresFilter(long time, boolean allowDir) {
      this.allowDir=allowDir;
      this.time=time;
    }

    public boolean accept(Resource res) {

      if(res.isDirectory()) return allowDir;
     
      // load content
      String str=null;
      try {
        str = IOUtil.toString(res,"UTF-8");
      }
      catch (IOException e) {
        return false;
      }
     
      int index=str.indexOf(':');
      if(index!=-1){
        long expires=Caster.toLongValue(str.substring(0,index),-1L);
        // check is for backward compatibility, old files have no expires date inside. they do ot expire
        if(expires!=-1) {
          if(expires<System.currentTimeMillis()){
            return true;
          }
          str=str.substring(index+1);
          return false;
        }
      }
      // old files not having a timestamp inside
      else if(res.lastModified()<=time) {
        return true;
       
      }
      return false;
    }
     
    }
}
TOP

Related Classes of railo.runtime.engine.Controler

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.