Description
Elasticsearch version: >= 7.9.0
Plugins installed: Any custom ActionPlugin
that uses the NodeClient
client from a BaseRestHandler
.
JVM version: JDK 11
OS version: The test scripts (see below) used Docker CE 19.03.13 and docker-compose 1.27.4 on macOS 10.15.7
Description of the problem
When using a multi-node cluster, requests made by the NodeClient
client from a BaseRestHandler
in an ActionPlugin
will cause Elasticsearch to hang.
Take this simple example (see entire sample plugin):
@Override
protected RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) {
return channel -> {
try {
client.prepareSearch("*").get(); // A search request made by the NodeClient.
XContentBuilder content = XContentFactory.jsonBuilder();
content.startObject().field("acknowledged", true).endObject();
channel.sendResponse(new BytesRestResponse(RestStatus.OK, content));
} catch (final Exception e) {
channel.sendResponse(new BytesRestResponse(channel, e));
}
};
}
In this example, a simple search performed by the plugin's NodeClient
will cause Elastisearch >= 7.9.0 to hang if that cluster has multiple nodes.
Any action, whether it's creating an index or performing a search, from a custom plugin appears to cause multi-node cluster to hang.
I've labeled this as a "bug" because the usage of the NodeClient
in plugins has worked since at least Elasticsearch 5.x, and the expected behavior stopped working after 7.9.0 without an explanation in the release notes.
Steps to reproduce
I've provided a test script to simplify the reproduction of this issue.
Step 1. Download and extract my test script (elasticsearch-plugin-troubleshooting.zip) which contains:
./post-7.9/docker-compose.yml
- A 3-node Elasticsearch cluster at version 7.10.2 with a sample plugin installed./pre-7.9/docker-compose.yml
- A 3-node Elasticsearch cluster at version 7.8.1 with a sample plugin installed./test.sh
- A script to test plugin behavior in the two versions of Elasticsearch
Step 2. Test the behavior of the plugin on Elasticsearch 7.8.1. Open two terminals:
- On Terminal 1:
cd pre-7.9
docker-compose up
- On Terminal 2:
./test.sh
Step 3. Observe the output. Notice that ./test.sh
performs three successful tasks:
- Creates and deletes an index (
sample-index
) usingcurl
50 times. - Creates and deletes an index (
sample-index
) using the custom plugin endpoint (/_sample/create
) 50 times. - Searches an index using the custom plugin endpoint (
_sample/search
) 50 times.
Step 4. Test the behavior of the plugin on Elasticsearch 7.10.2. Open two terminals:
- On Terminal 1:
cd post-7.9
docker-compose up
- On Terminal 2:
./test.sh
Step 5. Observe the output. Notice that ./test.sh
performs hangs when the custom plugin is used, unlike Step 3:
- Creates and deletes an index (
sample-index
) usingcurl
50 times. - Hangs when the custom plugin endpoint (
/_sample/create
) attempts to create an index (sample-index
).