-
Notifications
You must be signed in to change notification settings - Fork 24.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor tasks to improve APM support (#87917)
Part of #84369. Split out from #87696. Rework how some work is executed by creating child tasks for them, so that when traced by APM, it results in more meaningful parent and child tasks in the UI. It also improves how Elasticsearch is modelling the work.
- Loading branch information
1 parent
2309eb2
commit ca7c21f
Showing
49 changed files
with
640 additions
and
225 deletions.
There are no files selected for viewing
137 changes: 137 additions & 0 deletions
137
server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/TaskRecoveryIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
package org.elasticsearch.indices.recovery; | ||
|
||
import org.elasticsearch.cluster.metadata.IndexMetadata; | ||
import org.elasticsearch.common.settings.Settings; | ||
import org.elasticsearch.common.util.CollectionUtils; | ||
import org.elasticsearch.index.IndexSettings; | ||
import org.elasticsearch.index.engine.EngineFactory; | ||
import org.elasticsearch.index.engine.InternalEngine; | ||
import org.elasticsearch.plugins.EnginePlugin; | ||
import org.elasticsearch.plugins.Plugin; | ||
import org.elasticsearch.plugins.PluginsService; | ||
import org.elasticsearch.tasks.TaskInfo; | ||
import org.elasticsearch.test.ESIntegTestCase; | ||
|
||
import java.util.Collection; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.concurrent.CountDownLatch; | ||
import java.util.stream.StreamSupport; | ||
|
||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; | ||
import static org.hamcrest.Matchers.equalTo; | ||
|
||
@ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 0) | ||
public class TaskRecoveryIT extends ESIntegTestCase { | ||
|
||
@Override | ||
protected boolean addMockInternalEngine() { | ||
return false; | ||
} | ||
|
||
@Override | ||
protected Collection<Class<? extends Plugin>> nodePlugins() { | ||
return CollectionUtils.appendToCopy(super.nodePlugins(), TaskRecoveryIT.EngineTestPlugin.class); | ||
} | ||
|
||
/** | ||
* Checks that the parent / child task hierarchy is correct for tasks that are initiated by a recovery task. | ||
* We use an engine plugin that stalls translog recovery, which gives us the opportunity to inspect the | ||
* task hierarchy. | ||
*/ | ||
public void testTaskForOngoingRecovery() throws Exception { | ||
String indexName = "test"; | ||
internalCluster().startMasterOnlyNode(); | ||
String nodeWithPrimary = internalCluster().startDataOnlyNode(); | ||
assertAcked( | ||
client().admin() | ||
.indices() | ||
.prepareCreate(indexName) | ||
.setSettings( | ||
Settings.builder() | ||
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1) | ||
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0) | ||
.put("index.routing.allocation.include._name", nodeWithPrimary) | ||
) | ||
); | ||
try { | ||
String nodeWithReplica = internalCluster().startDataOnlyNode(); | ||
|
||
// Create an index so that there is something to recover | ||
assertAcked( | ||
client().admin() | ||
.indices() | ||
.prepareUpdateSettings(indexName) | ||
.setSettings( | ||
Settings.builder() | ||
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 1) | ||
.put("index.routing.allocation.include._name", nodeWithPrimary + "," + nodeWithReplica) | ||
) | ||
); | ||
// Translog recovery is stalled, so we can inspect the running tasks. | ||
assertBusy(() -> { | ||
List<TaskInfo> primaryTasks = client().admin() | ||
.cluster() | ||
.prepareListTasks(nodeWithPrimary) | ||
.setActions(PeerRecoverySourceService.Actions.START_RECOVERY) | ||
.get() | ||
.getTasks(); | ||
assertThat("Expected a single primary task", primaryTasks.size(), equalTo(1)); | ||
List<TaskInfo> replicaTasks = client().admin() | ||
.cluster() | ||
.prepareListTasks(nodeWithReplica) | ||
.setActions(PeerRecoveryTargetService.Actions.PREPARE_TRANSLOG) | ||
.get() | ||
.getTasks(); | ||
assertThat("Expected a single replica task", replicaTasks.size(), equalTo(1)); | ||
assertThat( | ||
"Replica task's parent task ID was incorrect", | ||
replicaTasks.get(0).parentTaskId(), | ||
equalTo(primaryTasks.get(0).taskId()) | ||
); | ||
}); | ||
} finally { | ||
// Release the EngineTestPlugin, which will allow translog recovery to complete | ||
StreamSupport.stream(internalCluster().getInstances(PluginsService.class).spliterator(), false) | ||
.flatMap(ps -> ps.filterPlugins(EnginePlugin.class).stream()) | ||
.map(EngineTestPlugin.class::cast) | ||
.forEach(EngineTestPlugin::release); | ||
} | ||
ensureGreen(indexName); | ||
} | ||
|
||
/** | ||
* An engine plugin that defers translog recovery until the engine is released via {@link #release()}. | ||
*/ | ||
public static class EngineTestPlugin extends Plugin implements EnginePlugin { | ||
private final CountDownLatch latch = new CountDownLatch(1); | ||
|
||
public void release() { | ||
latch.countDown(); | ||
} | ||
|
||
@Override | ||
public Optional<EngineFactory> getEngineFactory(IndexSettings indexSettings) { | ||
return Optional.of(config -> new InternalEngine(config) { | ||
|
||
@Override | ||
public void skipTranslogRecovery() { | ||
try { | ||
latch.await(); | ||
} catch (InterruptedException e) { | ||
throw new AssertionError(e); | ||
} | ||
super.skipTranslogRecovery(); | ||
} | ||
}); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.