4747
4848import com .github .benmanes .caffeine .cache .Cache ;
4949import com .github .benmanes .caffeine .cache .Caffeine ;
50+ import com .github .benmanes .caffeine .cache .RemovalListener ;
5051import net .jcip .annotations .ThreadSafe ;
5152import org .apache .logging .log4j .LogManager ;
5253import org .apache .logging .log4j .Logger ;
5354import org .exist .xquery .XQueryUtil ;
5455
56+ import javax .annotation .Nullable ;
5557import java .util .concurrent .TimeUnit ;
5658import java .util .concurrent .atomic .AtomicInteger ;
5759
@@ -64,6 +66,15 @@ public class SessionManager {
6466 private static final Logger LOG = LogManager .getLogger (SessionManager .class );
6567 private static final long TIMEOUT = 120_000 ; // ms (e.g. 2 minutes)
6668
69+ private static final RemovalListener <Integer , QueryAndResult > REMOVAL_LISTENER = (sessionId , queryAndResult , removalCause ) -> {
70+ if (LOG .isDebugEnabled ()) {
71+ LOG .debug ("Removing cached query result for session: {}" , sessionId );
72+ }
73+
74+ // NOTE(AR) make sure to release any resources still held by the query result and potentially send it back to the query pool for reuse
75+ queryAndResult .result .close ();
76+ };
77+
6778 private final AtomicInteger sessionIdCounter = new AtomicInteger ();
6879 private final Cache <Integer , QueryAndResult > cache ;
6980
@@ -78,12 +89,10 @@ private QueryAndResult(final String query, final XQueryUtil.QueryResult result)
7889 }
7990
8091 public SessionManager () {
81- final Caffeine <Object , Object > cacheBuilder = Caffeine .newBuilder ()
82- .expireAfterAccess (TIMEOUT , TimeUnit .MILLISECONDS );
83- if (LOG .isDebugEnabled ()) {
84- cacheBuilder .removalListener ((key , value , cause ) -> LOG .debug ("Removing cached query result for session: {}" , key ));
85- }
86- cache = cacheBuilder .build ();
92+ this .cache = Caffeine .newBuilder ()
93+ .expireAfterAccess (TIMEOUT , TimeUnit .MILLISECONDS )
94+ .removalListener (REMOVAL_LISTENER )
95+ .build ();
8796 }
8897
8998 public int add (final String query , final XQueryUtil .QueryResult result ) {
@@ -92,7 +101,7 @@ public int add(final String query, final XQueryUtil.QueryResult result) {
92101 return sessionId ;
93102 }
94103
95- public XQueryUtil .QueryResult get (final String query , final int sessionId ) {
104+ public @ Nullable XQueryUtil .QueryResult get (final String query , final int sessionId ) {
96105 if (sessionId < 0 || sessionId >= sessionIdCounter .get ()) {
97106 return null ; // out of scope
98107 }
0 commit comments