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:
@@ -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!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user