# HG changeset patch # User Ingo Weinzierl # Date 1314969125 0 # Node ID 6b9877a9f6c16e011a833c78880271d7463cb8f1 # Parent da4d8631fc468eabb6e957f5f5aa886d184fb82f Added infrastructure to start WSPLGEN calculations - the FloodMapState already start such calculations. flys-artifacts/trunk@2639 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r da4d8631fc46 -r 6b9877a9f6c1 flys-artifacts/ChangeLog --- a/flys-artifacts/ChangeLog Fri Sep 02 12:57:08 2011 +0000 +++ b/flys-artifacts/ChangeLog Fri Sep 02 13:12:05 2011 +0000 @@ -1,3 +1,28 @@ +2011-09-02 Ingo Weinzierl + + * src/main/java/de/intevation/flys/wsplgen/JobExecutor.java: New. This + class is used to start WSPLGEN for a specific WSPLGENJob. The System + property "wsplgen.bin.path" tells the JobExecutor where the WSPLGEN + binary is placed (which means in general, the property points to the + 'wsplgen.exe'). + + * src/main/java/de/intevation/flys/wsplgen/Scheduler.java: New. This + scheduler currently allows to start just a single WSPLGEN Thread. All + WSPLGEN calculations should be started using Scheduler.addJob(). + + * src/main/java/de/intevation/flys/wsplgen/JobObserver.java: New. This + thread reads log messages from WSPLGEN and listens for specific + messages. It should be used to update status messages of the WSPLGEN + calculation that is currently running. + There is a System property that tells the JobObserver to log all WSPLGEN + output to log4j: enable WSPLGEN output with "-Dwsplgen.log.output=true". + + * src/main/java/de/intevation/flys/artifacts/model/WSPLGENJob.java: Added + the FLYSArtifact, the current working directory and the CallContext. + + * src/main/java/de/intevation/flys/artifacts/states/FloodMapState.java: + Use the Scheduler to start new WSPLGEN calculations. + 2011-09-02 Felix Wolfsteller Add CrossSectionInfoGenerator. diff -r da4d8631fc46 -r 6b9877a9f6c1 flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WSPLGENJob.java --- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WSPLGENJob.java Fri Sep 02 12:57:08 2011 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WSPLGENJob.java Fri Sep 02 13:12:05 2011 +0000 @@ -8,6 +8,10 @@ import java.util.ArrayList; import java.util.List; +import de.intevation.artifacts.CallContext; + +import de.intevation.flys.artifacts.FLYSArtifact; + public class WSPLGENJob { @@ -15,6 +19,12 @@ public static final String GEL_NOSPERRE = "NOSPERRE"; + protected FLYSArtifact artifact; + + protected CallContext callContext; + + protected File workingDir; + protected String dgm; protected String pro; protected String wsp; @@ -37,7 +47,11 @@ - public WSPLGENJob() { + public WSPLGENJob(FLYSArtifact flys, File workingDir, CallContext context) { + this.artifact = flys; + this.workingDir = workingDir; + this.callContext = callContext; + out = -1; start = Double.NaN; end = Double.NaN; @@ -49,6 +63,16 @@ } + public File getWorkingDir() { + return workingDir; + } + + + public CallContext getCallContext() { + return callContext; + } + + public void setWsp(String wsp) { this.wsp = wsp; } diff -r da4d8631fc46 -r 6b9877a9f6c1 flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/FloodMapState.java --- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/FloodMapState.java Fri Sep 02 12:57:08 2011 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/FloodMapState.java Fri Sep 02 13:12:05 2011 +0000 @@ -47,6 +47,7 @@ import de.intevation.flys.exports.WstWriter; import de.intevation.flys.utils.FLYSUtils; import de.intevation.flys.utils.GeometryUtils; +import de.intevation.flys.wsplgen.Scheduler; public class FloodMapState @@ -110,6 +111,9 @@ return null; } + Scheduler scheduler = Scheduler.getInstance(); + scheduler.addJob(job); + facets.add(new WSPLGENFacet(0, FLOODMAP_WSPLGEN, "WSPLGEN")); //context.afterCall(CallContext.BACKGROUND); @@ -184,7 +188,7 @@ ) { logger.debug("FloodMapState.prepareWSPLGENJob"); - WSPLGENJob job = new WSPLGENJob(); + WSPLGENJob job = new WSPLGENJob(artifact, artifactDir, context); File paraFile = new File(artifactDir, WSPLGEN_PARAMETER_FILE); setOut(artifact, job); diff -r da4d8631fc46 -r 6b9877a9f6c1 flys-artifacts/src/main/java/de/intevation/flys/wsplgen/JobExecutor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/wsplgen/JobExecutor.java Fri Sep 02 13:12:05 2011 +0000 @@ -0,0 +1,96 @@ +package de.intevation.flys.wsplgen; + +import java.io.InputStream; +import java.io.IOException; +import java.io.File; + +import org.apache.log4j.Logger; + +import de.intevation.flys.artifacts.model.WSPLGENJob; + + +public class JobExecutor { + + public static final String WSPLGEN_PARAMETER_FILE = + "wsplgen.par"; + + public static final String WSPLGEN_BIN_PATH = + System.getProperty("wsplgen.bin.path"); + + + private Logger logger = Logger.getLogger(JobExecutor.class); + + private Process process; + + protected WSPLGENJob job; + + protected JobObserver observer; + + + public JobExecutor(WSPLGENJob job) { + this.job = job; + this.observer = new JobObserver(job); + } + + + public void execute() { + File dir = job.getWorkingDir(); + File parameter = new File(dir, WSPLGEN_PARAMETER_FILE); + + String[] args = new String[] { + WSPLGEN_BIN_PATH, + "-PAR=\"" + parameter.getAbsolutePath() + "\"" + }; + + execute(args, dir, observer); + } + + + public void execute(String[] args, File dir, JobObserver observer) { + logger.info("Start JobExecutor for artifact: " + dir.getName()); + + String errorMsg = null; + + try { + synchronized (this) { + process = Runtime.getRuntime().exec(args, null, dir); + + InputStream out = process.getInputStream(); + observer.setInputStream(out); + + observer.start(); + + try { + process.waitFor(); + } + catch (InterruptedException ie) { + logger.error("WSPLGEN job interrupted: " + ie.getMessage()); + } + + try { + observer.join(); + } + catch (InterruptedException iee) { /* do nothing */ } + + logger.info("WSPLGEN exit value: " + process.exitValue()); + + return; + } + } + catch (SecurityException se) { + errorMsg = se.getMessage(); + } + catch (IOException ioe) { + errorMsg = ioe.getMessage(); + } + catch (NullPointerException npe) { + errorMsg = npe.getMessage(); + } + catch (IndexOutOfBoundsException ioobe) { + errorMsg = ioobe.getMessage(); + } + + logger.error("An error occured while starting WSPLGEN: " + errorMsg); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : diff -r da4d8631fc46 -r 6b9877a9f6c1 flys-artifacts/src/main/java/de/intevation/flys/wsplgen/JobObserver.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/wsplgen/JobObserver.java Fri Sep 02 13:12:05 2011 +0000 @@ -0,0 +1,102 @@ +package de.intevation.flys.wsplgen; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.log4j.Logger; + +import de.intevation.flys.artifacts.model.WSPLGENJob; + + +public class JobObserver extends Thread { + + private static Logger logger = Logger.getLogger(JobObserver.class); + + + public static final String WSPLGEN_ENCODING = + "ISO-8859-1"; + + public static final String WSPLGEN_LOG_OUTPUT = + System.getProperty("wsplgen.log.output", "false"); + + public static final String[] STEPS = { + ".*<-Auswertung der Kommandozeilen-Parameter beendet.*", + ".*->Laden des DGM in Datei '.*' gestartet.*", + ".*->Triangulierung der Knoten gestartet.*", + ".*->Anpassung der Elemente an Dämme und Gräben gestartet.*", + ".*<-WSPLGEN Version .* beendet.*" + }; + + + protected WSPLGENJob job; + + protected InputStream in; + + protected Pattern[] patterns; + + protected int len; + + protected boolean copy; + + + public JobObserver(WSPLGENJob job) { + this.job = job; + this.len = 0; + this.copy = Boolean.parseBoolean(WSPLGEN_LOG_OUTPUT); + + patterns = new Pattern[STEPS.length]; + + prepareRegexes(); + } + + + private void prepareRegexes() { + for (int num = STEPS.length, i = 0; i < num; i++) { + patterns[i] = Pattern.compile(STEPS[i]); + } + } + + + public void setInputStream(InputStream in) { + this.in = in; + } + + + public void run() { + try { + + BufferedReader reader = + new BufferedReader( + new InputStreamReader(in, WSPLGEN_ENCODING)); + + String line = null; + + while ((line = reader.readLine()) != null) { + if (copy) { + logger.debug(line); + } + + update(line); + } + } + catch (IOException ioe) { + logger.warn("Observation canceled: " + ioe.getMessage()); + } + } + + + protected void update(String log) { + for (int num = patterns.length, i = 0; i < num; i++) { + Matcher m = patterns[i].matcher(log); + + if (m.matches()) { + logger.info("Finished step " + (i+1) + " / " + num); + } + } + } +} +// vim:set ts=4 sw=4 si et sta sts=5 fenc=utf-8 : diff -r da4d8631fc46 -r 6b9877a9f6c1 flys-artifacts/src/main/java/de/intevation/flys/wsplgen/Scheduler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/wsplgen/Scheduler.java Fri Sep 02 13:12:05 2011 +0000 @@ -0,0 +1,109 @@ +package de.intevation.flys.wsplgen; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +import org.apache.log4j.Logger; + +import de.intevation.flys.artifacts.model.WSPLGENJob; + + +public class Scheduler implements Runnable { + + public static final int MAX_WSPLGEN_PROCESSES = 1; + + + protected List jobs; + + + private static Scheduler INSTANCE; + + private static final Logger logger = Logger.getLogger(Scheduler.class); + + + + private Scheduler() { + jobs = Collections.synchronizedList(new LinkedList()); + } + + + public static Scheduler getInstance() { + if (INSTANCE == null) { + logger.info("Create new WSPLGEN Scheduler..."); + + INSTANCE = new Scheduler(); + new Thread(INSTANCE).start(); + } + + return INSTANCE; + } + + + public void addJob(WSPLGENJob job) { + synchronized(jobs) { + jobs.add(job); + + logger.info("New WSPLGEN job added."); + + jobs.notifyAll(); + } + } + + + public WSPLGENJob getJob() { + synchronized(jobs) { + if (!jobs.isEmpty()) { + return jobs.remove(0); + } + + return null; + } + } + + + public void run() { + logger.info("WSPLGEN Scheduler started."); + + for (;;) { + try { + doRun(); + } + catch (InterruptedException ie) { + logger.warn("Interrupt in WSPLGEN Scheduler -> restart it!"); + } + } + } + + + public void doRun() + throws InterruptedException + { + for (;;) { + final WSPLGENJob job = getJob(); + + if (job != null) { + logger.debug("Got new job to execute..."); + + Thread t = new Thread() { + public void run() { + JobExecutor executor = new JobExecutor(job); + executor.execute(); + } + }; + + t.start(); + t.join(); + } + else { + logger.info("No more jobs in Scheduler -> go sleep!"); + synchronized (jobs) { + jobs.wait(); + } + + logger.info("New jobs in Scheduler -> wake up!"); + } + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :