Author: bpoussin Date: 2014-05-15 12:09:19 +0200 (Thu, 15 May 2014) New Revision: 3981 Url: http://forge.codelutin.com/projects/isis-fish/repository/revisions/3981 Log: - Ajout d'un delai avant resoumission d'un job qui n'a pas pu etre execute (ex: probleme de connexion reseau) - ajout d'un message sur le job lorsqu'il est en pause - Remise en marche du bouton Pause/Reprendre de la queue de simulation - changement de traduction pour le bouton Added: trunk/src/main/java/fr/ifremer/isisfish/ui/queue/PauseButtonModel.java Modified: trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationExecutor.java trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationService.java trunk/src/main/java/fr/ifremer/isisfish/ui/queue/QueueUI.jaxx trunk/src/main/resources/i18n/isis-fish_en_GB.properties trunk/src/main/resources/i18n/isis-fish_fr_FR.properties Modified: trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationExecutor.java =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationExecutor.java 2014-05-12 08:16:17 UTC (rev 3980) +++ trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationExecutor.java 2014-05-15 10:09:19 UTC (rev 3981) @@ -27,11 +27,14 @@ import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; + import static org.nuiton.i18n.I18n.t; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -63,6 +66,9 @@ this); /** vrai si cet executor est en pause */ protected boolean pause = false; + private ReentrantLock pauseLock = new ReentrantLock(); + private Condition unpaused = pauseLock.newCondition(); + /** le nombre de thread utilise avant la pause */ protected int lastCorePoolSize; /** le simulation service qui a cree cet executor */ @@ -121,24 +127,39 @@ protected void beforeExecute(Thread t, Runnable r) { super.beforeExecute(t, r); - // en premier lieu il faut que SimulationService autorise le lancement - getSimulationService().waitAutoLaunch(); + if (r instanceof SimulationJob) { + SimulationJob job = (SimulationJob) r; - // ensuite si cet executor est en pause, on tu le thread apres avoir - // resoumis la simulation - if (isPause()) { - // on est en pause, il faut remettre la tache et tuer le thread - // un simple suspend du thread n'est pas bon, car la tache ne - // serait alors jamais executer et ce n'est pas forcement ce que - // l'on souhaite - if (r instanceof SimulationJob) { - SimulationService.getService().resubmit((SimulationJob) r); + // en premier lieu il faut que SimulationService autorise le lancement + getSimulationService().waitAutoLaunch(job); + + // wait if this executor is in pause status + pauseLock.lock(); + try { + while (isPause()) { + job.getItem().getControl().setText(t("Pause")); + unpaused.await(); + } + } catch (InterruptedException ie) { + t.interrupt(); + } finally { + pauseLock.unlock(); } - throw new RuntimeException( - t("Normal stop thread, this is not an error")); - } - if (r instanceof SimulationJob) { - SimulationJob job = (SimulationJob) r; + +// // ensuite si cet executor est en pause, on tu le thread apres avoir +// // resoumis la simulation +// if (isPause()) { +// // on est en pause, il faut remettre la tache et tuer le thread +// // un simple suspend du thread n'est pas bon, car la tache ne +// // serait alors jamais executer et ce n'est pas forcement ce que +// // l'on souhaite +// if (r instanceof SimulationJob) { +// SimulationService.getService().resubmit((SimulationJob) r); +// } +// throw new RuntimeException( +// t("Normal stop thread, this is not an error")); +// } + if (job.getLauncher() == null) { // si la tache a deja un launcher, on l'utilise sinon on lui // indique d'utilise le notre. C'est seul facon propre et sans @@ -186,19 +207,36 @@ * @param pause pause value to set */ public void setPause(boolean pause) { - boolean oldValue = this.pause; - synchronized (this) { + pauseLock.lock(); + try { + + if (this.pause == pause) { + // same state, do nothing + return; + } + boolean oldValue = this.pause; this.pause = pause; - if (this.pause) { - lastCorePoolSize = getCorePoolSize(); - setCorePoolSize(0); - } else { - setCorePoolSize(lastCorePoolSize); - // on recree tous les threads qui avait ete tue par la pause - prestartAllCoreThreads(); + if (!this.pause) { + unpaused.signalAll(); } + propertyListeners.firePropertyChange("pause", oldValue, pause); + } finally { + pauseLock.unlock(); } - propertyListeners.firePropertyChange("pause", oldValue, this.pause); + +// boolean oldValue = this.pause; +// synchronized (this) { +// this.pause = pause; +// if (this.pause) { +// lastCorePoolSize = getCorePoolSize(); +// setCorePoolSize(0); +// } else { +// setCorePoolSize(lastCorePoolSize); +// // on recree tous les threads qui avait ete tue par la pause +// prestartAllCoreThreads(); +// } +// } +// propertyListeners.firePropertyChange("pause", oldValue, this.pause); } } Modified: trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationService.java =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationService.java 2014-05-12 08:16:17 UTC (rev 3980) +++ trunk/src/main/java/fr/ifremer/isisfish/simulator/launcher/SimulationService.java 2014-05-15 10:09:19 UTC (rev 3981) @@ -346,12 +346,15 @@ /** * Permet de mettre en attente les threads de simulation si l'utilisateur * a suspendu la queue + * + * @param job le job pour lequel on vu savoir s'il faut l'executer ou non */ - protected void waitAutoLaunch() { + protected void waitAutoLaunch(SimulationJob job) { synchronized (this) { while (!isAutoLaunch()) { try { log.info("autoLaunch is false waiting queue start"); + job.getItem().getControl().setText(t("Pause")); this.wait(); } catch (InterruptedException eee) { log.warn("Error during wait autoLaunch flag", eee); @@ -655,6 +658,8 @@ } /** + * This method must be call in thread simulation + * * Report une erreur pour un launcher, on resoumet le job en supprimant * le launcher utilise * @@ -676,6 +681,12 @@ // FIXME: est ce le bon choix si l'utilisateur avait force un launcher particulier, ne faudrait t'il pas prevenir l'utilisateur ? // FIXME: disabled since caparmor is not our friend. Retry on caparmor in the limit of 50 errors //job.setLauncher(null); + try { + // not resubmit immediatly, wait some time (max 10 min and about 4,2 hours in total) + Thread.sleep(i.intValue() / 5 * 60 * 1000); + } catch (InterruptedException eee) { + log.info("Can't sleep before resubmit job, never mind", eee); + } resubmit(job); } Added: trunk/src/main/java/fr/ifremer/isisfish/ui/queue/PauseButtonModel.java =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/ui/queue/PauseButtonModel.java (rev 0) +++ trunk/src/main/java/fr/ifremer/isisfish/ui/queue/PauseButtonModel.java 2014-05-15 10:09:19 UTC (rev 3981) @@ -0,0 +1,71 @@ +package fr.ifremer.isisfish.ui.queue; + + +import fr.ifremer.isisfish.simulator.launcher.SimulationExecutor; +import fr.ifremer.isisfish.simulator.launcher.SimulationService; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.JToggleButton.ToggleButtonModel; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class PauseButtonModel extends ToggleButtonModel implements PropertyChangeListener, ItemListener { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(PauseButtonModel.class); + private static final long serialVersionUID = 1L; + + protected SimulationService service; + final static private String servicePropertyName = "autoLaunch"; + final static private String executorPropertyName = "pause"; + + public PauseButtonModel(SimulationService service) { + this.service = service; + + boolean b = service.isAutoLaunch(); + service.addPropertyChangeListener(servicePropertyName, this); + + for (SimulationExecutor e : service.getSimulationExecutors()) { + b = b && !e.isPause(); + e.addPropertyChangeListener(executorPropertyName, this); + } + + setSelected(b); + + addItemListener(this); + } + + // event from service or executor, change button + @Override + public void propertyChange(PropertyChangeEvent event) { + boolean b = (Boolean)event.getNewValue(); + setSelected(b); + } + + // event from button, change model + @Override + public void itemStateChanged(ItemEvent event) { + boolean b = event.getStateChange() == ItemEvent.SELECTED; + service.setAutoLaunch(b); + // if pause asked, (b == false) only service can be put in autoLaunch = false + // executor see this autoLaunch value. + // if resume asked (b == true), we must ensure that all executer are resume too + if (b) { + for (SimulationExecutor e : service.getSimulationExecutors()) { + e.resume(); + } + } + } + + +} Property changes on: trunk/src/main/java/fr/ifremer/isisfish/ui/queue/PauseButtonModel.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Modified: trunk/src/main/java/fr/ifremer/isisfish/ui/queue/QueueUI.jaxx =================================================================== --- trunk/src/main/java/fr/ifremer/isisfish/ui/queue/QueueUI.jaxx 2014-05-12 08:16:17 UTC (rev 3980) +++ trunk/src/main/java/fr/ifremer/isisfish/ui/queue/QueueUI.jaxx 2014-05-15 10:09:19 UTC (rev 3981) @@ -46,6 +46,7 @@ <SimulationServiceTableModel id="newSimulationModel" javaBean='new SimulationServiceTableModel(SimulationService.getService(), true)'/> <SimulationServiceTableModel id="doneSimulationModel" javaBean='new SimulationServiceTableModel(SimulationService.getService(), false)' onTableChanged='queueAction.updateActions()' /> + <PauseButtonModel id="autoLaunchButtonModel" javaBean='new PauseButtonModel(SimulationService.getService())'/> <DefaultListSelectionModel id="selectionModelQueueTable" onValueChanged='queueAction.updateActions()'/> <DefaultListSelectionModel id="selectionModelQueueTableDone" onValueChanged='queueAction.updateActions()'/> @@ -68,7 +69,7 @@ </row> <row> <cell fill="horizontal" weightx="0.3"> - <JToggleButton id="autoLaunchButton" text="isisfish.queue.simulationLaunch"/> + <JToggleButton id="autoLaunchButton" text="isisfish.queue.simulationLaunch" model="{autoLaunchButtonModel}"/> </cell> <cell fill="horizontal" weightx="0.3"> <JButton id="stopSimuButton" text="isisfish.queue.stopSimulation" onActionPerformed='queueAction.stopSimulation()' enabled='{isCanStop()}' /> Modified: trunk/src/main/resources/i18n/isis-fish_en_GB.properties =================================================================== --- trunk/src/main/resources/i18n/isis-fish_en_GB.properties 2014-05-12 08:16:17 UTC (rev 3980) +++ trunk/src/main/resources/i18n/isis-fish_en_GB.properties 2014-05-15 10:09:19 UTC (rev 3981) @@ -45,6 +45,7 @@ No\ port\ cell= Normal\ stop\ thread,\ this\ is\ not\ an\ error= Not\ start\ simulation\ %s\ because\ user\ ask\ stop= +Pause= Process\ template\ error= QUnif\ %= QUnif\ Min/Max= @@ -811,7 +812,7 @@ isisfish.queue.progression=Progress isisfish.queue.restartSimulation=Restart isisfish.queue.showLog=Show simulation log -isisfish.queue.simulationLaunch=Simulation queue launch +isisfish.queue.simulationLaunch=Pause / Resume isisfish.queue.status=Status isisfish.queue.stopSimulation=Stop simulation isisfish.queue.title=Queue Modified: trunk/src/main/resources/i18n/isis-fish_fr_FR.properties =================================================================== --- trunk/src/main/resources/i18n/isis-fish_fr_FR.properties 2014-05-12 08:16:17 UTC (rev 3980) +++ trunk/src/main/resources/i18n/isis-fish_fr_FR.properties 2014-05-15 10:09:19 UTC (rev 3981) @@ -45,6 +45,7 @@ No\ port\ cell= Normal\ stop\ thread,\ this\ is\ not\ an\ error= Not\ start\ simulation\ %s\ because\ user\ ask\ stop= +Pause= Process\ template\ error= QUnif\ %= QUnif\ Min/Max= @@ -806,7 +807,7 @@ isisfish.queue.progression=Progression isisfish.queue.restartSimulation=Redémarrer isisfish.queue.showLog=Voir les logs de la simulation -isisfish.queue.simulationLaunch=Lanceur de la queue des simulations +isisfish.queue.simulationLaunch=Pause / Reprendre isisfish.queue.status=État isisfish.queue.stopSimulation=Arrêter la simulation isisfish.queue.title=Queue