Author: bleny Date: 2010-07-07 16:56:36 +0200 (Wed, 07 Jul 2010) New Revision: 99 Url: http://nuiton.org/repositories/revision/diswork/99 Log: suppression des attentes actives Modified: trunk/diswork-daemon/src/main/java/org/nuiton/diswork/daemon/ActivityStrategy.java trunk/diswork-daemon/src/main/java/org/nuiton/diswork/daemon/DisworkDaemon.java trunk/diswork-daemon/src/main/java/org/nuiton/diswork/daemon/WorkersManager.java Modified: trunk/diswork-daemon/src/main/java/org/nuiton/diswork/daemon/ActivityStrategy.java =================================================================== --- trunk/diswork-daemon/src/main/java/org/nuiton/diswork/daemon/ActivityStrategy.java 2010-07-07 09:22:04 UTC (rev 98) +++ trunk/diswork-daemon/src/main/java/org/nuiton/diswork/daemon/ActivityStrategy.java 2010-07-07 14:56:36 UTC (rev 99) @@ -61,13 +61,72 @@ * */ public interface ActivityStrategy { + + public enum ActivityStrategies { + NONE ("none"), + UNLIMITED ("unlimited"), + LIMITED ("limited"), + SCHEDULED ("scheduled"); + /** those labels will be used in the config file */ + public String label; + + ActivityStrategies(String name) { + this.label = name; + } + + /** return the enumeration element given its label */ + static ActivityStrategies valueOfLabel(String label) { + for (ActivityStrategies aStrategy : values()) { + if (aStrategy.label == label) { + return aStrategy; + } + } + throw new IllegalArgumentException("wrong strategy label : " + label); + } + + /** factory method, instantiate the good strategy given its label */ + static ActivityStrategy getNewInstance(DisworkConfig config, String label) { + return getNewInstance(config, valueOfLabel(label)); + } + + static ActivityStrategy getNewInstance(DisworkConfig config, ActivityStrategies strat) { + ActivityStrategy result = null; + switch (strat) { + case NONE: + result = new NoActivity(); + break; + case UNLIMITED: + result = new UnlimitedActivity(); + break; + case LIMITED: + result = new LimitedActivity(); + break; + case SCHEDULED: + result = new ScheduledActivity(config); + break; + } + return result; + } + } + /** use this strategy to never run a job */ public static class NoActivity implements ActivityStrategy { @Override public boolean canWork() { return false; } + + @Override + public long timeBeforeNextUpdate() { + // this will never change + return -1; + } + + @Override + public String toString() { + return "no activity"; + } } /** use this strategy to always run a job */ @@ -76,21 +135,32 @@ public boolean canWork() { return true; } + + @Override + public long timeBeforeNextUpdate() { + // this will never change + return -1; + } + + @Override + public String toString() { + return "unlimited activity"; + } } /** use this strategy to run a job only if computer is idling */ public static class LimitedActivity implements ActivityStrategy { - + private static final Log log = LogFactory.getLog(LimitedActivity.class); - - protected static class LoadAverageMonitoring extends Thread { + protected class LoadAverageMonitoring extends Thread { + OperatingSystemMXBean os = ManagementFactory.getOperatingSystemMXBean(); Double loadAverageNow = 1.0; Double loadAverage5MinutesBefore = 1.0; Double loadAverage10MinutesBefore = 1.0; - + @Override public void run() { while (true) { @@ -108,9 +178,9 @@ } } } - - LoadAverageMonitoring monitoring; - + + LoadAverageMonitoring monitoring; + public LimitedActivity() { monitoring = new LoadAverageMonitoring(); monitoring.start(); @@ -123,13 +193,25 @@ && monitoring.loadAverage10MinutesBefore < 1.0; return canWork; } + + @Override + public long timeBeforeNextUpdate() { + return 5 * 60 * 1000; + } + + @Override + public String toString() { + return "limited activity"; + } } /** use this strategy to run a job only at fixed times of the week */ public static class ScheduledActivity implements ActivityStrategy { protected DisworkConfig config; - + + protected long timeBeforeNextUpdate = 1000L; + protected ScheduledActivity(DisworkConfig config) { this.config = config; } @@ -138,14 +220,40 @@ public boolean canWork() throws DisworkException { Date currentDate = new Date(); boolean result = false; + Date nextChange = new Date(System.currentTimeMillis() + 60 * 60 * 1000); for (CronExpression pattern : config.getSchedule()) { result = result || pattern.isSatisfiedBy(currentDate); + Date aDate = pattern.getNextInvalidTimeAfter(currentDate); + if (aDate.before(nextChange)) { + nextChange = aDate; + } + aDate = pattern.getNextValidTimeAfter(currentDate); + if (aDate.before(nextChange)) { + nextChange = aDate; + } } + timeBeforeNextUpdate = nextChange.getTime() - currentDate.getTime(); return result; } + + @Override + public long timeBeforeNextUpdate() { + return timeBeforeNextUpdate; + } + + @Override + public String toString() { + return "scheduled activity"; + } } /** return true if a job can be run */ - boolean canWork() throws DisworkException; + boolean canWork() throws DisworkException; + + /** + * + * @return time to wait before next update, -1 is never (wait definitly) + */ + long timeBeforeNextUpdate(); } \ No newline at end of file Modified: trunk/diswork-daemon/src/main/java/org/nuiton/diswork/daemon/DisworkDaemon.java =================================================================== --- trunk/diswork-daemon/src/main/java/org/nuiton/diswork/daemon/DisworkDaemon.java 2010-07-07 09:22:04 UTC (rev 98) +++ trunk/diswork-daemon/src/main/java/org/nuiton/diswork/daemon/DisworkDaemon.java 2010-07-07 14:56:36 UTC (rev 99) @@ -196,7 +196,7 @@ /** worker-manager will make the daemon accomplish jobs */ protected WorkersManager workers; - + protected HttpFrontEnd httpFrontEnd; public DisworkDaemon(DisworkConfig config) throws DisworkException { @@ -817,4 +817,36 @@ throw new DisworkException("can't read hardware infos ", e); } } + + public void activeNoActivityStrategy() throws DisworkException { + if (workers == null) { + log.warn("trying to change activy while working is disabled"); + } else { + workers.activeNoActivityStrategy(); + } + } + + public void activeUnlimitedActivityStrategy() throws DisworkException { + if (workers == null) { + log.warn("trying to change activy while working is disabled"); + } else { + workers.activeUnlimitedActivityStrategy(); + } + } + + public void activeLimitedActivityStrategy() throws DisworkException { + if (workers == null) { + log.warn("trying to change activy while working is disabled"); + } else { + workers.activeLimitedActivityStrategy(); + } + } + + public void activeScheduledActivityStrategy() throws DisworkException { + if (workers == null) { + log.warn("trying to change activy while working is disabled"); + } else { + workers.activeScheduledActivityStrategy(); + } + } } \ No newline at end of file Modified: trunk/diswork-daemon/src/main/java/org/nuiton/diswork/daemon/WorkersManager.java =================================================================== --- trunk/diswork-daemon/src/main/java/org/nuiton/diswork/daemon/WorkersManager.java 2010-07-07 09:22:04 UTC (rev 98) +++ trunk/diswork-daemon/src/main/java/org/nuiton/diswork/daemon/WorkersManager.java 2010-07-07 14:56:36 UTC (rev 99) @@ -44,6 +44,7 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.nuiton.diswork.daemon.ActivityStrategy.ActivityStrategies; import org.nuiton.diswork.fs.DisworkFileSystem; import org.nuiton.diswork.fs.DisworkFileSystemException; import org.nuiton.util.FileUtil; @@ -105,6 +106,25 @@ protected File applicationCache; + protected Boolean flag = Boolean.FALSE; + + protected final Object sem = new Object(); + + protected void updateFlag() throws DisworkException { + boolean newStatus = activityStrategy.canWork(); + if (newStatus != flag) { + synchronized (sem) { + flag = newStatus; + sem.notifyAll(); + } + } + } + + protected Boolean getFlag() throws DisworkException { + updateFlag(); + return flag; + } + /** A worker search a job and execute it. * * Jobs are found on the file-system by browsing some special directories, @@ -512,11 +532,18 @@ public void run() { while (! shouldStop) { try { - if (activityStrategy.canWork()) { - findAJobAndRunIt(); - } else { - // waiting for strategy to change state - Thread.sleep(10 * 1000); + synchronized (sem) { + if (getFlag()) { + findAJobAndRunIt(); + } else { + log.debug("sleeping until a change on flag"); + long waitTime = activityStrategy.timeBeforeNextUpdate(); + if (waitTime == -1) { + sem.wait(); + } else { + sem.wait(waitTime); + } + } } } catch (DisworkException e) { log.error("worker error " + e); @@ -535,28 +562,15 @@ } } - public WorkersManager(DisworkFileSystem fileSystem, DisworkConfig config) { + public WorkersManager(DisworkFileSystem fileSystem, DisworkConfig config) throws DisworkException { this.fileSystem = fileSystem; this.config = config; applicationCache = new File(config.getTempDirectory(), "cache"); applicationCache.mkdirs(); - // initialize activityStrategy according to config - String initialStrategy = config.getActivityStrategy(); - if ("none".equals(initialStrategy)) { - activeNoActivityStrategy(); - } else if ("unlimited".equals(initialStrategy)) { - activeUnlimitedActivityStrategy(); - } else if ("limited".equals(initialStrategy)) { - activeLimitedActivityStrategy(); - } else if ("scheduled".equals(initialStrategy)) { - activeScheduledActivityStrategy(); - } else { - log.error("wrong config directive for initial strategy" + - initialStrategy); - activeNoActivityStrategy(); - } + // initialize activityStrategy according to config + setActivityStrategy(config.getActivityStrategy()); // start as many workers as needed log.info("will start " + config.getNumberOfWorkers() + " workers"); @@ -593,16 +607,18 @@ return cachedApplicationData; } - public void stop() { + public void stop() throws DisworkException { stop(false); } - public void stop(boolean now) { + public void stop(boolean now) throws DisworkException { // asking to all threads to stop for (Worker worker : workers) { worker.shouldStop = true; } + activeNoActivityStrategy(); + FileUtil.deleteRecursively(applicationCache); if( !now ) { @@ -624,24 +640,33 @@ return activityStrategy; } - public void setActivityStrategy(ActivityStrategy activityStrategy) { + public void setActivityStrategy(ActivityStrategy activityStrategy) throws DisworkException { this.activityStrategy = activityStrategy; + log.info("swithching to " + activityStrategy); + updateFlag(); } - - public void activeNoActivityStrategy() { - setActivityStrategy(new ActivityStrategy.NoActivity()); + + public void setActivityStrategy(String activityStrategyLabel) throws DisworkException { + setActivityStrategy(ActivityStrategies.getNewInstance(config, activityStrategyLabel)); } - - public void activeUnlimitedActivityStrategy() { - setActivityStrategy(new ActivityStrategy.UnlimitedActivity()); + + public void setActivityStrategy(ActivityStrategies activityStrategies) throws DisworkException { + setActivityStrategy(ActivityStrategies.getNewInstance(config, activityStrategies)); } - - public void activeLimitedActivityStrategy() { - setActivityStrategy(new ActivityStrategy.LimitedActivity()); + + public void activeNoActivityStrategy() throws DisworkException { + setActivityStrategy(ActivityStrategies.NONE); } - - public void activeScheduledActivityStrategy() { - setActivityStrategy(new ActivityStrategy.ScheduledActivity(config)); + + public void activeUnlimitedActivityStrategy() throws DisworkException { + setActivityStrategy(ActivityStrategies.UNLIMITED); } - + + public void activeLimitedActivityStrategy() throws DisworkException { + setActivityStrategy(ActivityStrategies.LIMITED); + } + + public void activeScheduledActivityStrategy() throws DisworkException { + setActivityStrategy(ActivityStrategies.SCHEDULED); + } } \ No newline at end of file