35
35
import org .elasticsearch .common .unit .ByteSizeValue ;
36
36
import org .elasticsearch .common .util .concurrent .AbstractRunnable ;
37
37
import org .elasticsearch .common .xcontent .XContentBuilder ;
38
+ import org .elasticsearch .core .internal .io .IOUtils ;
38
39
import org .elasticsearch .index .seqno .SequenceNumbers ;
39
40
import org .elasticsearch .index .translog .Translog ;
40
41
import org .elasticsearch .tasks .Task ;
@@ -80,48 +81,25 @@ void setChunkSize(ByteSizeValue chunkSize) { // only settable for tests
80
81
}
81
82
82
83
public void resync (final IndexShard indexShard , final ActionListener <ResyncTask > listener ) {
83
- ActionListener < ResyncTask > resyncListener = null ;
84
+ Translog . Snapshot snapshot = null ;
84
85
try {
85
86
final long startingSeqNo = indexShard .getGlobalCheckpoint () + 1 ;
86
- Translog .Snapshot snapshot = indexShard .newTranslogSnapshotFromMinSeqNo (startingSeqNo );
87
87
final long maxSeqNo = indexShard .seqNoStats ().getMaxSeqNo ();
88
- resyncListener = new ActionListener <ResyncTask >() {
89
- @ Override
90
- public void onResponse (final ResyncTask resyncTask ) {
91
- try {
92
- snapshot .close ();
93
- listener .onResponse (resyncTask );
94
- } catch (final Exception e ) {
95
- onFailure (e );
96
- }
97
- }
98
-
99
- @ Override
100
- public void onFailure (final Exception e ) {
101
- try {
102
- snapshot .close ();
103
- } catch (final Exception inner ) {
104
- e .addSuppressed (inner );
105
- } finally {
106
- listener .onFailure (e );
107
- }
108
- }
109
- };
110
- ShardId shardId = indexShard .shardId ();
111
-
88
+ final ShardId shardId = indexShard .shardId ();
112
89
// Wrap translog snapshot to make it synchronized as it is accessed by different threads through SnapshotSender.
113
90
// Even though those calls are not concurrent, snapshot.next() uses non-synchronized state and is not multi-thread-compatible
114
91
// Also fail the resync early if the shard is shutting down
115
- Translog .Snapshot wrappedSnapshot = new Translog .Snapshot () {
116
-
92
+ snapshot = indexShard .newTranslogSnapshotFromMinSeqNo (startingSeqNo );
93
+ final Translog .Snapshot originalSnapshot = snapshot ;
94
+ final Translog .Snapshot wrappedSnapshot = new Translog .Snapshot () {
117
95
@ Override
118
96
public synchronized void close () throws IOException {
119
- snapshot .close ();
97
+ originalSnapshot .close ();
120
98
}
121
99
122
100
@ Override
123
101
public synchronized int totalOperations () {
124
- return snapshot .totalOperations ();
102
+ return originalSnapshot .totalOperations ();
125
103
}
126
104
127
105
@ Override
@@ -132,15 +110,40 @@ public synchronized Translog.Operation next() throws IOException {
132
110
} else {
133
111
assert state == IndexShardState .STARTED : "resync should only happen on a started shard, but state was: " + state ;
134
112
}
135
- return snapshot .next ();
113
+ return originalSnapshot .next ();
136
114
}
137
115
};
116
+ final ActionListener <ResyncTask > resyncListener = new ActionListener <ResyncTask >() {
117
+ @ Override
118
+ public void onResponse (final ResyncTask resyncTask ) {
119
+ try {
120
+ wrappedSnapshot .close ();
121
+ listener .onResponse (resyncTask );
122
+ } catch (final Exception e ) {
123
+ onFailure (e );
124
+ }
125
+ }
126
+
127
+ @ Override
128
+ public void onFailure (final Exception e ) {
129
+ try {
130
+ wrappedSnapshot .close ();
131
+ } catch (final Exception inner ) {
132
+ e .addSuppressed (inner );
133
+ } finally {
134
+ listener .onFailure (e );
135
+ }
136
+ }
137
+ };
138
+
138
139
resync (shardId , indexShard .routingEntry ().allocationId ().getId (), indexShard .getPrimaryTerm (), wrappedSnapshot ,
139
140
startingSeqNo , maxSeqNo , resyncListener );
140
141
} catch (Exception e ) {
141
- if (resyncListener != null ) {
142
- resyncListener .onFailure (e );
143
- } else {
142
+ try {
143
+ IOUtils .close (snapshot );
144
+ } catch (IOException inner ) {
145
+ e .addSuppressed (inner );
146
+ } finally {
144
147
listener .onFailure (e );
145
148
}
146
149
}
0 commit comments