1515import org .elasticsearch .action .support .PlainActionFuture ;
1616import org .elasticsearch .cluster .node .DiscoveryNode ;
1717import org .elasticsearch .cluster .node .DiscoveryNodeUtils ;
18+ import org .elasticsearch .common .breaker .CircuitBreaker ;
19+ import org .elasticsearch .common .breaker .CircuitBreakingException ;
1820import org .elasticsearch .common .settings .Settings ;
1921import org .elasticsearch .common .util .concurrent .ConcurrentCollections ;
2022import org .elasticsearch .common .util .concurrent .EsExecutors ;
4042import java .util .HashMap ;
4143import java .util .List ;
4244import java .util .Map ;
45+ import java .util .Objects ;
4346import java .util .Queue ;
4447import java .util .Set ;
4548import java .util .concurrent .Executor ;
@@ -85,7 +88,7 @@ public void setThreadPool() {
8588 }
8689
8790 @ After
88- public void shutdownThreadPool () throws Exception {
91+ public void shutdownThreadPool () {
8992 terminate (threadPool );
9093 }
9194
@@ -109,8 +112,7 @@ public void testOnePass() {
109112 Queue <NodeRequest > sent = ConcurrentCollections .newQueue ();
110113 var future = sendRequests (targetShards , randomBoolean (), (node , shardIds , aliasFilters , listener ) -> {
111114 sent .add (new NodeRequest (node , shardIds , aliasFilters ));
112- var resp = new DataNodeComputeResponse (List .of (), Map .of ());
113- runWithDelay (() -> listener .onResponse (resp ));
115+ runWithDelay (() -> listener .onResponse (new DataNodeComputeResponse (List .of (), Map .of ())));
114116 });
115117 safeGet (future );
116118 assertThat (sent .size (), equalTo (2 ));
@@ -123,8 +125,7 @@ public void testMissingShards() {
123125 var future = sendRequests (targetShards , false , (node , shardIds , aliasFilters , listener ) -> {
124126 fail ("expect no data-node request is sent when target shards are missing" );
125127 });
126- var error = expectThrows (NoShardAvailableActionException .class , future ::actionGet );
127- assertThat (error .getMessage (), containsString ("no shard copies found" ));
128+ expectThrows (NoShardAvailableActionException .class , containsString ("no shard copies found" ), future ::actionGet );
128129 }
129130 {
130131 var targetShards = List .of (targetShard (shard1 , node1 ), targetShard (shard3 ), targetShard (shard4 , node2 , node3 ));
@@ -244,6 +245,34 @@ public void testAllowPartialResults() {
244245 assertThat (resp .successfulShards , equalTo (1 ));
245246 }
246247
248+ public void testNonFatalErrorIsRetriedOnAnotherShard () {
249+ var targetShards = List .of (targetShard (shard1 , node1 , node2 ));
250+ Queue <NodeRequest > sent = ConcurrentCollections .newQueue ();
251+ var response = safeGet (sendRequests (targetShards , false , (node , shardIds , aliasFilters , listener ) -> {
252+ sent .add (new NodeRequest (node , shardIds , aliasFilters ));
253+ if (Objects .equals (node1 , node )) {
254+ runWithDelay (() -> listener .onFailure (new CircuitBreakingException ("cbe" , CircuitBreaker .Durability .TRANSIENT ), false ));
255+ } else {
256+ runWithDelay (() -> listener .onResponse (new DataNodeComputeResponse (List .of (), Map .of ())));
257+ }
258+ }));
259+ assertThat (response .totalShards , equalTo (1 ));
260+ assertThat (response .successfulShards , equalTo (1 ));
261+ assertThat (response .failedShards , equalTo (0 ));
262+ assertThat (sent .size (), equalTo (2 ));
263+ }
264+
265+ public void testNonFatalFailedOnAllNodes () {
266+ var targetShards = List .of (targetShard (shard1 , node1 , node2 ));
267+ Queue <NodeRequest > sent = ConcurrentCollections .newQueue ();
268+ var future = sendRequests (targetShards , false , (node , shardIds , aliasFilters , listener ) -> {
269+ sent .add (new NodeRequest (node , shardIds , aliasFilters ));
270+ runWithDelay (() -> listener .onFailure (new CircuitBreakingException ("cbe" , CircuitBreaker .Durability .TRANSIENT ), false ));
271+ });
272+ expectThrows (CircuitBreakingException .class , equalTo ("cbe" ), future ::actionGet );
273+ assertThat (sent .size (), equalTo (2 ));
274+ }
275+
247276 static DataNodeRequestSender .TargetShard targetShard (ShardId shardId , DiscoveryNode ... nodes ) {
248277 return new DataNodeRequestSender .TargetShard (shardId , new ArrayList <>(Arrays .asList (nodes )), null );
249278 }
0 commit comments