Skip to content

Commit 1cde4a6

Browse files
Make SnapshotsService#getRepositoryData Async (#49322) (#49358)
* Make SnapshotsService#getRepositoryData Async (#49322) Follow up to #49299 removing the blocking step for the snapshot status APIs as well.
1 parent 20558cf commit 1cde4a6

File tree

3 files changed

+37
-21
lines changed

3 files changed

+37
-21
lines changed

server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/get/TransportGetSnapshotsAction.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.apache.lucene.util.CollectionUtil;
2323
import org.elasticsearch.action.ActionListener;
2424
import org.elasticsearch.action.support.ActionFilters;
25+
import org.elasticsearch.action.support.PlainActionFuture;
2526
import org.elasticsearch.action.support.master.TransportMasterNodeAction;
2627
import org.elasticsearch.cluster.ClusterState;
2728
import org.elasticsearch.cluster.block.ClusterBlockException;
@@ -96,7 +97,7 @@ protected void masterOperation(final GetSnapshotsRequest request, final ClusterS
9697

9798
final RepositoryData repositoryData;
9899
if (isCurrentSnapshotsOnly(request.snapshots()) == false) {
99-
repositoryData = snapshotsService.getRepositoryData(repository);
100+
repositoryData = PlainActionFuture.get(fut -> snapshotsService.getRepositoryData(repository, fut));
100101
for (SnapshotId snapshotId : repositoryData.getSnapshotIds()) {
101102
allSnapshotIds.put(snapshotId.getName(), snapshotId);
102103
}

server/src/main/java/org/elasticsearch/action/admin/cluster/snapshots/status/TransportSnapshotsStatusAction.java

+26-14
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
2424
import org.elasticsearch.action.ActionListener;
2525
import org.elasticsearch.action.ActionRunnable;
26+
import org.elasticsearch.action.StepListener;
2627
import org.elasticsearch.action.support.ActionFilters;
2728
import org.elasticsearch.action.support.master.TransportMasterNodeAction;
2829
import org.elasticsearch.cluster.ClusterState;
@@ -97,7 +98,7 @@ protected void masterOperation(final SnapshotsStatusRequest request,
9798
List<SnapshotsInProgress.Entry> currentSnapshots =
9899
snapshotsService.currentSnapshots(request.repository(), Arrays.asList(request.snapshots()));
99100
if (currentSnapshots.isEmpty()) {
100-
listener.onResponse(buildResponse(request, currentSnapshots, null));
101+
buildResponse(request, currentSnapshots, null, listener);
101102
return;
102103
}
103104

@@ -119,20 +120,22 @@ protected void masterOperation(final SnapshotsStatusRequest request,
119120
transportNodesSnapshotsStatus.execute(
120121
new TransportNodesSnapshotsStatus.Request(nodesIds.toArray(Strings.EMPTY_ARRAY))
121122
.snapshots(snapshots).timeout(request.masterNodeTimeout()),
122-
ActionListener.wrap(
123-
nodeSnapshotStatuses -> threadPool.executor(ThreadPool.Names.GENERIC).execute(
124-
ActionRunnable.supply(listener, () -> buildResponse(request, snapshotsService.currentSnapshots(
125-
request.repository(), Arrays.asList(request.snapshots())), nodeSnapshotStatuses))), listener::onFailure));
123+
ActionListener.wrap(nodeSnapshotStatuses -> threadPool.generic().execute(
124+
ActionRunnable.wrap(listener,
125+
l -> buildResponse(
126+
request, snapshotsService.currentSnapshots(request.repository(), Arrays.asList(request.snapshots())),
127+
nodeSnapshotStatuses, l))
128+
), listener::onFailure));
126129
} else {
127130
// We don't have any in-progress shards, just return current stats
128-
listener.onResponse(buildResponse(request, currentSnapshots, null));
131+
buildResponse(request, currentSnapshots, null, listener);
129132
}
130133

131134
}
132135

133-
private SnapshotsStatusResponse buildResponse(SnapshotsStatusRequest request, List<SnapshotsInProgress.Entry> currentSnapshotEntries,
134-
TransportNodesSnapshotsStatus.NodesSnapshotStatus nodeSnapshotStatuses)
135-
throws IOException {
136+
private void buildResponse(SnapshotsStatusRequest request, List<SnapshotsInProgress.Entry> currentSnapshotEntries,
137+
TransportNodesSnapshotsStatus.NodesSnapshotStatus nodeSnapshotStatuses,
138+
ActionListener<SnapshotsStatusResponse> listener) {
136139
// First process snapshot that are currently processed
137140
List<SnapshotStatus> builder = new ArrayList<>();
138141
Set<String> currentSnapshotNames = new HashSet<>();
@@ -192,8 +195,18 @@ private SnapshotsStatusResponse buildResponse(SnapshotsStatusRequest request, Li
192195
// Now add snapshots on disk that are not currently running
193196
final String repositoryName = request.repository();
194197
if (Strings.hasText(repositoryName) && request.snapshots() != null && request.snapshots().length > 0) {
195-
final Set<String> requestedSnapshotNames = Sets.newHashSet(request.snapshots());
196-
final RepositoryData repositoryData = snapshotsService.getRepositoryData(repositoryName);
198+
loadRepositoryData(request, builder, currentSnapshotNames, repositoryName, listener);
199+
} else {
200+
listener.onResponse(new SnapshotsStatusResponse(Collections.unmodifiableList(builder)));
201+
}
202+
}
203+
204+
private void loadRepositoryData(SnapshotsStatusRequest request, List<SnapshotStatus> builder, Set<String> currentSnapshotNames,
205+
String repositoryName, ActionListener<SnapshotsStatusResponse> listener) {
206+
final Set<String> requestedSnapshotNames = Sets.newHashSet(request.snapshots());
207+
final StepListener<RepositoryData> repositoryDataListener = new StepListener<>();
208+
snapshotsService.getRepositoryData(repositoryName, repositoryDataListener);
209+
repositoryDataListener.whenComplete(repositoryData -> {
197210
final Map<String, SnapshotId> matchedSnapshotIds = repositoryData.getSnapshotIds().stream()
198211
.filter(s -> requestedSnapshotNames.contains(s.getName()))
199212
.collect(Collectors.toMap(SnapshotId::getName, Function.identity()));
@@ -248,9 +261,8 @@ private SnapshotsStatusResponse buildResponse(SnapshotsStatusRequest request, Li
248261
(endTime == 0 ? threadPool.absoluteTimeInMillis() : endTime) - startTime));
249262
}
250263
}
251-
}
252-
253-
return new SnapshotsStatusResponse(Collections.unmodifiableList(builder));
264+
listener.onResponse(new SnapshotsStatusResponse(Collections.unmodifiableList(builder)));
265+
}, listener::onFailure);
254266
}
255267

