Skip to content

Commit 7bedd18

Browse files
committed
[bugfix] RestXQ was not releasing file handles on Binary Files accessed in Resource Functions
1 parent be03944 commit 7bedd18

File tree

3 files changed

+38
-17
lines changed

3 files changed

+38
-17
lines changed

extensions/exquery/restxq/src/main/java/org/exist/extensions/exquery/restxq/impl/ResourceFunctionExecutorImpl.java

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,7 @@
5050
import org.exist.storage.DBBroker;
5151
import org.exist.storage.ProcessMonitor;
5252
import org.exist.xmldb.XmldbURI;
53-
import org.exist.xquery.AbstractExpression;
54-
import org.exist.xquery.AnalyzeContextInfo;
55-
import org.exist.xquery.CompiledXQuery;
56-
import org.exist.xquery.Expression;
57-
import org.exist.xquery.FunctionCall;
58-
import org.exist.xquery.UserDefinedFunction;
59-
import org.exist.xquery.VariableDeclaration;
60-
import org.exist.xquery.XPathException;
61-
import org.exist.xquery.XQueryContext;
53+
import org.exist.xquery.*;
6254
import org.exist.xquery.util.ExpressionDumper;
6355
import org.exist.xquery.value.AnyURIValue;
6456
import org.exist.xquery.value.AtomicValue;
@@ -175,7 +167,17 @@ public Sequence execute(final ResourceFunction resourceFunction, final Iterable<
175167
try {
176168
effectiveSubject.ifPresent(broker::pushSubject); //switch to effective user if setUid/setGid
177169
final org.exist.xquery.value.Sequence result = fnRef.evalFunction(null, null, fnArgs);
178-
return new SequenceAdapter(result);
170+
171+
// copy for closure
172+
final CompiledXQuery xquery1 = xquery;
173+
174+
// return a sequence adapter which returns the query when it is finished with the results
175+
return new SequenceAdapter(result, () -> {
176+
if (xquery1 != null) {
177+
//return the compiled query to the pool
178+
cache.returnCompiledQuery(resourceFunction.getXQueryLocation(), xquery1);
179+
}
180+
});
179181
} finally {
180182
//switch back from effective user if setUid/setGid
181183
if (effectiveSubject.isPresent()) {
@@ -185,19 +187,20 @@ public Sequence execute(final ResourceFunction resourceFunction, final Iterable<
185187
}
186188

187189
} catch(final URISyntaxException | EXistException | XPathException | PermissionDeniedException use) {
190+
191+
// if an error occurred we should return the compiled query
192+
if(xquery != null) {
193+
//return the compiled query to the pool
194+
cache.returnCompiledQuery(resourceFunction.getXQueryLocation(), xquery);
195+
}
196+
188197
throw new RestXqServiceException(use.getMessage(), use);
189198
} finally {
190-
191199
//clear down monitoring
192200
if(processMonitor != null) {
193201
xquery.getContext().getProfiler().traceQueryEnd(xquery.getContext());
194202
processMonitor.queryCompleted(xquery.getContext().getWatchDog());
195203
}
196-
197-
if(xquery != null) {
198-
//return the compiled query to the pool
199-
cache.returnCompiledQuery(resourceFunction.getXQueryLocation(), xquery);
200-
}
201204
}
202205
}
203206

extensions/exquery/restxq/src/main/java/org/exist/extensions/exquery/restxq/impl/RestXqServiceCompiledXQueryCacheImpl.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ public CompiledXQuery getCompiledQuery(final DBBroker broker, final URI xqueryLo
9292
@Override
9393
public void returnCompiledQuery(final URI xqueryLocation, final CompiledXQuery xquery) {
9494
//reset the query and context
95+
xquery.getContext().runCleanupTasks();
9596
xquery.reset();
9697
xquery.getContext().reset();
9798

extensions/exquery/restxq/src/main/java/org/exist/extensions/exquery/restxq/impl/adapters/SequenceAdapter.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
package org.exist.extensions.exquery.restxq.impl.adapters;
2828

2929
import java.util.Iterator;
30+
31+
import com.evolvedbinary.j8fu.function.RunnableE;
3032
import org.apache.logging.log4j.LogManager;
3133
import org.apache.logging.log4j.Logger;
3234
import org.exist.dom.persistent.NodeProxy;
@@ -37,6 +39,8 @@
3739
import org.exquery.xquery.Type;
3840
import org.exquery.xquery.TypedValue;
3941

42+
import javax.annotation.Nullable;
43+
4044
/**
4145
*
4246
* @author Adam Retter <[email protected]>
@@ -46,9 +50,15 @@ public class SequenceAdapter implements Sequence<Item> {
4650
private final static Logger LOG = LogManager.getLogger(SequenceAdapter.class);
4751

4852
private final org.exist.xquery.value.Sequence sequence;
53+
@Nullable private final RunnableE<SequenceException> closer;
4954

5055
public SequenceAdapter(final org.exist.xquery.value.Sequence sequence) {
56+
this(sequence, null);
57+
}
58+
59+
public SequenceAdapter(final org.exist.xquery.value.Sequence sequence, @Nullable final RunnableE<SequenceException> closer) {
5160
this.sequence = sequence;
61+
this.closer = closer;
5262
}
5363

5464
@Override
@@ -123,8 +133,15 @@ public Sequence<Item> tail() {
123133
return new SequenceAdapter(org.exist.xquery.value.Sequence.EMPTY_SEQUENCE);
124134
}
125135
}
126-
136+
137+
@Override
138+
public void close() throws SequenceException {
139+
closer.run();
140+
}
141+
127142
public org.exist.xquery.value.Sequence getExistSequence() {
128143
return sequence;
129144
}
145+
146+
130147
}

0 commit comments

Comments
 (0)