Errors (like StackOverflow) can cause a search context to not be released

It will eventually time out (with the default 5 minutes timeout), but we should properly handle it, and also, properly propagate the failure.
closes #3513
This commit is contained in:
Shay Banon 2013-08-14 23:41:00 +02:00
parent 4a15106d6a
commit 28ae4d6393
2 changed files with 52 additions and 38 deletions

View File

@ -30,6 +30,20 @@ public final class ExceptionsHelper {
private static final ESLogger logger = Loggers.getLogger(ExceptionsHelper.class); private static final ESLogger logger = Loggers.getLogger(ExceptionsHelper.class);
public static RuntimeException convertToRuntime(Throwable t) {
if (t instanceof RuntimeException) {
return (RuntimeException) t;
}
return new ElasticSearchException(t.getMessage(), t);
}
public static ElasticSearchException convertToElastic(Throwable t) {
if (t instanceof ElasticSearchException) {
return (ElasticSearchException) t;
}
return new ElasticSearchException(t.getMessage(), t);
}
public static RestStatus status(Throwable t) { public static RestStatus status(Throwable t) {
if (t instanceof ElasticSearchException) { if (t instanceof ElasticSearchException) {
return ((ElasticSearchException) t).status(); return ((ElasticSearchException) t).status();

View File

@ -22,6 +22,7 @@ package org.elasticsearch.search;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import org.apache.lucene.search.TopDocs; import org.apache.lucene.search.TopDocs;
import org.elasticsearch.ElasticSearchException; import org.elasticsearch.ElasticSearchException;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.action.search.SearchType; import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.cache.recycler.CacheRecycler; import org.elasticsearch.cache.recycler.CacheRecycler;
import org.elasticsearch.cluster.ClusterService; import org.elasticsearch.cluster.ClusterService;
@ -58,7 +59,6 @@ import org.elasticsearch.search.query.*;
import org.elasticsearch.search.warmer.IndexWarmersMetaData; import org.elasticsearch.search.warmer.IndexWarmersMetaData;
import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool;
import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
@ -175,10 +175,10 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
dfsPhase.execute(context); dfsPhase.execute(context);
contextProcessedSuccessfully(context); contextProcessedSuccessfully(context);
return context.dfsResult(); return context.dfsResult();
} catch (RuntimeException e) { } catch (Throwable e) {
logger.trace("Dfs phase failed", e); logger.trace("Dfs phase failed", e);
freeContext(context); freeContext(context);
throw e; throw ExceptionsHelper.convertToRuntime(e);
} finally { } finally {
cleanContext(context); cleanContext(context);
} }
@ -197,10 +197,10 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
queryPhase.execute(context); queryPhase.execute(context);
contextProcessedSuccessfully(context); contextProcessedSuccessfully(context);
return context.queryResult(); return context.queryResult();
} catch (RuntimeException e) { } catch (Throwable e) {
logger.trace("Scan phase failed", e); logger.trace("Scan phase failed", e);
freeContext(context); freeContext(context);
throw e; throw ExceptionsHelper.convertToRuntime(e);
} finally { } finally {
cleanContext(context); cleanContext(context);
} }
@ -225,10 +225,10 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
contextProcessedSuccessfully(context); contextProcessedSuccessfully(context);
} }
return new ScrollQueryFetchSearchResult(new QueryFetchSearchResult(context.queryResult(), context.fetchResult()), context.shardTarget()); return new ScrollQueryFetchSearchResult(new QueryFetchSearchResult(context.queryResult(), context.fetchResult()), context.shardTarget());
} catch (RuntimeException e) { } catch (Throwable e) {
logger.trace("Scan phase failed", e); logger.trace("Scan phase failed", e);
freeContext(context); freeContext(context);
throw e; throw ExceptionsHelper.convertToRuntime(e);
} finally { } finally {
cleanContext(context); cleanContext(context);
} }
@ -248,11 +248,11 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
} }
context.indexShard().searchService().onQueryPhase(context, System.nanoTime() - time); context.indexShard().searchService().onQueryPhase(context, System.nanoTime() - time);
return context.queryResult(); return context.queryResult();
} catch (RuntimeException e) { } catch (Throwable e) {
context.indexShard().searchService().onFailedQueryPhase(context); context.indexShard().searchService().onFailedQueryPhase(context);
logger.trace("Query phase failed", e); logger.trace("Query phase failed", e);
freeContext(context); freeContext(context);
throw e; throw ExceptionsHelper.convertToRuntime(e);
} finally { } finally {
cleanContext(context); cleanContext(context);
} }
@ -269,11 +269,11 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
contextProcessedSuccessfully(context); contextProcessedSuccessfully(context);
context.indexShard().searchService().onQueryPhase(context, System.nanoTime() - time); context.indexShard().searchService().onQueryPhase(context, System.nanoTime() - time);
return new ScrollQuerySearchResult(context.queryResult(), context.shardTarget()); return new ScrollQuerySearchResult(context.queryResult(), context.shardTarget());
} catch (RuntimeException e) { } catch (Throwable e) {
context.indexShard().searchService().onFailedQueryPhase(context); context.indexShard().searchService().onFailedQueryPhase(context);
logger.trace("Query phase failed", e); logger.trace("Query phase failed", e);
freeContext(context); freeContext(context);
throw e; throw ExceptionsHelper.convertToRuntime(e);
} finally { } finally {
cleanContext(context); cleanContext(context);
} }
@ -284,7 +284,7 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
contextProcessing(context); contextProcessing(context);
try { try {
context.searcher().dfSource(new CachedDfSource(context.searcher().getIndexReader(), request.dfs(), context.similarityService().similarity())); context.searcher().dfSource(new CachedDfSource(context.searcher().getIndexReader(), request.dfs(), context.similarityService().similarity()));
} catch (IOException e) { } catch (Throwable e) {
freeContext(context); freeContext(context);
cleanContext(context); cleanContext(context);
throw new QueryPhaseExecutionException(context, "Failed to set aggregated df", e); throw new QueryPhaseExecutionException(context, "Failed to set aggregated df", e);
@ -296,11 +296,11 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
contextProcessedSuccessfully(context); contextProcessedSuccessfully(context);
context.indexShard().searchService().onQueryPhase(context, System.nanoTime() - time); context.indexShard().searchService().onQueryPhase(context, System.nanoTime() - time);
return context.queryResult(); return context.queryResult();
} catch (RuntimeException e) { } catch (Throwable e) {
context.indexShard().searchService().onFailedQueryPhase(context); context.indexShard().searchService().onFailedQueryPhase(context);
logger.trace("Query phase failed", e); logger.trace("Query phase failed", e);
freeContext(context); freeContext(context);
throw e; throw ExceptionsHelper.convertToRuntime(e);
} finally { } finally {
cleanContext(context); cleanContext(context);
} }
@ -314,9 +314,9 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
long time = System.nanoTime(); long time = System.nanoTime();
try { try {
queryPhase.execute(context); queryPhase.execute(context);
} catch (RuntimeException e) { } catch (Throwable e) {
context.indexShard().searchService().onFailedQueryPhase(context); context.indexShard().searchService().onFailedQueryPhase(context);
throw e; throw ExceptionsHelper.convertToRuntime(e);
} }
long time2 = System.nanoTime(); long time2 = System.nanoTime();
context.indexShard().searchService().onQueryPhase(context, time2 - time); context.indexShard().searchService().onQueryPhase(context, time2 - time);
@ -329,16 +329,16 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
} else { } else {
contextProcessedSuccessfully(context); contextProcessedSuccessfully(context);
} }
} catch (RuntimeException e) { } catch (Throwable e) {
context.indexShard().searchService().onFailedFetchPhase(context); context.indexShard().searchService().onFailedFetchPhase(context);
throw e; throw ExceptionsHelper.convertToRuntime(e);
} }
context.indexShard().searchService().onFetchPhase(context, System.nanoTime() - time2); context.indexShard().searchService().onFetchPhase(context, System.nanoTime() - time2);
return new QueryFetchSearchResult(context.queryResult(), context.fetchResult()); return new QueryFetchSearchResult(context.queryResult(), context.fetchResult());
} catch (RuntimeException e) { } catch (Throwable e) {
logger.trace("Fetch phase failed", e); logger.trace("Fetch phase failed", e);
freeContext(context); freeContext(context);
throw e; throw ExceptionsHelper.convertToRuntime(e);
} finally { } finally {
cleanContext(context); cleanContext(context);
} }
@ -349,7 +349,7 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
contextProcessing(context); contextProcessing(context);
try { try {
context.searcher().dfSource(new CachedDfSource(context.searcher().getIndexReader(), request.dfs(), context.similarityService().similarity())); context.searcher().dfSource(new CachedDfSource(context.searcher().getIndexReader(), request.dfs(), context.similarityService().similarity()));
} catch (IOException e) { } catch (Throwable e) {
freeContext(context); freeContext(context);
cleanContext(context); cleanContext(context);
throw new QueryPhaseExecutionException(context, "Failed to set aggregated df", e); throw new QueryPhaseExecutionException(context, "Failed to set aggregated df", e);
@ -359,9 +359,9 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
long time = System.nanoTime(); long time = System.nanoTime();
try { try {
queryPhase.execute(context); queryPhase.execute(context);
} catch (RuntimeException e) { } catch (Throwable e) {
context.indexShard().searchService().onFailedQueryPhase(context); context.indexShard().searchService().onFailedQueryPhase(context);
throw e; throw ExceptionsHelper.convertToRuntime(e);
} }
long time2 = System.nanoTime(); long time2 = System.nanoTime();
context.indexShard().searchService().onQueryPhase(context, time2 - time); context.indexShard().searchService().onQueryPhase(context, time2 - time);
@ -374,16 +374,16 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
} else { } else {
contextProcessedSuccessfully(context); contextProcessedSuccessfully(context);
} }
} catch (RuntimeException e) { } catch (Throwable e) {
context.indexShard().searchService().onFailedFetchPhase(context); context.indexShard().searchService().onFailedFetchPhase(context);
throw e; throw ExceptionsHelper.convertToRuntime(e);
} }
context.indexShard().searchService().onFetchPhase(context, System.nanoTime() - time2); context.indexShard().searchService().onFetchPhase(context, System.nanoTime() - time2);
return new QueryFetchSearchResult(context.queryResult(), context.fetchResult()); return new QueryFetchSearchResult(context.queryResult(), context.fetchResult());
} catch (RuntimeException e) { } catch (Throwable e) {
logger.trace("Fetch phase failed", e); logger.trace("Fetch phase failed", e);
freeContext(context); freeContext(context);
throw e; throw ExceptionsHelper.convertToRuntime(e);
} finally { } finally {
cleanContext(context); cleanContext(context);
} }
@ -398,9 +398,9 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
long time = System.nanoTime(); long time = System.nanoTime();
try { try {
queryPhase.execute(context); queryPhase.execute(context);
} catch (RuntimeException e) { } catch (Throwable e) {
context.indexShard().searchService().onFailedQueryPhase(context); context.indexShard().searchService().onFailedQueryPhase(context);
throw e; throw ExceptionsHelper.convertToRuntime(e);
} }
long time2 = System.nanoTime(); long time2 = System.nanoTime();
context.indexShard().searchService().onQueryPhase(context, time2 - time); context.indexShard().searchService().onQueryPhase(context, time2 - time);
@ -413,16 +413,16 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
} else { } else {
contextProcessedSuccessfully(context); contextProcessedSuccessfully(context);
} }
} catch (RuntimeException e) { } catch (Throwable e) {
context.indexShard().searchService().onFailedFetchPhase(context); context.indexShard().searchService().onFailedFetchPhase(context);
throw e; throw ExceptionsHelper.convertToRuntime(e);
} }
context.indexShard().searchService().onFetchPhase(context, System.nanoTime() - time2); context.indexShard().searchService().onFetchPhase(context, System.nanoTime() - time2);
return new ScrollQueryFetchSearchResult(new QueryFetchSearchResult(context.queryResult(), context.fetchResult()), context.shardTarget()); return new ScrollQueryFetchSearchResult(new QueryFetchSearchResult(context.queryResult(), context.fetchResult()), context.shardTarget());
} catch (RuntimeException e) { } catch (Throwable e) {
logger.trace("Fetch phase failed", e); logger.trace("Fetch phase failed", e);
freeContext(context); freeContext(context);
throw e; throw ExceptionsHelper.convertToRuntime(e);
} finally { } finally {
cleanContext(context); cleanContext(context);
} }
@ -443,11 +443,11 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
} }
context.indexShard().searchService().onFetchPhase(context, System.nanoTime() - time); context.indexShard().searchService().onFetchPhase(context, System.nanoTime() - time);
return context.fetchResult(); return context.fetchResult();
} catch (RuntimeException e) { } catch (Throwable e) {
context.indexShard().searchService().onFailedFetchPhase(context); context.indexShard().searchService().onFailedFetchPhase(context);
logger.trace("Fetch phase failed", e); logger.trace("Fetch phase failed", e);
freeContext(context); freeContext(context);
throw e; throw ExceptionsHelper.convertToRuntime(e);
} finally { } finally {
cleanContext(context); cleanContext(context);
} }
@ -507,9 +507,9 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
keepAlive = request.scroll().keepAlive().millis(); keepAlive = request.scroll().keepAlive().millis();
} }
context.keepAlive(keepAlive); context.keepAlive(keepAlive);
} catch (RuntimeException e) { } catch (Throwable e) {
context.release(); context.release();
throw e; throw ExceptionsHelper.convertToRuntime(e);
} }
return context; return context;
@ -567,7 +567,7 @@ public class SearchService extends AbstractLifecycleComponent<SearchService> {
break; break;
} }
} }
} catch (Exception e) { } catch (Throwable e) {
String sSource = "_na_"; String sSource = "_na_";
try { try {
sSource = XContentHelper.convertToJson(source, false); sSource = XContentHelper.convertToJson(source, false);