@@ -48,9 +48,9 @@ public void testNoShardMovement() {
4848 final var originalNode0ThreadPoolStats = randomThreadPoolUsageStats ();
4949 final var originalNode1ThreadPoolStats = randomThreadPoolUsageStats ();
5050 final var allocation = createRoutingAllocationWithRandomisedWriteLoads (
51+ Set .of (),
5152 originalNode0ThreadPoolStats ,
52- originalNode1ThreadPoolStats ,
53- Set .of ()
53+ originalNode1ThreadPoolStats
5454 );
5555
5656 final var shardMovementWriteLoadSimulator = new ShardMovementWriteLoadSimulator (allocation );
@@ -66,13 +66,15 @@ public void testNoShardMovement() {
6666 );
6767 }
6868
69- public void testMovementOfAShardWillMoveThreadPoolUtilisation () {
69+ public void testMovementOfAShardWillMoveThreadPoolStats () {
7070 final var originalNode0ThreadPoolStats = randomThreadPoolUsageStats ();
7171 final var originalNode1ThreadPoolStats = randomThreadPoolUsageStats ();
72+ final var originalNode2ThreadPoolStats = randomThreadPoolUsageStats ();
7273 final var allocation = createRoutingAllocationWithRandomisedWriteLoads (
74+ Set .of (),
7375 originalNode0ThreadPoolStats ,
7476 originalNode1ThreadPoolStats ,
75- Set . of ()
77+ originalNode2ThreadPoolStats
7678 );
7779 final var shardMovementWriteLoadSimulator = new ShardMovementWriteLoadSimulator (allocation );
7880
@@ -84,7 +86,7 @@ public void testMovementOfAShardWillMoveThreadPoolUtilisation() {
8486 final ShardRouting movedAndStartedShard = allocation .routingNodes ().startShard (moveShardTuple .v2 (), NOOP , expectedShardSize );
8587
8688 final var calculatedNodeUsageStats = shardMovementWriteLoadSimulator .simulatedNodeUsageStatsForThreadPools ();
87- assertThat (calculatedNodeUsageStats , Matchers .aMapWithSize (2 ));
89+ assertThat (calculatedNodeUsageStats , Matchers .aMapWithSize (3 ));
8890
8991 final var shardWriteLoad = allocation .clusterInfo ().getShardWriteLoads ().get (randomShard .shardId ());
9092 final var expectedUtilisationReductionAtSource = shardWriteLoad / originalNode0ThreadPoolStats .totalThreadPoolThreads ();
@@ -109,6 +111,19 @@ public void testMovementOfAShardWillMoveThreadPoolUtilisation() {
109111 closeTo (expectedUtilisationIncreaseAtDestination , 0.001f )
110112 );
111113
114+ // Queue latency reduced for node_0 since it has a shard moved out
115+ assertThat (getMaxThreadPoolQueueLatency (shardMovementWriteLoadSimulator , "node_0" ), equalTo (0L ));
116+ // Queue latency stays unchanged for node_1 since it only has a shard moved in
117+ assertThat (
118+ getMaxThreadPoolQueueLatency (shardMovementWriteLoadSimulator , "node_1" ),
119+ equalTo (originalNode1ThreadPoolStats .maxThreadPoolQueueLatencyMillis ())
120+ );
121+ // Queue latency stays unchanged for node_2 since it has no shard movement
122+ assertThat (
123+ getMaxThreadPoolQueueLatency (shardMovementWriteLoadSimulator , "node_2" ),
124+ equalTo (originalNode2ThreadPoolStats .maxThreadPoolQueueLatencyMillis ())
125+ );
126+
112127 // Then move it back
113128 final var moveBackTuple = allocation .routingNodes ()
114129 .relocateShard (movedAndStartedShard , "node_0" , expectedShardSize , "testing" , NOOP );
@@ -123,15 +138,25 @@ public void testMovementOfAShardWillMoveThreadPoolUtilisation() {
123138 getAverageWritePoolUtilization (shardMovementWriteLoadSimulator , "node_1" ),
124139 equalTo (originalNode1ThreadPoolStats .averageThreadPoolUtilization ())
125140 );
141+
142+ // We intentionally keep things simple so that if a shard has moved away from a node, its queue latency is reduced to zero
143+ // regardless of whether other shards have subsequently moved onto or out of the same node.
144+ assertThat (getMaxThreadPoolQueueLatency (shardMovementWriteLoadSimulator , "node_0" ), equalTo (0L ));
145+ assertThat (getMaxThreadPoolQueueLatency (shardMovementWriteLoadSimulator , "node_1" ), equalTo (0L ));
146+ // Queue latency stays unchanged for node_2 since it has no shard movement
147+ assertThat (
148+ getMaxThreadPoolQueueLatency (shardMovementWriteLoadSimulator , "node_2" ),
149+ equalTo (originalNode2ThreadPoolStats .maxThreadPoolQueueLatencyMillis ())
150+ );
126151 }
127152
128153 public void testMovementBetweenNodesWithNoThreadPoolAndWriteLoadStats () {
129154 final var originalNode0ThreadPoolStats = randomBoolean () ? randomThreadPoolUsageStats () : null ;
130155 final var originalNode1ThreadPoolStats = randomBoolean () ? randomThreadPoolUsageStats () : null ;
131156 final var allocation = createRoutingAllocationWithRandomisedWriteLoads (
157+ new HashSet <>(randomSubsetOf (Arrays .asList (INDICES ))),
132158 originalNode0ThreadPoolStats ,
133- originalNode1ThreadPoolStats ,
134- new HashSet <>(randomSubsetOf (Arrays .asList (INDICES )))
159+ originalNode1ThreadPoolStats
135160 );
136161 final var shardMovementWriteLoadSimulator = new ShardMovementWriteLoadSimulator (allocation );
137162
@@ -147,12 +172,29 @@ public void testMovementBetweenNodesWithNoThreadPoolAndWriteLoadStats() {
147172 assertThat (simulated .containsKey ("node_1" ), equalTo (originalNode1ThreadPoolStats != null ));
148173 }
149174
175+ public void testUpdateThreadPoolQueueLatencyWithShardMovements () {
176+ final long originalLatency = randomNonNegativeLong ();
177+
178+ assertThat (
179+ ShardMovementWriteLoadSimulator .adjustThreadPoolQueueLatencyWithShardMovements (originalLatency , false ),
180+ equalTo (originalLatency )
181+ );
182+
183+ assertThat (ShardMovementWriteLoadSimulator .adjustThreadPoolQueueLatencyWithShardMovements (originalLatency , true ), equalTo (0L ));
184+ }
185+
150186 private float getAverageWritePoolUtilization (ShardMovementWriteLoadSimulator shardMovementWriteLoadSimulator , String nodeId ) {
151187 final var generatedNodeUsageStates = shardMovementWriteLoadSimulator .simulatedNodeUsageStatsForThreadPools ();
152188 final var node0WritePoolStats = generatedNodeUsageStates .get (nodeId ).threadPoolUsageStatsMap ().get ("write" );
153189 return node0WritePoolStats .averageThreadPoolUtilization ();
154190 }
155191
192+ private long getMaxThreadPoolQueueLatency (ShardMovementWriteLoadSimulator shardMovementWriteLoadSimulator , String nodeId ) {
193+ final var generatedNodeUsageStates = shardMovementWriteLoadSimulator .simulatedNodeUsageStatsForThreadPools ();
194+ final var writePoolStats = generatedNodeUsageStates .get (nodeId ).threadPoolUsageStatsMap ().get ("write" );
195+ return writePoolStats .maxThreadPoolQueueLatencyMillis ();
196+ }
197+
156198 private NodeUsageStatsForThreadPools .ThreadPoolUsageStats randomThreadPoolUsageStats () {
157199 return new NodeUsageStatsForThreadPools .ThreadPoolUsageStats (
158200 randomIntBetween (4 , 16 ),
@@ -162,16 +204,16 @@ private NodeUsageStatsForThreadPools.ThreadPoolUsageStats randomThreadPoolUsageS
162204 }
163205
164206 private RoutingAllocation createRoutingAllocationWithRandomisedWriteLoads (
165- NodeUsageStatsForThreadPools .ThreadPoolUsageStats node0ThreadPoolStats ,
166- NodeUsageStatsForThreadPools .ThreadPoolUsageStats node1ThreadPoolStats ,
167- Set <String > indicesWithNoWriteLoad
207+ Set <String > indicesWithNoWriteLoad ,
208+ NodeUsageStatsForThreadPools .ThreadPoolUsageStats ... arrayOfNodeThreadPoolStats
168209 ) {
169210 final Map <String , NodeUsageStatsForThreadPools > nodeUsageStats = new HashMap <>();
170- if (node0ThreadPoolStats != null ) {
171- nodeUsageStats .put ("node_0" , new NodeUsageStatsForThreadPools ("node_0" , Map .of ("write" , node0ThreadPoolStats )));
172- }
173- if (node1ThreadPoolStats != null ) {
174- nodeUsageStats .put ("node_1" , new NodeUsageStatsForThreadPools ("node_1" , Map .of ("write" , node1ThreadPoolStats )));
211+ for (int i = 0 ; i < arrayOfNodeThreadPoolStats .length ; i ++) {
212+ final var nodeThreadPoolStats = arrayOfNodeThreadPoolStats [i ];
213+ if (nodeThreadPoolStats != null ) {
214+ final var nodeId = "node_" + i ;
215+ nodeUsageStats .put (nodeId , new NodeUsageStatsForThreadPools (nodeId , Map .of ("write" , nodeThreadPoolStats )));
216+ }
175217 }
176218
177219 final ClusterState clusterState = createClusterState ();
0 commit comments