prevent parallel plot requests

Plotting can take a long time and use a lot of resources. 
Multiple plot requests can cause the machine to run OOM.

We are now allowing plots for 500k files again. This is mainly to
prevent unwanted plots of everything.
This commit is contained in:
ahr
2017-12-15 17:20:12 +01:00
parent 8d48726472
commit d63fabc85d
3 changed files with 40 additions and 11 deletions

View File

@@ -10,6 +10,7 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.concurrent.locks.ReentrantLock;
import org.lucares.pdb.datastore.Proposal; import org.lucares.pdb.datastore.Proposal;
import org.lucares.pdb.plot.api.PlotSettings; import org.lucares.pdb.plot.api.PlotSettings;
@@ -51,6 +52,8 @@ public class PdbController implements HardcodedValues {
private final Plotter plotter; private final Plotter plotter;
private final PerformanceDb db; private final PerformanceDb db;
private final ReentrantLock plotterLock = new ReentrantLock();
public PdbController(final PerformanceDb db, final Plotter plotter) { public PdbController(final PerformanceDb db, final Plotter plotter) {
this.db = db; this.db = db;
this.plotter = plotter; this.plotter = plotter;
@@ -71,20 +74,32 @@ public class PdbController implements HardcodedValues {
produces = MediaType.APPLICATION_JSON_UTF8_VALUE // produces = MediaType.APPLICATION_JSON_UTF8_VALUE //
) )
@ResponseBody @ResponseBody
PlotResponse createPlot(@RequestBody final PlotRequest request) throws InternalPlottingException { PlotResponse createPlot(@RequestBody final PlotRequest request)
throws InternalPlottingException, InterruptedException {
final PlotSettings plotSettings = PlotSettingsTransformer.toSettings(request); final PlotSettings plotSettings = PlotSettingsTransformer
.toSettings(request);
try { // TODO the UI should cancel requests that are in flight before sending a plot request
final PlotResult result = plotter.plot(plotSettings); if (plotterLock.tryLock()) {
try {
final PlotResult result = plotter.plot(plotSettings);
final String imageUrl = WEB_IMAGE_OUTPUT_PATH + "/" + result.getImageName(); final String imageUrl = WEB_IMAGE_OUTPUT_PATH + "/"
LOGGER.trace("image url: {}", imageUrl); + result.getImageName();
System.gc(); LOGGER.trace("image url: {}", imageUrl);
System.gc();
return new PlotResponse(DataSeries.toMap(result.getDataSeries()), imageUrl); return new PlotResponse(
} catch (final NoDataPointsException e) { DataSeries.toMap(result.getDataSeries()), imageUrl);
throw new NotFoundException(e); } catch (final NoDataPointsException e) {
throw new NotFoundException(e);
} finally {
plotterLock.unlock();
}
} else {
throw new ServiceUnavailableException("Too many parallel requests!");
} }
} }

View File

@@ -0,0 +1,14 @@
package org.lucares.pdbui;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value = HttpStatus.SERVICE_UNAVAILABLE, reason = "Service Unavailable")
public class ServiceUnavailableException extends RuntimeException {
private static final long serialVersionUID = -4512668277873760500L;
public ServiceUnavailableException(String message) {
super(message);
}
}

View File

@@ -80,7 +80,7 @@ public class TagsToFile implements AutoCloseable {
final List<PdbFile> result = new ArrayList<>(); final List<PdbFile> result = new ArrayList<>();
final List<Doc> searchResult = db.search(query); final List<Doc> searchResult = db.search(query);
if (searchResult.size() > 100_000){ if (searchResult.size() > 500_000){
throw new IllegalStateException("Too many results."); throw new IllegalStateException("Too many results.");
} }