merged changes from helma_1_2_cron branch (replacing the scheduler with
a cron-like setup)
This commit is contained in:
		
							parent
							
								
									c8674a5f3d
								
							
						
					
					
						commit
						b522a740df
					
				
					 4 changed files with 234 additions and 38 deletions
				
			
		| 
						 | 
					@ -146,6 +146,11 @@ public final class Application implements IPathElement, Runnable {
 | 
				
			||||||
    // the name under which this app serves XML-RPC requests. Defaults to the app name
 | 
					    // the name under which this app serves XML-RPC requests. Defaults to the app name
 | 
				
			||||||
    private String xmlrpcHandlerName;
 | 
					    private String xmlrpcHandlerName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // the list of cron jobs
 | 
				
			||||||
 | 
					    private Map activeCronJobs = null;
 | 
				
			||||||
 | 
					    private Vector cronJobs = null;
 | 
				
			||||||
 | 
					    Hashtable customCronJobs = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Build an application with the given name in the app directory. No Server-wide
 | 
					     * Build an application with the given name in the app directory. No Server-wide
 | 
				
			||||||
     * properties are created or used.
 | 
					     * properties are created or used.
 | 
				
			||||||
| 
						 | 
					@ -305,6 +310,8 @@ public final class Application implements IPathElement, Runnable {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        activeRequests = new Hashtable();
 | 
					        activeRequests = new Hashtable();
 | 
				
			||||||
 | 
					        activeCronJobs = new WeakHashMap();
 | 
				
			||||||
 | 
					        customCronJobs = new Hashtable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        skinmgr = new SkinManager(this);
 | 
					        skinmgr = new SkinManager(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1355,42 +1362,88 @@ public final class Application implements IPathElement, Runnable {
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // check if we should call scheduler
 | 
					            if ((cronJobs == null) || (props.lastModified() > lastPropertyRead)) {
 | 
				
			||||||
            if ((now - lastScheduler) > scheduleSleep) {
 | 
					                updateProperties();
 | 
				
			||||||
                lastScheduler = now;
 | 
					                cronJobs = CronJob.parse(props);
 | 
				
			||||||
 | 
					 | 
				
			||||||
                Object val = null;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                try {
 | 
					 | 
				
			||||||
                    val = eval.invokeFunction((INode) null, "scheduler", new Object[0]);
 | 
					 | 
				
			||||||
                } catch (Exception ignore) {
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                try {
 | 
					 | 
				
			||||||
                    int ret = ((Number) val).intValue();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if (ret < 1000) {
 | 
					 | 
				
			||||||
                        scheduleSleep = 60000L;
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        scheduleSleep = ret;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                } catch (Exception ignore) {
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // logEvent ("Called scheduler for "+name+", will sleep for "+scheduleSleep+" millis");
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // sleep until we have work to do
 | 
					            Date d = new Date();
 | 
				
			||||||
 | 
					            List jobs = (List) cronJobs.clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            jobs.addAll(customCronJobs.values());
 | 
				
			||||||
 | 
					            CronJob.sort(jobs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for (Iterator i = jobs.iterator(); i.hasNext();) {
 | 
				
			||||||
 | 
					                CronJob j = (CronJob) i.next();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (j.appliesToDate(d)) {
 | 
				
			||||||
 | 
					                    // check if the job is already active ...
 | 
				
			||||||
 | 
					                    if (activeCronJobs.containsKey(j.getName())) {
 | 
				
			||||||
 | 
					                        logEvent(j + " is still active, skipped in this minute");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        continue;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    RequestEvaluator thisEvaluator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    try {
 | 
				
			||||||
 | 
					                        thisEvaluator = getEvaluator();
 | 
				
			||||||
 | 
					                    } catch (RuntimeException rt) {
 | 
				
			||||||
 | 
					                        if (stopped == false) {
 | 
				
			||||||
 | 
					                            logEvent("couldn't execute " + j +
 | 
				
			||||||
 | 
					                                     ", maximum thread count reached");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            continue;
 | 
				
			||||||
 | 
					                        } else {
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // if the job has a long timeout or we're already late during this minute
 | 
				
			||||||
 | 
					                    // the job is run from an extra thread
 | 
				
			||||||
 | 
					                    if ((j.getTimeout() > 20000) ||
 | 
				
			||||||
 | 
					                            (CronJob.millisToNextFullMinute() < 30000)) {
 | 
				
			||||||
 | 
					                        CronRunner r = new CronRunner(thisEvaluator, j);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        r.start();
 | 
				
			||||||
 | 
					                        activeCronJobs.put(j.getName(), r);
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        try {
 | 
				
			||||||
 | 
					                            thisEvaluator.invokeFunction((INode) null, j.getFunction(),
 | 
				
			||||||
 | 
					                                                         new Object[0], j.getTimeout());
 | 
				
			||||||
 | 
					                        } catch (Exception ex) {
 | 
				
			||||||
 | 
					                            logEvent("error running " + j + ": " + ex.toString());
 | 
				
			||||||
 | 
					                        } finally {
 | 
				
			||||||
 | 
					                            if (stopped == false) {
 | 
				
			||||||
 | 
					                                releaseEvaluator(thisEvaluator);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    thisEvaluator = null;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // sleep until the next full minute
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                worker.sleep(Math.min(cleanupSleep, scheduleSleep));
 | 
					                worker.sleep(CronJob.millisToNextFullMinute());
 | 
				
			||||||
            } catch (InterruptedException x) {
 | 
					            } catch (InterruptedException x) {
 | 
				
			||||||
                logEvent("Scheduler for " + name + " interrupted");
 | 
					                logEvent("Scheduler for " + name + " interrupted");
 | 
				
			||||||
                worker = null;
 | 
					                worker = null;
 | 
				
			||||||
 | 
					 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // when interrupted, shutdown running cron jobs
 | 
				
			||||||
 | 
					        synchronized (activeCronJobs) {
 | 
				
			||||||
 | 
					            for (Iterator i = activeCronJobs.keySet().iterator(); i.hasNext();) {
 | 
				
			||||||
 | 
					                String jobname = (String) i.next();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                ((CronRunner) activeCronJobs.get(jobname)).interrupt();
 | 
				
			||||||
 | 
					                activeCronJobs.remove(jobname);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        logEvent("Scheduler for " + name + " exiting");
 | 
					        logEvent("Scheduler for " + name + " exiting");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1761,4 +1814,29 @@ public final class Application implements IPathElement, Runnable {
 | 
				
			||||||
            logEvent("error loading session data: " + e.toString());
 | 
					            logEvent("error loading session data: " + e.toString());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class CronRunner extends Thread {
 | 
				
			||||||
 | 
					        RequestEvaluator thisEvaluator;
 | 
				
			||||||
 | 
					        CronJob job;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public CronRunner(RequestEvaluator thisEvaluator, CronJob job) {
 | 
				
			||||||
 | 
					            this.thisEvaluator = thisEvaluator;
 | 
				
			||||||
 | 
					            this.job = job;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void run() {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                thisEvaluator.invokeFunction((INode) null, job.getFunction(),
 | 
				
			||||||
 | 
					                                             new Object[0], job.getTimeout());
 | 
				
			||||||
 | 
					            } catch (Exception ex) {
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (stopped == false) {
 | 
				
			||||||
 | 
					                releaseEvaluator(thisEvaluator);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            thisEvaluator = null;
 | 
				
			||||||
 | 
					            activeCronJobs.remove(job.getName());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,6 +17,7 @@
 | 
				
			||||||
package helma.framework.core;
 | 
					package helma.framework.core;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import helma.objectmodel.INode;
 | 
					import helma.objectmodel.INode;
 | 
				
			||||||
 | 
					import helma.util.CronJob;
 | 
				
			||||||
import java.io.File;
 | 
					import java.io.File;
 | 
				
			||||||
import java.io.Serializable;
 | 
					import java.io.Serializable;
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
| 
						 | 
					@ -254,6 +255,45 @@ public class ApplicationBean implements Serializable {
 | 
				
			||||||
        return (SessionBean[]) userSessions.toArray(new SessionBean[0]);
 | 
					        return (SessionBean[]) userSessions.toArray(new SessionBean[0]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param functionName ...
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public void addCronJob(String functionName) {
 | 
				
			||||||
 | 
					        CronJob job = new CronJob(functionName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        job.setFunction(functionName);
 | 
				
			||||||
 | 
					        app.customCronJobs.put(functionName, job);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param functionName ...
 | 
				
			||||||
 | 
					     * @param year ...
 | 
				
			||||||
 | 
					     * @param month ...
 | 
				
			||||||
 | 
					     * @param day ...
 | 
				
			||||||
 | 
					     * @param weekday ...
 | 
				
			||||||
 | 
					     * @param hour ...
 | 
				
			||||||
 | 
					     * @param minute ...
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public void addCronJob(String functionName, String year, String month, String day,
 | 
				
			||||||
 | 
					                           String weekday, String hour, String minute) {
 | 
				
			||||||
 | 
					        CronJob job = CronJob.newJob(functionName, year, month, day, weekday, hour, minute);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        app.customCronJobs.put(functionName, job);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param functionName ...
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public void removeCronJob(String functionName) {
 | 
				
			||||||
 | 
					        app.customCronJobs.remove(functionName);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // getter methods for readonly properties of this application
 | 
					    // getter methods for readonly properties of this application
 | 
				
			||||||
    public int getcacheusage() {
 | 
					    public int getcacheusage() {
 | 
				
			||||||
        return app.getCacheUsage();
 | 
					        return app.getCacheUsage();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -737,6 +737,25 @@ public final class RequestEvaluator implements Runnable {
 | 
				
			||||||
    public synchronized Object invokeFunction(Object object, String functionName,
 | 
					    public synchronized Object invokeFunction(Object object, String functionName,
 | 
				
			||||||
                                              Object[] args)
 | 
					                                              Object[] args)
 | 
				
			||||||
                                       throws Exception {
 | 
					                                       throws Exception {
 | 
				
			||||||
 | 
					        // give internal call more time (15 minutes) to complete
 | 
				
			||||||
 | 
					        return invokeFunction(object, functionName, args, 60000L * 15);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param object ...
 | 
				
			||||||
 | 
					     * @param functionName ...
 | 
				
			||||||
 | 
					     * @param args ...
 | 
				
			||||||
 | 
					     * @param timeout ...
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return ...
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @throws Exception ...
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public synchronized Object invokeFunction(Object object, String functionName,
 | 
				
			||||||
 | 
					                                              Object[] args, long timeout)
 | 
				
			||||||
 | 
					                                       throws Exception {
 | 
				
			||||||
        reqtype = INTERNAL;
 | 
					        reqtype = INTERNAL;
 | 
				
			||||||
        session = null;
 | 
					        session = null;
 | 
				
			||||||
        thisObject = object;
 | 
					        thisObject = object;
 | 
				
			||||||
| 
						 | 
					@ -747,7 +766,7 @@ public final class RequestEvaluator implements Runnable {
 | 
				
			||||||
        exception = null;
 | 
					        exception = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        checkThread();
 | 
					        checkThread();
 | 
				
			||||||
        wait(60000L * 15); // give internal call more time (15 minutes) to complete
 | 
					        wait(timeout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (reqtype != NONE) {
 | 
					        if (reqtype != NONE) {
 | 
				
			||||||
            stopThread();
 | 
					            stopThread();
 | 
				
			||||||
| 
						 | 
					@ -799,7 +818,6 @@ public final class RequestEvaluator implements Runnable {
 | 
				
			||||||
        if (exception != null) {
 | 
					        if (exception != null) {
 | 
				
			||||||
            throw (exception);
 | 
					            throw (exception);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        return result;
 | 
					        return result;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -86,7 +86,7 @@ public class CronJob {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   private String name     = null;
 | 
					   private String name     = null;
 | 
				
			||||||
   private String function = null;
 | 
					   private String function = null;
 | 
				
			||||||
   private long   timeout = 30000;
 | 
					   private long   timeout = 20000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   /** A method for parsing properties. It looks through the properties
 | 
					   /** A method for parsing properties. It looks through the properties
 | 
				
			||||||
     * file for entries that look like this:
 | 
					     * file for entries that look like this:
 | 
				
			||||||
| 
						 | 
					@ -161,7 +161,26 @@ public class CronJob {
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public static Collection parse(Properties props) {
 | 
					  public static CronJob newJob (String functionName, String year, String month, String day, String weekday, String hour, String minute) {
 | 
				
			||||||
 | 
					    CronJob job = new CronJob (functionName);
 | 
				
			||||||
 | 
					    job.setFunction (functionName);
 | 
				
			||||||
 | 
					    if (year != null)
 | 
				
			||||||
 | 
					        parseYear (job, year);
 | 
				
			||||||
 | 
					    if (month != null)
 | 
				
			||||||
 | 
					        parseMonth (job, month);
 | 
				
			||||||
 | 
					    if (day != null)
 | 
				
			||||||
 | 
					        parseDay (job, day);
 | 
				
			||||||
 | 
					    if (weekday != null)
 | 
				
			||||||
 | 
					        parseWeekDay (job, weekday);
 | 
				
			||||||
 | 
					    if (hour != null)
 | 
				
			||||||
 | 
					        parseHour (job, hour);
 | 
				
			||||||
 | 
					    if (minute != null)
 | 
				
			||||||
 | 
					        parseMinute (job, minute);
 | 
				
			||||||
 | 
					    return job;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public static Vector parse(Properties props) {
 | 
				
			||||||
      Hashtable jobs = new Hashtable ();
 | 
					      Hashtable jobs = new Hashtable ();
 | 
				
			||||||
      Enumeration e = props.keys ();
 | 
					      Enumeration e = props.keys ();
 | 
				
			||||||
      while (e.hasMoreElements ()) {
 | 
					      while (e.hasMoreElements ()) {
 | 
				
			||||||
| 
						 | 
					@ -195,13 +214,40 @@ public class CronJob {
 | 
				
			||||||
               parseHour (job, value);
 | 
					               parseHour (job, value);
 | 
				
			||||||
            } else if (jobSpec.equalsIgnoreCase("minute")) {
 | 
					            } else if (jobSpec.equalsIgnoreCase("minute")) {
 | 
				
			||||||
               parseMinute (job, value);
 | 
					               parseMinute (job, value);
 | 
				
			||||||
 | 
					            } else if (jobSpec.equalsIgnoreCase("timeout")) {
 | 
				
			||||||
 | 
					            	parseTimeout (job, value);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
         } catch (NoSuchElementException nsee) {
 | 
					         } catch (NoSuchElementException nsee) {
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      return jobs.values ();
 | 
					      Vector jobVec = new Vector (jobs.values ());
 | 
				
			||||||
 | 
					      return (Vector) sort (jobVec);
 | 
				
			||||||
   }
 | 
					   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static List sort (List list) {
 | 
				
			||||||
 | 
					      Collections.sort (list, new Comparator() {
 | 
				
			||||||
 | 
					        public int compare (Object o1, Object o2) {
 | 
				
			||||||
 | 
					            CronJob cron1 = (CronJob) o1;
 | 
				
			||||||
 | 
					            CronJob cron2 = (CronJob) o2;
 | 
				
			||||||
 | 
					            if (cron1.getTimeout () > cron2.getTimeout ())
 | 
				
			||||||
 | 
					                return 1;
 | 
				
			||||||
 | 
					            else if (cron1.getTimeout () < cron2.getTimeout ())
 | 
				
			||||||
 | 
					                return -1;
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                return 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public boolean equals (Object o1, Object o2) {
 | 
				
			||||||
 | 
					            if (o1!=null) {
 | 
				
			||||||
 | 
					                return o1.equals (o2);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        return list;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   public static void parseYear (CronJob job, String value) {
 | 
					   public static void parseYear (CronJob job, String value) {
 | 
				
			||||||
      if (value.equals("*")) {
 | 
					      if (value.equals("*")) {
 | 
				
			||||||
| 
						 | 
					@ -351,6 +397,22 @@ public class CronJob {
 | 
				
			||||||
   }
 | 
					   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   public static void parseTimeout (CronJob job, String timeout) {
 | 
				
			||||||
 | 
					      long timeoutValue = 1000 * Long.valueOf(timeout).longValue ();
 | 
				
			||||||
 | 
					      job.setTimeout (timeoutValue);
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public static long nextFullMinute () {
 | 
				
			||||||
 | 
							long now = System.currentTimeMillis();
 | 
				
			||||||
 | 
					      long millisAfterMinute = (now % 60000);
 | 
				
			||||||
 | 
							return (now + 60000 - millisAfterMinute);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public static long millisToNextFullMinute () {
 | 
				
			||||||
 | 
							long now = System.currentTimeMillis();
 | 
				
			||||||
 | 
					      long millisAfterMinute = (now % 60000);
 | 
				
			||||||
 | 
							return (60000 - millisAfterMinute);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   *  Create an empty CronJob.
 | 
					   *  Create an empty CronJob.
 | 
				
			||||||
| 
						 | 
					@ -657,13 +719,6 @@ public class CronJob {
 | 
				
			||||||
    this.timeout = timeout;
 | 
					    this.timeout = timeout;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					 | 
				
			||||||
   *  Set this entry's timeout
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
  public void setTimeout(String timeout)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    this.timeout = Long.valueOf(timeout).longValue ();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   *  Get this entry's timeout
 | 
					   *  Get this entry's timeout
 | 
				
			||||||
| 
						 | 
					@ -672,4 +727,9 @@ public class CronJob {
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    return this.timeout;
 | 
					    return this.timeout;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  public String toString () {
 | 
				
			||||||
 | 
					  		return "[CronJob " + name + "]";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue