diff --git a/src/main/java/org/elasticsearch/search/SearchService.java b/src/main/java/org/elasticsearch/search/SearchService.java index 17374db8cbfdc..05502be60464b 100644 --- a/src/main/java/org/elasticsearch/search/SearchService.java +++ b/src/main/java/org/elasticsearch/search/SearchService.java @@ -460,9 +460,17 @@ private SearchContext findContext(long id) throws SearchContextMissingException SearchContext createAndPutContext(ShardSearchRequest request) throws ElasticSearchException { SearchContext context = createContext(request); - activeContexts.put(context.id(), context); - context.indexShard().searchService().onNewContext(context); - return context; + boolean success = false; + try { + activeContexts.put(context.id(), context); + context.indexShard().searchService().onNewContext(context); + success = true; + return context; + } finally { + if (!success) { + freeContext(context); + } + } } SearchContext createContext(ShardSearchRequest request) throws ElasticSearchException { @@ -833,10 +841,14 @@ class Reaper implements Runnable { public void run() { long time = threadPool.estimatedTimeInMillis(); for (SearchContext context : activeContexts.values()) { - if (context.lastAccessTime() == -1) { // its being processed or timeout is disabled + // Use the same value for both checks since lastAccessTime can + // be modified by another thread between checks! + long lastAccessTime = context.lastAccessTime(); + if (lastAccessTime == -1l) { // its being processed or timeout is disabled continue; } - if ((time - context.lastAccessTime() > context.keepAlive())) { + if ((time - lastAccessTime > context.keepAlive())) { + logger.debug("freeing search context [{}], time [{}], lastAccessTime [{}], keepAlive [{}]", context.id(), time, lastAccessTime, context.keepAlive()); freeContext(context); } } diff --git a/src/main/java/org/elasticsearch/search/internal/SearchContext.java b/src/main/java/org/elasticsearch/search/internal/SearchContext.java index b21fac91609a3..73da685733758 100644 --- a/src/main/java/org/elasticsearch/search/internal/SearchContext.java +++ b/src/main/java/org/elasticsearch/search/internal/SearchContext.java @@ -175,7 +175,7 @@ public static SearchContext current() { private volatile long keepAlive; - private volatile long lastAccessTime; + private volatile long lastAccessTime = -1; private List clearables = null;