|
55 | 55 | import java.io.IOException;
|
56 | 56 | import java.net.InetAddress;
|
57 | 57 | import java.util.ArrayList;
|
58 |
| -import java.util.Arrays; |
59 | 58 | import java.util.Collections;
|
60 | 59 | import java.util.Date;
|
61 | 60 | import java.util.HashMap;
|
@@ -285,7 +284,7 @@ public void testSelectLeastLoadedMlNode_maxConcurrentOpeningJobs() {
|
285 | 284 | nodeAttr, Collections.emptySet(), Version.CURRENT))
|
286 | 285 | .build();
|
287 | 286 |
|
288 |
| - PersistentTasksCustomMetaData.Builder tasksBuilder = PersistentTasksCustomMetaData.builder(); |
| 287 | + PersistentTasksCustomMetaData.Builder tasksBuilder = PersistentTasksCustomMetaData.builder(); |
289 | 288 | addJobTask("job_id1", "_node_id1", null, tasksBuilder);
|
290 | 289 | addJobTask("job_id2", "_node_id1", null, tasksBuilder);
|
291 | 290 | addJobTask("job_id3", "_node_id2", null, tasksBuilder);
|
@@ -340,6 +339,55 @@ public void testSelectLeastLoadedMlNode_maxConcurrentOpeningJobs() {
|
340 | 339 | assertTrue(result.getExplanation().contains("because node exceeds [2] the maximum number of jobs [2] in opening state"));
|
341 | 340 | }
|
342 | 341 |
|
| 342 | + public void testSelectLeastLoadedMlNode_concurrentOpeningJobsAndStaleFailedJob() { |
| 343 | + Map<String, String> nodeAttr = new HashMap<>(); |
| 344 | + nodeAttr.put(MachineLearning.ML_ENABLED_NODE_ATTR, "true"); |
| 345 | + DiscoveryNodes nodes = DiscoveryNodes.builder() |
| 346 | + .add(new DiscoveryNode("_node_name1", "_node_id1", new TransportAddress(InetAddress.getLoopbackAddress(), 9300), |
| 347 | + nodeAttr, Collections.emptySet(), Version.CURRENT)) |
| 348 | + .add(new DiscoveryNode("_node_name2", "_node_id2", new TransportAddress(InetAddress.getLoopbackAddress(), 9301), |
| 349 | + nodeAttr, Collections.emptySet(), Version.CURRENT)) |
| 350 | + .add(new DiscoveryNode("_node_name3", "_node_id3", new TransportAddress(InetAddress.getLoopbackAddress(), 9302), |
| 351 | + nodeAttr, Collections.emptySet(), Version.CURRENT)) |
| 352 | + .build(); |
| 353 | + |
| 354 | + PersistentTasksCustomMetaData.Builder tasksBuilder = PersistentTasksCustomMetaData.builder(); |
| 355 | + addJobTask("job_id1", "_node_id1", JobState.fromString("failed"), tasksBuilder); |
| 356 | + // This will make the allocation stale for job_id1 |
| 357 | + tasksBuilder.reassignTask(MlMetadata.jobTaskId("job_id1"), new Assignment("_node_id1", "test assignment")); |
| 358 | + addJobTask("job_id2", "_node_id1", null, tasksBuilder); |
| 359 | + addJobTask("job_id3", "_node_id2", null, tasksBuilder); |
| 360 | + addJobTask("job_id4", "_node_id2", null, tasksBuilder); |
| 361 | + addJobTask("job_id5", "_node_id3", null, tasksBuilder); |
| 362 | + addJobTask("job_id6", "_node_id3", null, tasksBuilder); |
| 363 | + PersistentTasksCustomMetaData tasks = tasksBuilder.build(); |
| 364 | + |
| 365 | + ClusterState.Builder csBuilder = ClusterState.builder(new ClusterName("_name")); |
| 366 | + csBuilder.nodes(nodes); |
| 367 | + MetaData.Builder metaData = MetaData.builder(); |
| 368 | + RoutingTable.Builder routingTable = RoutingTable.builder(); |
| 369 | + addJobAndIndices(metaData, routingTable, "job_id1", "job_id2", "job_id3", "job_id4", "job_id5", "job_id6", "job_id7", "job_id8"); |
| 370 | + csBuilder.routingTable(routingTable.build()); |
| 371 | + metaData.putCustom(PersistentTasksCustomMetaData.TYPE, tasks); |
| 372 | + csBuilder.metaData(metaData); |
| 373 | + |
| 374 | + ClusterState cs = csBuilder.build(); |
| 375 | + // Allocation won't be possible if the stale failed job is treated as opening |
| 376 | + Assignment result = TransportOpenJobAction.selectLeastLoadedMlNode("job_id7", cs, 2, 10, 30, logger); |
| 377 | + assertEquals("_node_id1", result.getExecutorNode()); |
| 378 | + |
| 379 | + tasksBuilder = PersistentTasksCustomMetaData.builder(tasks); |
| 380 | + addJobTask("job_id7", "_node_id1", null, tasksBuilder); |
| 381 | + tasks = tasksBuilder.build(); |
| 382 | + |
| 383 | + csBuilder = ClusterState.builder(cs); |
| 384 | + csBuilder.metaData(MetaData.builder(cs.metaData()).putCustom(PersistentTasksCustomMetaData.TYPE, tasks)); |
| 385 | + cs = csBuilder.build(); |
| 386 | + result = TransportOpenJobAction.selectLeastLoadedMlNode("job_id8", cs, 2, 10, 30, logger); |
| 387 | + assertNull("no node selected, because OPENING state", result.getExecutorNode()); |
| 388 | + assertTrue(result.getExplanation().contains("because node exceeds [2] the maximum number of jobs [2] in opening state")); |
| 389 | + } |
| 390 | + |
343 | 391 | public void testSelectLeastLoadedMlNode_noCompatibleJobTypeNodes() {
|
344 | 392 | Map<String, String> nodeAttr = new HashMap<>();
|
345 | 393 | nodeAttr.put(MachineLearning.ML_ENABLED_NODE_ATTR, "true");
|
@@ -678,13 +726,13 @@ private ClusterState getClusterStateWithMappingsWithMetaData(Map<String, Object>
|
678 | 726 |
|
679 | 727 | private static Function<String, Job> jobWithRulesCreator() {
|
680 | 728 | return jobId -> {
|
681 |
| - DetectionRule rule = new DetectionRule.Builder(Arrays.asList( |
| 729 | + DetectionRule rule = new DetectionRule.Builder(Collections.singletonList( |
682 | 730 | new RuleCondition(RuleCondition.AppliesTo.TYPICAL, Operator.LT, 100.0)
|
683 | 731 | )).build();
|
684 | 732 |
|
685 | 733 | Detector.Builder detector = new Detector.Builder("count", null);
|
686 |
| - detector.setRules(Arrays.asList(rule)); |
687 |
| - AnalysisConfig.Builder analysisConfig = new AnalysisConfig.Builder(Arrays.asList(detector.build())); |
| 734 | + detector.setRules(Collections.singletonList(rule)); |
| 735 | + AnalysisConfig.Builder analysisConfig = new AnalysisConfig.Builder(Collections.singletonList(detector.build())); |
688 | 736 | DataDescription.Builder dataDescription = new DataDescription.Builder();
|
689 | 737 | Job.Builder job = new Job.Builder(jobId);
|
690 | 738 | job.setAnalysisConfig(analysisConfig);
|
|
0 commit comments