diff --git a/deploy/java-library/check.sh b/deploy/java-library/check.sh index 38932c61..8e4c761d 100755 --- a/deploy/java-library/check.sh +++ b/deploy/java-library/check.sh @@ -142,7 +142,12 @@ candidates=$(docker exec "$neo2" cypher-shell -u neo4j -p fixturepass -d graph.d RETURN kind + " " + e.stId + " " + e.dbId + " " + replace(e.speciesName, " ", "_") ORDER BY kind, e.dbId' | tail -n +2 | tr -d '"') events=$(while read -r kind id dbid species; do - grep -q ">$dbid" "$bci/fixture/expected/$species.owl" && echo "$kind $id $dbid $species" + # The event's own database-id xref, whose comment ends with its id: not any + # numeric id (a PubMed id) that happens to match. An if, not &&: under + # pipefail a last candidate not in its file would end the script silently. + if grep -q "&ID=$dbid" "$bci/fixture/expected/$species.owl"; then + echo "$kind $id $dbid $species" + fi done <<<"$candidates" | sort -u -k1,1 | cut -d' ' -f2-) [ "$(printf '%s\n' "$events" | wc -l)" -eq 5 ] || { echo "Expected one event of each of five kinds in the fixture's files, got: $events" >&2; exit 1; } diff --git a/deploy/java-library/src/main/java/org/reactome/server/library/ExportFiles.java b/deploy/java-library/src/main/java/org/reactome/server/library/ExportFiles.java index 97f8b063..c9fda0ea 100644 --- a/deploy/java-library/src/main/java/org/reactome/server/library/ExportFiles.java +++ b/deploy/java-library/src/main/java/org/reactome/server/library/ExportFiles.java @@ -74,6 +74,8 @@ public DiagramUnavailable(String message, Throwable cause) { } private static final Logger logger = LoggerFactory.getLogger(ExportFiles.class); + private static final java.util.regex.Pattern OLD_WORK = + java.util.regex.Pattern.compile("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"); private final String kind; private final String extension; @@ -100,8 +102,16 @@ public ExportFiles(String kind, String extension, Graph graph, Converter convert this.diagrams = diagrams; this.cache = cache; this.conversions = conversions; - // Work in progress when the service last stopped, which nothing will finish + // Work in progress when the service last stopped, which nothing will finish: this export's, and any left + // in the layout before exports had a folder each (cache/tmp/{uuid}) delete(work()); + try (DirectoryStream left = Files.newDirectoryStream(cache.resolve("tmp"))) { + for (Path old : left) { + if (OLD_WORK.matcher(old.getFileName().toString()).matches()) delete(old); + } + } catch (IOException e) { + // No tmp folder yet, or none readable: nothing to clear + } } private Path work() { diff --git a/deploy/java-library/src/main/java/org/reactome/server/library/LibraryApplication.java b/deploy/java-library/src/main/java/org/reactome/server/library/LibraryApplication.java index f4995633..8c571bed 100644 --- a/deploy/java-library/src/main/java/org/reactome/server/library/LibraryApplication.java +++ b/deploy/java-library/src/main/java/org/reactome/server/library/LibraryApplication.java @@ -59,10 +59,13 @@ public Optional event(String stId) { }; } - /** The conversions at once, across every export: two, within the heap (spec 015 T069). */ + /** + * The conversions at once, across every export: two, within the heap (spec 015 T069). Fair, so a request + * waiting for a place is not overtaken by later ones of the other export. + */ @Bean public Semaphore conversions() { - return new Semaphore(2); + return new Semaphore(2, true); } @Bean diff --git a/deploy/java-library/src/test/java/org/reactome/server/library/ExportFilesTest.java b/deploy/java-library/src/test/java/org/reactome/server/library/ExportFilesTest.java index 9cecb3b9..eaefae9f 100644 --- a/deploy/java-library/src/test/java/org/reactome/server/library/ExportFilesTest.java +++ b/deploy/java-library/src/test/java/org/reactome/server/library/ExportFilesTest.java @@ -194,6 +194,16 @@ void workLeftByAStoppedServiceIsRemoved() throws Exception { assertTrue(Files.exists(others)); } + @Test + void workLeftInTheLayoutBeforeExportsHadFoldersIsRemoved() throws Exception { + Path old = Files.createDirectories(cache.resolve("tmp/0f8fad5b-d9cb-469f-a165-70867728950e")); + Files.writeString(old.resolve("R-HSA-2.sbml"), " { * deep pool, so a burst of exports cannot starve the queries the pages need, * and from each other, so one export cannot take the other's places here. The * service converts two at once across both (spec 015 T069), for its heap: a - * BioPAX file may wait there behind two SBML ones, within the headers' time. + * BioPAX file may wait there behind two SBML ones, and past the headers' time + * at the worst (T069 measured 300–310 s): the reader then gets the 503 below, + * and the service, finishing, keeps the file for the next request. */ const SBML_SHARE = deepShare(2); const BIOPAX_SHARE = deepShare(2);