Skip to content

Commit

Permalink
Fixed file handle leak in VariantCallIterator.
Browse files Browse the repository at this point in the history
Added defensive GC to SAMEvidenceSource to reduce likelihood of running out of file handles due to unfinialised htsjdk memory mapped buffers
  • Loading branch information
d-cameron committed Mar 27, 2017
1 parent 483910e commit 5d9d932
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 5 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<groupId>au.edu.wehi</groupId>
<artifactId>gridss</artifactId>
<packaging>jar</packaging>
<version>1.3.3</version>
<version>1.3.4</version>
<name>gridss</name>
<url>https://github.com/PapenfussLab/gridss</url>
<properties>
Expand Down
27 changes: 25 additions & 2 deletions src/main/java/au/edu/wehi/idsv/SAMEvidenceSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -244,14 +244,37 @@ public void ensureExtracted() throws IOException {
public CloseableIterator<DirectedEvidence> iterator(final QueryInterval interval) {
SamReader reader = getReader();
// expand query bounds as the alignment for a discordant read pair could fall before or after the breakend interval we are extracting
SAMRecordIterator it = reader.queryOverlapping(new QueryInterval[] {
new QueryInterval(interval.referenceIndex, interval.start - getMaxConcordantFragmentSize() - 1, interval.end + getMaxConcordantFragmentSize() + 1)});
SAMRecordIterator it = tryOpenReader(reader, new QueryInterval(interval.referenceIndex, interval.start - getMaxConcordantFragmentSize() - 1, interval.end + getMaxConcordantFragmentSize() + 1));
Iterator<DirectedEvidence> eit = asEvidence(it);
final BreakendSummary bsf = new BreakendSummary(interval.referenceIndex, BreakendDirection.Forward, interval.start, interval.start, interval.end);
final BreakendSummary bsb = new BreakendSummary(interval.referenceIndex, BreakendDirection.Backward, interval.start, interval.start, interval.end);
eit = Iterators.filter(eit, e -> bsf.overlaps(e.getBreakendSummary()) || bsb.overlaps(e.getBreakendSummary()));
return new AutoClosingIterator<>(eit, reader, it);
}
/**
* Attempts to open a new iterator.
*
* As htsjdk performing memory mapping internally, many open/close cycles can results in an exhaustion
* of file handles.
*
* @param reader
* @param interval
* @return
*/
private SAMRecordIterator tryOpenReader(SamReader reader, QueryInterval interval) {
SAMRecordIterator it = null;
try {
it = reader.queryOverlapping(new QueryInterval[] { interval });
} catch (Exception e) {
log.debug("Attempting to recover from query failure: ", e);
System.gc();
System.runFinalization();
System.gc();
it = reader.queryOverlapping(new QueryInterval[] { interval });
log.debug("Recovery successful");
}
return it;
}
public CloseableIterator<DirectedEvidence> iterator() {
SamReader reader = getReader();
SAMRecordIterator it = reader.iterator();
Expand Down
8 changes: 6 additions & 2 deletions src/main/java/au/edu/wehi/idsv/VariantCallIterator.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class VariantCallIterator implements CloseableIterator<VariantContextDire
private final Supplier<Iterator<DirectedEvidence>> iteratorGenerator;
private final QueryInterval filterInterval;
private Iterator<VariantContextDirectedBreakpoint> currentIterator;
private Iterator<DirectedEvidence> currentUnderlyingIterator;
private int currentDirectionOrdinal;
public VariantCallIterator(ProcessingContext processContext, Iterable<DirectedEvidence> evidence) throws InterruptedException {
this.processContext = processContext;
Expand Down Expand Up @@ -59,10 +60,12 @@ public VariantCallIterator(AggregateEvidenceSource source, QueryInterval interva
private void reinitialiseIterator() {
assert(currentIterator == null || !currentIterator.hasNext());
CloserUtil.close(currentIterator);
if (currentDirectionOrdinal >= DIRECTION_ORDER.size()) return;
CloserUtil.close(currentUnderlyingIterator);
if (currentDirectionOrdinal >= DIRECTION_ORDER.size()) return;
currentUnderlyingIterator = iteratorGenerator.get();
currentIterator = new MaximalEvidenceCliqueIterator(
processContext,
iteratorGenerator.get(),
currentUnderlyingIterator,
DIRECTION_ORDER.get(currentDirectionOrdinal).getLeft(),
DIRECTION_ORDER.get(currentDirectionOrdinal).getRight(),
idGenerator);
Expand Down Expand Up @@ -92,6 +95,7 @@ public VariantContextDirectedBreakpoint next() {
@Override
public void close() {
CloserUtil.close(currentIterator);
CloserUtil.close(currentUnderlyingIterator);
}
}

0 comments on commit 5d9d932

Please sign in to comment.