33
33
import org .elasticsearch .Version ;
34
34
import org .elasticsearch .action .ActionListener ;
35
35
import org .elasticsearch .action .StepListener ;
36
+ import org .elasticsearch .action .support .ThreadedActionListener ;
36
37
import org .elasticsearch .action .support .replication .ReplicationResponse ;
37
38
import org .elasticsearch .cluster .metadata .IndexMetaData ;
38
39
import org .elasticsearch .cluster .routing .IndexShardRoutingTable ;
66
67
import org .elasticsearch .index .translog .Translog ;
67
68
import org .elasticsearch .threadpool .ThreadPool ;
68
69
import org .elasticsearch .transport .RemoteTransportException ;
70
+ import org .elasticsearch .transport .Transports ;
69
71
70
72
import java .io .Closeable ;
71
73
import java .io .IOException ;
@@ -146,8 +148,10 @@ public void recoverToTarget(ActionListener<RecoveryResponse> listener) {
146
148
IOUtils .closeWhileHandlingException (releaseResources , () -> wrappedListener .onFailure (e ));
147
149
throw e ;
148
150
});
149
- final Consumer <Exception > onFailure = e ->
151
+ final Consumer <Exception > onFailure = e -> {
152
+ Transports .assertNotTransportThread ("failure of recovery from " + shard .routingEntry () + " to " + request .targetNode ());
150
153
IOUtils .closeWhileHandlingException (releaseResources , () -> wrappedListener .onFailure (e ));
154
+ };
151
155
152
156
runUnderPrimaryPermit (() -> {
153
157
final IndexShardRoutingTable routingTable = shard .getReplicationGroup ().getRoutingTable ();
@@ -208,7 +212,9 @@ public void recoverToTarget(ActionListener<RecoveryResponse> listener) {
208
212
// If the target previously had a copy of this shard then a file-based recovery might move its global
209
213
// checkpoint backwards. We must therefore remove any existing retention lease so that we can create a
210
214
// new one later on in the recovery.
211
- shard .removePeerRecoveryRetentionLease (request .targetNode ().getId (), deleteRetentionLeaseStep );
215
+ shard .removePeerRecoveryRetentionLease (request .targetNode ().getId (),
216
+ new ThreadedActionListener <>(logger , shard .getThreadPool (), ThreadPool .Names .GENERIC ,
217
+ deleteRetentionLeaseStep , false ));
212
218
} catch (RetentionLeaseNotFoundException e ) {
213
219
logger .debug ("no peer-recovery retention lease for " + request .targetAllocationId ());
214
220
deleteRetentionLeaseStep .onResponse (null );
@@ -220,6 +226,7 @@ public void recoverToTarget(ActionListener<RecoveryResponse> listener) {
220
226
}
221
227
222
228
deleteRetentionLeaseStep .whenComplete (ignored -> {
229
+ Transports .assertNotTransportThread (RecoverySourceHandler .this + "[phase1]" );
223
230
phase1 (safeCommitRef .getIndexCommit (), shard .getLastKnownGlobalCheckpoint (), () -> estimateNumOps , sendFileStep );
224
231
}, onFailure );
225
232
@@ -233,30 +240,33 @@ public void recoverToTarget(ActionListener<RecoveryResponse> listener) {
233
240
if (shard .indexSettings ().isSoftDeleteEnabled ()
234
241
&& shard .indexSettings ().getIndexMetaData ().getState () != IndexMetaData .State .CLOSE ) {
235
242
runUnderPrimaryPermit (() -> {
236
- try {
237
- // conservative estimate of the GCP for creating the lease. TODO use the actual GCP once it's appropriate
238
- final long globalCheckpoint = startingSeqNo - 1 ;
239
- // blindly create the lease. TODO integrate this with the recovery process
240
- shard .addPeerRecoveryRetentionLease (
241
- request .targetNode ().getId (), globalCheckpoint , establishRetentionLeaseStep );
242
- } catch (RetentionLeaseAlreadyExistsException e ) {
243
- logger .debug ("peer-recovery retention lease already exists" , e );
244
- establishRetentionLeaseStep .onResponse (null );
245
- }
246
- }, shardId + " establishing retention lease for [" + request .targetAllocationId () + "]" ,
243
+ try {
244
+ // conservative estimate of the GCP for creating the lease. TODO use the actual GCP once it's appropriate
245
+ final long globalCheckpoint = startingSeqNo - 1 ;
246
+ // blindly create the lease. TODO integrate this with the recovery process
247
+ shard .addPeerRecoveryRetentionLease (request .targetNode ().getId (), globalCheckpoint ,
248
+ new ThreadedActionListener <>(logger , shard .getThreadPool (),
249
+ ThreadPool .Names .GENERIC , establishRetentionLeaseStep , false ));
250
+ } catch (RetentionLeaseAlreadyExistsException e ) {
251
+ logger .debug ("peer-recovery retention lease already exists" , e );
252
+ establishRetentionLeaseStep .onResponse (null );
253
+ }
254
+ }, shardId + " establishing retention lease for [" + request .targetAllocationId () + "]" ,
247
255
shard , cancellableThreads , logger );
248
256
} else {
249
257
establishRetentionLeaseStep .onResponse (null );
250
258
}
251
259
}, onFailure );
252
260
253
261
establishRetentionLeaseStep .whenComplete (r -> {
262
+ Transports .assertNotTransportThread (RecoverySourceHandler .this + "[prepareTargetForTranslog]" );
254
263
// For a sequence based recovery, the target can keep its local translog
255
264
prepareTargetForTranslog (isSequenceNumberBasedRecovery == false ,
256
265
shard .estimateNumberOfHistoryOperations ("peer-recovery" , startingSeqNo ), prepareEngineStep );
257
266
}, onFailure );
258
267
259
268
prepareEngineStep .whenComplete (prepareEngineTime -> {
269
+ Transports .assertNotTransportThread (RecoverySourceHandler .this + "[phase2]" );
260
270
/*
261
271
* add shard to replication group (shard will receive replication requests from this point on) now that engine is open.
262
272
* This means that any document indexed into the primary after this will be replicated to this replica as well
0 commit comments