256268
}

server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java

+9-6
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import org.elasticsearch.action.ActionRunnable;
3232
import org.elasticsearch.action.StepListener;
3333
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest;
34-
import org.elasticsearch.action.support.PlainActionFuture;
3534
import org.elasticsearch.cluster.ClusterChangedEvent;
3635
import org.elasticsearch.cluster.ClusterState;
3736
import org.elasticsearch.cluster.ClusterStateApplier;
@@ -163,12 +162,16 @@ public SnapshotsService(Settings settings, ClusterService clusterService, IndexN
163162
* Gets the {@link RepositoryData} for the given repository.
164163
*
165164
* @param repositoryName repository name
166-
* @return repository data
165+
* @param listener listener to pass {@link RepositoryData} to
167166
*/
168-
public RepositoryData getRepositoryData(final String repositoryName) {
169-
Repository repository = repositoriesService.repository(repositoryName);
170-
assert repository != null; // should only be called once we've validated the repository exists
171-
return PlainActionFuture.get(repository::getRepositoryData);
167+
public void getRepositoryData(final String repositoryName, final ActionListener<RepositoryData> listener) {
168+
try {
169+
Repository repository = repositoriesService.repository(repositoryName);
170+
assert repository != null; // should only be called once we've validated the repository exists
171+
repository.getRepositoryData(listener);
172+
} catch (Exception e) {
173+
listener.onFailure(e);
174+
}
172175
}
173176

174177
/**

0 commit comments

Comments
 (0)