Skip to content

Commit 11d46ad

Browse files
committed
Merge branch 'master' into ccr
* master: Skip shard refreshes if shard is `search idle` (#27500) Remove workaround in translog rest test (#27530) inner_hits: Return an empty _source for nested inner hit when filtering on a field that doesn't exist. percolator: Avoid TooManyClauses exception if number of terms / ranges is exactly equal to 1024 Dedup translog operations by reading in reverse (#27268) Ensure logging is configured for CLI commands Ensure `doc_stats` are changing even if refresh is disabled (#27505) Fix classes that can exit Revert "Adjust CombinedDeletionPolicy for multiple commits (#27456)" Transpose expected and actual, and remove duplicate info from message. (#27515) [DOCS] Fixed broken link in breaking changes
2 parents 69bc97d + f23ed61 commit 11d46ad

File tree

48 files changed

+1426
-324
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1426
-324
lines changed

core/cli/src/main/java/org/elasticsearch/cli/Command.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ public abstract class Command implements Closeable {
3838
/** A description of the command, used in the help output. */
3939
protected final String description;
4040

41+
private final Runnable beforeMain;
42+
4143
/** The option parser for this command. */
4244
protected final OptionParser parser = new OptionParser();
4345

@@ -46,8 +48,15 @@ public abstract class Command implements Closeable {
4648
private final OptionSpec<Void> verboseOption =
4749
parser.acceptsAll(Arrays.asList("v", "verbose"), "show verbose output").availableUnless(silentOption);
4850

49-
public Command(String description) {
51+
/**
52+
* Construct the command with the specified command description and runnable to execute before main is invoked.
53+
*
54+
* @param description the command description
55+
* @param beforeMain the before-main runnable
56+
*/
57+
public Command(final String description, final Runnable beforeMain) {
5058
this.description = description;
59+
this.beforeMain = beforeMain;
5160
}
5261

5362
private Thread shutdownHookThread;
@@ -75,7 +84,7 @@ public final int main(String[] args, Terminal terminal) throws Exception {
7584
Runtime.getRuntime().addShutdownHook(shutdownHookThread);
7685
}
7786

78-
beforeExecute();
87+
beforeMain.run();
7988

8089
try {
8190
mainWithoutErrorHandling(args, terminal);
@@ -93,12 +102,6 @@ public final int main(String[] args, Terminal terminal) throws Exception {
93102
return ExitCodes.OK;
94103
}
95104

96-
/**
97-
* Setup method to be executed before parsing or execution of the command being run. Any exceptions thrown by the
98-
* method will not be cleanly caught by the parser.
99-
*/
100-
protected void beforeExecute() {}
101-
102105
/**
103106
* Executes the command, but all errors are thrown.
104107
*/

core/cli/src/main/java/org/elasticsearch/cli/MultiCommand.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,14 @@ public class MultiCommand extends Command {
3535

3636
private final NonOptionArgumentSpec<String> arguments = parser.nonOptions("command");
3737

38-
public MultiCommand(String description) {
39-
super(description);
38+
/**
39+
* Construct the multi-command with the specified command description and runnable to execute before main is invoked.
40+
*
41+
* @param description the multi-command description
42+
* @param beforeMain the before-main runnable
43+
*/
44+
public MultiCommand(final String description, final Runnable beforeMain) {
45+
super(description, beforeMain);
4046
parser.posixlyCorrect(true);
4147
}
4248

core/src/main/java/org/elasticsearch/action/explain/TransportExplainAction.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@
3333
import org.elasticsearch.common.inject.Inject;
3434
import org.elasticsearch.common.lease.Releasables;
3535
import org.elasticsearch.common.settings.Settings;
36+
import org.elasticsearch.index.IndexService;
3637
import org.elasticsearch.index.engine.Engine;
3738
import org.elasticsearch.index.get.GetResult;
39+
import org.elasticsearch.index.shard.IndexShard;
3840
import org.elasticsearch.index.shard.ShardId;
3941
import org.elasticsearch.search.SearchService;
4042
import org.elasticsearch.search.internal.AliasFilter;
@@ -86,6 +88,19 @@ protected void resolveRequest(ClusterState state, InternalRequest request) {
8688
}
8789
}
8890

91+
@Override
92+
protected void asyncShardOperation(ExplainRequest request, ShardId shardId, ActionListener<ExplainResponse> listener) throws IOException {
93+
IndexService indexService = searchService.getIndicesService().indexServiceSafe(shardId.getIndex());
94+
IndexShard indexShard = indexService.getShard(shardId.id());
95+
indexShard.awaitShardSearchActive(b -> {
96+
try {
97+
super.asyncShardOperation(request, shardId, listener);
98+
} catch (Exception ex) {
99+
listener.onFailure(ex);
100+
}
101+
});
102+
}
103+
89104
@Override
90105
protected ExplainResponse shardOperation(ExplainRequest request, ShardId shardId) throws IOException {
91106
ShardSearchLocalRequest shardSearchLocalRequest = new ShardSearchLocalRequest(shardId,

core/src/main/java/org/elasticsearch/action/get/TransportGetAction.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@
1919

2020
package org.elasticsearch.action.get;
2121

22+
import org.elasticsearch.action.ActionListener;
2223
import org.elasticsearch.action.RoutingMissingException;
2324
import org.elasticsearch.action.support.ActionFilters;
2425
import org.elasticsearch.action.support.single.shard.TransportSingleShardAction;
2526
import org.elasticsearch.cluster.ClusterState;
2627
import org.elasticsearch.cluster.metadata.IndexMetaData;
2728
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
28-
import org.elasticsearch.cluster.routing.Preference;
2929
import org.elasticsearch.cluster.routing.ShardIterator;
3030
import org.elasticsearch.cluster.service.ClusterService;
3131
import org.elasticsearch.common.inject.Inject;
@@ -38,6 +38,8 @@
3838
import org.elasticsearch.threadpool.ThreadPool;
3939
import org.elasticsearch.transport.TransportService;
4040

41+
import java.io.IOException;
42+
4143
/**
4244
* Performs the get operation.
4345
*/
@@ -76,6 +78,23 @@ protected void resolveRequest(ClusterState state, InternalRequest request) {
7678
}
7779
}
7880

81+
@Override
82+
protected void asyncShardOperation(GetRequest request, ShardId shardId, ActionListener<GetResponse> listener) throws IOException {
83+
IndexService indexService = indicesService.indexServiceSafe(shardId.getIndex());
84+
IndexShard indexShard = indexService.getShard(shardId.id());
85+
if (request.realtime()) { // we are not tied to a refresh cycle here anyway
86+
listener.onResponse(shardOperation(request, shardId));
87+
} else {
88+
indexShard.awaitShardSearchActive(b -> {
89+
try {
90+
super.asyncShardOperation(request, shardId, listener);
91+
} catch (Exception ex) {
92+
listener.onFailure(ex);
93+
}
94+
});
95+
}
96+
}
97+
7998
@Override
8099
protected GetResponse shardOperation(GetRequest request, ShardId shardId) {
81100
IndexService indexService = indicesService.indexServiceSafe(shardId.getIndex());

core/src/main/java/org/elasticsearch/action/support/single/shard/TransportSingleShardAction.java

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.elasticsearch.common.Nullable;
3939
import org.elasticsearch.common.logging.LoggerMessageFormat;
4040
import org.elasticsearch.common.settings.Settings;
41+
import org.elasticsearch.common.util.concurrent.AbstractRunnable;
4142
import org.elasticsearch.index.shard.ShardId;
4243
import org.elasticsearch.threadpool.ThreadPool;
4344
import org.elasticsearch.transport.TransportChannel;
@@ -47,6 +48,8 @@
4748
import org.elasticsearch.transport.TransportService;
4849

4950
import java.io.IOException;
51+
import java.io.UncheckedIOException;
52+
import java.util.concurrent.Executor;
5053
import java.util.function.Supplier;
5154

5255
import static org.elasticsearch.action.support.TransportActions.isShardNotAvailableException;
@@ -78,7 +81,7 @@ protected TransportSingleShardAction(Settings settings, String actionName, Threa
7881
if (!isSubAction()) {
7982
transportService.registerRequestHandler(actionName, request, ThreadPool.Names.SAME, new TransportHandler());
8083
}
81-
transportService.registerRequestHandler(transportShardAction, request, executor, new ShardTransportHandler());
84+
transportService.registerRequestHandler(transportShardAction, request, ThreadPool.Names.SAME, new ShardTransportHandler());
8285
}
8386

8487
/**
@@ -97,6 +100,19 @@ protected void doExecute(Request request, ActionListener<Response> listener) {
97100

98101
protected abstract Response shardOperation(Request request, ShardId shardId) throws IOException;
99102

103+
protected void asyncShardOperation(Request request, ShardId shardId, ActionListener<Response> listener) throws IOException {
104+
threadPool.executor(this.executor).execute(new AbstractRunnable() {
105+
@Override
106+
public void onFailure(Exception e) {
107+
listener.onFailure(e);
108+
}
109+
110+
@Override
111+
protected void doRun() throws Exception {
112+
listener.onResponse(shardOperation(request, shardId));
113+
}
114+
});
115+
}
100116
protected abstract Response newResponse();
101117

102118
protected abstract boolean resolveIndex(Request request);
@@ -291,11 +307,27 @@ public void messageReceived(final Request request, final TransportChannel channe
291307
if (logger.isTraceEnabled()) {
292308
logger.trace("executing [{}] on shard [{}]", request, request.internalShardId);
293309
}
294-
Response response = shardOperation(request, request.internalShardId);
295-
channel.sendResponse(response);
310+
asyncShardOperation(request, request.internalShardId, new ActionListener<Response>() {
311+
@Override
312+
public void onResponse(Response response) {
313+
try {
314+
channel.sendResponse(response);
315+
} catch (IOException e) {
316+
onFailure(e);
317+
}
318+
}
319+
320+
@Override
321+
public void onFailure(Exception e) {
322+
try {
323+
channel.sendResponse(e);
324+
} catch (IOException e1) {
325+
throw new UncheckedIOException(e1);
326+
}
327+
}
328+
});
296329
}
297330
}
298-
299331
/**
300332
* Internal request class that gets built on each node. Holds the original request plus additional info.
301333
*/

core/src/main/java/org/elasticsearch/action/termvectors/TransportTermVectorsAction.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
package org.elasticsearch.action.termvectors;
2121

22+
import org.elasticsearch.action.ActionListener;
2223
import org.elasticsearch.action.RoutingMissingException;
2324
import org.elasticsearch.action.support.ActionFilters;
2425
import org.elasticsearch.action.support.single.shard.TransportSingleShardAction;
@@ -37,6 +38,8 @@
3738
import org.elasticsearch.threadpool.ThreadPool;
3839
import org.elasticsearch.transport.TransportService;
3940

41+
import java.io.IOException;
42+
4043
/**
4144
* Performs the get operation.
4245
*/
@@ -82,6 +85,23 @@ protected void resolveRequest(ClusterState state, InternalRequest request) {
8285
}
8386
}
8487

88+
@Override
89+
protected void asyncShardOperation(TermVectorsRequest request, ShardId shardId, ActionListener<TermVectorsResponse> listener) throws IOException {
90+
IndexService indexService = indicesService.indexServiceSafe(shardId.getIndex());
91+
IndexShard indexShard = indexService.getShard(shardId.id());
92+
if (request.realtime()) { // it's a realtime request which is not subject to refresh cycles
93+
listener.onResponse(shardOperation(request, shardId));
94+
} else {
95+
indexShard.awaitShardSearchActive(b -> {
96+
try {
97+
super.asyncShardOperation(request, shardId, listener);
98+
} catch (Exception ex) {
99+
listener.onFailure(ex);
100+
}
101+
});
102+
}
103+
}
104+
85105
@Override
86106
protected TermVectorsResponse shardOperation(TermVectorsRequest request, ShardId shardId) {
87107
IndexService indexService = indicesService.indexServiceSafe(shardId.getIndex());

core/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class Elasticsearch extends EnvironmentAwareCommand {
5151

5252
// visible for testing
5353
Elasticsearch() {
54-
super("starts elasticsearch");
54+
super("starts elasticsearch", () -> {}); // we configure logging later so we override the base class from configuring logging
5555
versionOption = parser.acceptsAll(Arrays.asList("V", "version"),
5656
"Prints elasticsearch version information and exits");
5757
daemonizeOption = parser.acceptsAll(Arrays.asList("d", "daemonize"),
@@ -92,15 +92,6 @@ static int main(final String[] args, final Elasticsearch elasticsearch, final Te
9292
return elasticsearch.main(args, terminal);
9393
}
9494

95-
@Override
96-
protected boolean shouldConfigureLoggingWithoutConfig() {
97-
/*
98-
* If we allow logging to be configured without a config before we are ready to read the log4j2.properties file, then we will fail
99-
* to detect uses of logging before it is properly configured.
100-
*/
101-
return false;
102-
}
103-
10495
@Override
10596
protected void execute(Terminal terminal, OptionSet options, Environment env) throws UserException {
10697
if (options.nonOptionArguments().isEmpty() == false) {

core/src/main/java/org/elasticsearch/bootstrap/ElasticsearchUncaughtExceptionHandler.java

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,37 +65,43 @@ public void uncaughtException(Thread t, Throwable e) {
6565
}
6666
}
6767

68-
// visible for testing
6968
static boolean isFatalUncaught(Throwable e) {
7069
return e instanceof Error;
7170
}
7271

73-
// visible for testing
7472
void onFatalUncaught(final String threadName, final Throwable t) {
7573
final Logger logger = Loggers.getLogger(ElasticsearchUncaughtExceptionHandler.class, loggingPrefixSupplier.get());
7674
logger.error(
7775
(org.apache.logging.log4j.util.Supplier<?>)
7876
() -> new ParameterizedMessage("fatal error in thread [{}], exiting", threadName), t);
7977
}
8078

81-
// visible for testing
8279
void onNonFatalUncaught(final String threadName, final Throwable t) {
8380
final Logger logger = Loggers.getLogger(ElasticsearchUncaughtExceptionHandler.class, loggingPrefixSupplier.get());
8481
logger.warn((org.apache.logging.log4j.util.Supplier<?>)
8582
() -> new ParameterizedMessage("uncaught exception in thread [{}]", threadName), t);
8683
}
8784

88-
// visible for testing
8985
void halt(int status) {
90-
AccessController.doPrivileged(new PrivilegedAction<Void>() {
91-
@SuppressForbidden(reason = "halt")
92-
@Override
93-
public Void run() {
94-
// we halt to prevent shutdown hooks from running
95-
Runtime.getRuntime().halt(status);
96-
return null;
97-
}
98-
});
86+
AccessController.doPrivileged(new PrivilegedHaltAction(status));
87+
}
88+
89+
static class PrivilegedHaltAction implements PrivilegedAction<Void> {
90+
91+
private final int status;
92+
93+
private PrivilegedHaltAction(final int status) {
94+
this.status = status;
95+
}
96+
97+
@SuppressForbidden(reason = "halt")
98+
@Override
99+
public Void run() {
100+
// we halt to prevent shutdown hooks from running
101+
Runtime.getRuntime().halt(status);
102+
return null;
103+
}
104+
99105
}
100106

101107
}

core/src/main/java/org/elasticsearch/bootstrap/Security.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,11 @@ static void configure(Environment environment, boolean filterBadDefaults) throws
119119
Policy.setPolicy(new ESPolicy(createPermissions(environment), getPluginPermissions(environment), filterBadDefaults));
120120

121121
// enable security manager
122-
final String[] classesThatCanExit = new String[]{ElasticsearchUncaughtExceptionHandler.class.getName(), Command.class.getName()};
122+
final String[] classesThatCanExit =
123+
new String[]{
124+
// SecureSM matches class names as regular expressions so we escape the $ that arises from the nested class name
125+
ElasticsearchUncaughtExceptionHandler.PrivilegedHaltAction.class.getName().replace("$", "\\$"),
126+
Command.class.getName()};
123127
System.setSecurityManager(new SecureSM(classesThatCanExit));
124128

125129
// do some basic tests

0 commit comments

Comments
 (0)