Skip to content

Commit

Permalink
Implement the capacity to stop realtime after a defined duration
Browse files Browse the repository at this point in the history
  • Loading branch information
surli committed Mar 14, 2018
1 parent a9ae729 commit 8a56b9e
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package fr.inria.spirals.repairnator;

import com.martiansoftware.jsap.ParseException;
import com.martiansoftware.jsap.StringParser;

import java.time.Duration;
import java.time.format.DateTimeParseException;

public class PeriodStringParser extends StringParser {
private static PeriodStringParser instance;

private PeriodStringParser() {}

public static PeriodStringParser getParser() {
if (instance == null) {
instance = new PeriodStringParser();
}
return instance;
}

@Override
public Object parse(String s) throws ParseException {
try {
return Duration.parse(s);
} catch (DateTimeParseException e) {
throw new ParseException(e);
} catch (NullPointerException e) {
throw new ParseException("No period given to parse");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,17 @@ public void submitBuild(Build build) {
}
}

public void switchOff() {
LOGGER.warn("The process will now stop. "+this.getRunning()+" docker containers will be stopped.");
this.waitingBuilds.clear();
for (RunnablePipelineContainer container : this.submittedRunnablePipelineContainers) {
container.serialize("ABORT");
container.killDockerContainer(this.getDockerClient(), false);
}

this.executorService.shutdownNow();
}

@Override
public void removeSubmittedRunnablePipelineContainer(RunnablePipelineContainer pipelineContainer) {
LOGGER.info("Build (id: "+pipelineContainer.getBuildId()+") has finished.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class InspectBuilds implements Runnable {
private int sleepTime;
private int maxSubmittedBuilds;
private WatchedBuildSerializer watchedBuildSerializer;
private boolean shouldStop;

public InspectBuilds(RTScanner rtScanner) {
this.rtScanner = rtScanner;
Expand All @@ -32,6 +33,10 @@ public InspectBuilds(RTScanner rtScanner) {
this.watchedBuildSerializer = new WatchedBuildSerializer(this.rtScanner.getEngines(), this.rtScanner);
}

public void switchOff() {
this.shouldStop = true;
}

public void setSleepTime(int sleepTime) {
this.sleepTime = sleepTime;
}
Expand Down Expand Up @@ -68,7 +73,7 @@ public void run() {
if (this.sleepTime == -1) {
throw new RuntimeException("You must set sleepTime before running this.");
}
while (true) {
while (!this.shouldStop) {
LOGGER.info("Refresh all inspected build status (nb builds: "+this.nbSubmittedBuilds+")");
for (Build build : this.waitingBuilds) {
build.refreshStatus();
Expand Down Expand Up @@ -96,5 +101,6 @@ public void run() {
e.printStackTrace();
}
}
LOGGER.info("This will now stop.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class InspectJobs implements Runnable {
public static final int JOB_SLEEP_TIME = 60;
private RTScanner rtScanner;
private int sleepTime;
private boolean shouldStop;

public InspectJobs(RTScanner scanner) {
this.rtScanner = scanner;
Expand All @@ -23,13 +24,17 @@ public void setSleepTime(int sleepTime) {
this.sleepTime = sleepTime;
}

public void switchOff() {
this.shouldStop = true;
}

@Override
public void run() {
LOGGER.debug("Start running inspect Jobs...");
if (sleepTime == -1) {
throw new RuntimeException("Sleep time has to be set before running this.");
}
while (true) {
while (!shouldStop) {
List<Job> jobList = JobHelper.getJobList();

if (jobList != null) {
Expand All @@ -49,5 +54,6 @@ public void run() {
}
}
}
LOGGER.info("This will now stop.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package fr.inria.spirals.repairnator.realtime;

import fr.inria.spirals.repairnator.notifier.EndProcessNotifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.Duration;
import java.time.Instant;
import java.util.Date;

public class InspectProcessDuration implements Runnable {
private static final Logger LOGGER = LoggerFactory.getLogger(InspectProcessDuration.class);
private static final int SLEEP_TIME = 10; // seconds

private Duration duration;
private EndProcessNotifier endProcessNotifier;
private InspectBuilds inspectBuilds;
private InspectJobs inspectJobs;
private BuildRunner buildRunner;

public InspectProcessDuration(Duration duration, InspectBuilds inspectBuilds, InspectJobs inspectJobs, BuildRunner buildRunner, EndProcessNotifier endProcessNotifier) {
this(duration, inspectBuilds, inspectJobs, buildRunner);
this.endProcessNotifier = endProcessNotifier;
}

public InspectProcessDuration(Duration duration, InspectBuilds inspectBuilds, InspectJobs inspectJobs, BuildRunner buildRunner) {
this.duration = duration;
this.inspectBuilds = inspectBuilds;
this.inspectJobs = inspectJobs;
this.buildRunner = buildRunner;
}

@Override
public void run() {
Instant endOfProcessDate = new Date().toInstant().plus(duration);
LOGGER.info("The process will finish at: " + endOfProcessDate);

while (!new Date().toInstant().isAfter(endOfProcessDate)) {
try {
Thread.sleep(SLEEP_TIME * 1000);
} catch (InterruptedException e) {
LOGGER.warn("Sleep interrupted: premature stop will occured.");
}
}

LOGGER.info("The process will now stop.");
this.inspectBuilds.switchOff();
this.inspectJobs.switchOff();
this.buildRunner.switchOff();

if (this.endProcessNotifier != null) {
this.endProcessNotifier.notifyEnd();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.martiansoftware.jsap.stringparsers.FileStringParser;
import fr.inria.spirals.repairnator.LauncherType;
import fr.inria.spirals.repairnator.LauncherUtils;
import fr.inria.spirals.repairnator.PeriodStringParser;
import fr.inria.spirals.repairnator.config.RepairnatorConfig;
import fr.inria.spirals.repairnator.notifier.EndProcessNotifier;
import fr.inria.spirals.repairnator.notifier.engines.NotifierEngine;
Expand All @@ -16,6 +17,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;

Expand Down Expand Up @@ -109,6 +111,13 @@ private void defineArgs() throws JSAPException {
opt2.setDefault(InspectBuilds.LIMIT_SUBMITTED_BUILDS+"");
opt2.setHelp("Specify the maximum number of watched builds");
this.jsap.registerParameter(opt2);

opt2 = new FlaggedOption("duration");
opt2.setLongFlag("duration");
opt2.setShortFlag('d');
opt2.setStringParser(PeriodStringParser.getParser());
opt2.setHelp("Duration of the execution. If not given, the execution never stop. This argument should be given on the ISO-8601 duration format: PWdTXhYmZs where W, X, Y, Z respectively represents number of Days, Hours, Minutes and Seconds. T is mandatory before the number of hours and P is always mandatory.");
this.jsap.registerParameter(opt2);
}

private void initConfig() {
Expand Down Expand Up @@ -155,6 +164,14 @@ private void initAndRunRTScanner() {
rtScanner.getInspectBuilds().setSleepTime(this.arguments.getInt("buildsleeptime"));
rtScanner.getInspectJobs().setSleepTime(this.arguments.getInt("jobsleeptime"));

if (this.arguments.getObject("duration") != null) {
rtScanner.setDuration((Duration) this.arguments.getObject("duration"));

if (this.endProcessNotifier != null) {
rtScanner.setEndProcessNotifier(this.endProcessNotifier);
}
}

LOGGER.info("Init build runner");
BuildRunner buildRunner = rtScanner.getBuildRunner();
buildRunner.setDockerOutputDir(LauncherUtils.getArgLogDirectory(this.arguments));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import fr.inria.jtravis.entities.Repository;
import fr.inria.jtravis.helpers.BuildHelper;
import fr.inria.jtravis.helpers.RepositoryHelper;
import fr.inria.spirals.repairnator.notifier.EndProcessNotifier;
import fr.inria.spirals.repairnator.realtime.serializer.BlacklistedSerializer;
import fr.inria.spirals.repairnator.serializer.engines.SerializerEngine;
import org.slf4j.Logger;
Expand All @@ -16,6 +17,7 @@
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
Expand All @@ -38,6 +40,8 @@ public class RTScanner {
private String runId;
private List<SerializerEngine> engines;
private BlacklistedSerializer blacklistedSerializer;
private Duration duration;
private EndProcessNotifier endProcessNotifier;

public RTScanner(String runId, List<SerializerEngine> engines) {
this.engines = engines;
Expand All @@ -51,6 +55,14 @@ public RTScanner(String runId, List<SerializerEngine> engines) {
this.blacklistedSerializer = new BlacklistedSerializer(this.engines, this);
}

public void setDuration(Duration duration) {
this.duration = duration;
}

public void setEndProcessNotifier(EndProcessNotifier endProcessNotifier) {
this.endProcessNotifier = endProcessNotifier;
}

public List<SerializerEngine> getEngines() {
return engines;
}
Expand Down Expand Up @@ -111,6 +123,17 @@ public void launch() {
new Thread(this.inspectBuilds).start();
new Thread(this.inspectJobs).start();
this.running = true;

if (this.duration != null) {
InspectProcessDuration inspectProcessDuration;
if (this.endProcessNotifier != null) {
inspectProcessDuration = new InspectProcessDuration(this.duration, this.inspectBuilds, this.inspectJobs, this.buildRunner, this.endProcessNotifier);
} else {
inspectProcessDuration = new InspectProcessDuration(this.duration, this.inspectBuilds, this.inspectJobs, this.buildRunner);
}

new Thread(inspectProcessDuration).start();
}
}
}

Expand Down

0 comments on commit 8a56b9e

Please sign in to comment.