11
11
import org .apache .lucene .search .FieldDoc ;
12
12
import org .apache .lucene .search .Query ;
13
13
import org .apache .lucene .search .TotalHits ;
14
+ import org .elasticsearch .action .ActionListener ;
14
15
import org .elasticsearch .action .search .SearchType ;
16
+ import org .elasticsearch .action .support .SubscribableListener ;
15
17
import org .elasticsearch .common .breaker .CircuitBreaker ;
16
18
import org .elasticsearch .core .Assertions ;
17
19
import org .elasticsearch .core .Nullable ;
18
20
import org .elasticsearch .core .Releasable ;
19
- import org .elasticsearch .core .Releasables ;
20
21
import org .elasticsearch .core .TimeValue ;
21
22
import org .elasticsearch .index .cache .bitset .BitsetFilterCache ;
22
23
import org .elasticsearch .index .mapper .IdLoader ;
56
57
import java .util .List ;
57
58
import java .util .Map ;
58
59
import java .util .Set ;
59
- import java .util .concurrent .CopyOnWriteArrayList ;
60
- import java .util .concurrent .atomic .AtomicBoolean ;
61
60
62
61
/**
63
62
* This class encapsulates the state needed to execute a search. It holds a reference to the
@@ -71,13 +70,16 @@ public abstract class SearchContext implements Releasable {
71
70
public static final int TRACK_TOTAL_HITS_DISABLED = -1 ;
72
71
public static final int DEFAULT_TRACK_TOTAL_HITS_UP_TO = 10000 ;
73
72
74
- protected final List <Releasable > releasables = new CopyOnWriteArrayList <>();
75
-
76
- private final AtomicBoolean closed = new AtomicBoolean (false );
73
+ protected final SubscribableListener <Void > closeFuture = new SubscribableListener <>();
77
74
78
75
{
79
76
if (Assertions .ENABLED ) {
80
- releasables .add (LeakTracker .wrap (() -> { assert closed .get (); }));
77
+ closeFuture .addListener (ActionListener .releasing (LeakTracker .wrap (new Releasable () {
78
+ @ Override
79
+ public void close () {
80
+ // empty instance that will actually get GC'ed so that the leak tracker works
81
+ }
82
+ })));
81
83
}
82
84
}
83
85
private InnerHitsContext innerHitsContext ;
@@ -109,9 +111,7 @@ public final List<Runnable> getCancellationChecks() {
109
111
110
112
@ Override
111
113
public final void close () {
112
- if (closed .compareAndSet (false , true )) {
113
- Releasables .close (releasables );
114
- }
114
+ closeFuture .onResponse (null );
115
115
}
116
116
117
117
/**
@@ -399,8 +399,8 @@ public final boolean checkRealMemoryCB(int locallyAccumulatedBytes, String label
399
399
* Adds a releasable that will be freed when this context is closed.
400
400
*/
401
401
public void addReleasable (Releasable releasable ) { // TODO most Releasables are managed by their callers. We probably don't need this.
402
- assert closed . get () == false ;
403
- releasables . add ( releasable );
402
+ assert closeFuture . isDone () == false ;
403
+ closeFuture . addListener ( ActionListener . releasing ( releasable ) );
404
404
}
405
405
406
406
/**
0 commit comments