Package railo.runtime.schedule

Source Code of railo.runtime.schedule.ScheduledTaskThread

package railo.runtime.schedule;

import java.util.Calendar;
import java.util.TimeZone;

import railo.commons.date.DateTimeUtil;
import railo.commons.date.JREDateTimeUtil;
import railo.commons.io.log.Log;
import railo.commons.io.log.LogAndSource;
import railo.commons.io.log.LogUtil;
import railo.commons.lang.SystemOut;
import railo.runtime.config.Config;
import railo.runtime.engine.CFMLEngineImpl;
import railo.runtime.engine.ThreadLocalPageContext;
import railo.runtime.type.dt.DateTimeImpl;

public class ScheduledTaskThread extends Thread {


  private static final long DAY=24*3600000;
  //private Calendar calendar;
 
  private long startDate;
  private long startTime;
  private long endDate;
  private long endTime;
  private int intervall;
  private int amount;
 
  private DateTimeUtil util;

  private int cIntervall;
 
  private Config config;
  private LogAndSource log;
  private ScheduleTask task;
  private String charset;
  private final CFMLEngineImpl engine;
  private TimeZone timeZone;
  private SchedulerImpl scheduler;



 
  public ScheduledTaskThread(CFMLEngineImpl engine,SchedulerImpl scheduler, Config config, LogAndSource log, ScheduleTask task, String charset) {
    util = DateTimeUtil.getInstance();
    this.engine=engine;
    this.scheduler=scheduler;
    this.config=config;
    this.log=log;
    this.task=task;
    this.charset=charset;
    timeZone=ThreadLocalPageContext.getTimeZone(config);
   
    this.startDate=util.getMilliSecondsAdMidnight(timeZone,task.getStartDate().getTime());
    this.startTime=util.getMilliSecondsInDay(timeZone, task.getStartTime().getTime());
    this.endDate=task.getEndDate()==null?Long.MAX_VALUE:util.getMilliSecondsAdMidnight(timeZone,task.getEndDate().getTime());
    this.endTime=task.getEndTime()==null?DAY:util.getMilliSecondsInDay(timeZone, task.getEndTime().getTime());

   
    this.intervall=task.getInterval();
    if(intervall>=10){
      amount=intervall;
      intervall=ScheduleTaskImpl.INTERVAL_EVEREY;
    }
    else amount=1;

    cIntervall = toCalndarIntervall(intervall);
  }


  public void run(){
    try{
    _run();
    }
    finally{
      task.setValid(false);
      try {
        scheduler.removeIfNoLonerValid(task);
      } catch (Throwable t) {
        t.printStackTrace();
      }
    }
   
  }
  public void _run(){
   
       
    // check values
    if(startDate>endDate) {
      log(Log.LEVEL_ERROR,"This task can not be executed because the task definition is invalid; enddate is before startdate");
      return;
    }
    if(intervall==ScheduleTaskImpl.INTERVAL_EVEREY && startTime>endTime) {
      log(Log.LEVEL_ERROR,"This task can not be executed because the task definition is invalid; endtime is before starttime");
      return;
    }
   
   
    long today = System.currentTimeMillis();
    long execution ;
    boolean isOnce=intervall==ScheduleTask.INTERVAL_ONCE;
    if(isOnce){
      if(startDate+startTime<today) return;
      execution=startDate+startTime;
    }
    else execution = calculateNextExecution(today,false);
    //long sleep=execution-today;
   
    log(Log.LEVEL_INFO,"first execution runs at "+new DateTimeImpl(execution,false).castToString(timeZone));
   
   
    while(true){
      sleepEL(execution,today);
     
      if(!engine.isRunning()) break;
     
      today=System.currentTimeMillis();
      long todayTime=util.getMilliSecondsInDay(null,today);
      long todayDate=today-todayTime;
     
      if(!task.isValid()) break;
      if(!task.isPaused()){
        if(endDate<todayDate && endTime<todayTime) {
          break;
        }
        execute();
      }
      if(isOnce)break;
      today=System.currentTimeMillis();
      execution=calculateNextExecution(today,true);
      log(Log.LEVEL_INFO,"next execution runs at "+new DateTimeImpl(execution,false).castToString(timeZone)+":"+today+":"+execution);
      //sleep=execution-today;
    }
  }
 
 
 
 
  private void log(int level, String msg) {
    String logName="schedule task:"+task.getTask();
    if(log!=null) log.log(level,logName, msg);
    else SystemOut.print(LogUtil.toStringType(level, "INFO").toUpperCase()+":"+msg);
   
  }


  private void sleepEL(long when, long now) {
    long millis = when-now;
   
    try {
      while(true){
        sleep(millis);
        millis=when-System.currentTimeMillis();
        if(millis<=0)break;
        millis=10;
      }
    }
    catch (InterruptedException e) {
      e.printStackTrace();
    }

  }

  private void execute() {
    if(config!=null)new ExecutionThread(config,log,task,charset).start();
  }

  private long calculateNextExecution(long now, boolean notNow) {
    long nowTime=util.getMilliSecondsInDay(timeZone,now);
    long nowDate=now-nowTime;
   
   
    // when second or date intervall switch to current date
    if(startDate<nowDate && (cIntervall==Calendar.SECOND || cIntervall==Calendar.DATE))
      startDate=nowDate;
   
    // init calendar
    Calendar calendar = JREDateTimeUtil.getThreadCalendar(timeZone);
    calendar.setTimeInMillis(startDate+startTime);
   
    long time;
    while(true) {
      time=getMilliSecondsInDay(calendar);
      if(now<=calendar.getTimeInMillis() && time>=startTime) {
        // this is used because when cames back sometme to early
        if(notNow && (calendar.getTimeInMillis()-now)<1000);
        else if(intervall==ScheduleTaskImpl.INTERVAL_EVEREY && time>endTime)
          now=nowDate+DAY;
        else
          break;
      }
      calendar.add(cIntervall, amount);
    }
    return calendar.getTimeInMillis();
  }

  private static int toCalndarIntervall(int intervall) {
    switch(intervall){
    case ScheduleTask.INTERVAL_DAY:return Calendar.DATE;
    case ScheduleTask.INTERVAL_MONTH:return Calendar.MONTH;
    case ScheduleTask.INTERVAL_WEEK:return Calendar.WEEK_OF_YEAR;
    case ScheduleTask.INTERVAL_ONCE:return -1;
   
    }
    return Calendar.SECOND;
  }
 
  public static long getMilliSecondsInDay(Calendar c) {
    return  (c.get(Calendar.HOUR_OF_DAY)*3600000)+
                    (c.get(Calendar.MINUTE)*60000)+
                    (c.get(Calendar.SECOND)*1000)+
                    (c.get(Calendar.MILLISECOND));
       
    }
 

  public Config getConfig() {
    return config;
  }


  public ScheduleTask getTask() {
    return task;
  }
}
TOP

Related Classes of railo.runtime.schedule.ScheduledTaskThread

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.