Skip to content

Commit 473468d

Browse files
committed
[ML] Better error when persistent task assignment disabled (#52014)
Changes the misleading error message when attempting to open a job while the "cluster.persistent_tasks.allocation.enable" setting is set to "none" to a clearer message that names the setting. Closes #51956
1 parent 8785457 commit 473468d

File tree

4 files changed

+54
-3
lines changed

4 files changed

+54
-3
lines changed

server/src/main/java/org/elasticsearch/persistent/decider/EnableAssignmentDecider.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public class EnableAssignmentDecider {
4343

4444
public static final Setting<Allocation> CLUSTER_TASKS_ALLOCATION_ENABLE_SETTING =
4545
new Setting<>("cluster.persistent_tasks.allocation.enable", Allocation.ALL.toString(), Allocation::fromString, Dynamic, NodeScope);
46+
public static final String ALLOCATION_NONE_EXPLANATION = "no persistent task assignments are allowed due to cluster settings";
4647

4748
private volatile Allocation enableAssignment;
4849

@@ -64,7 +65,7 @@ public void setEnableAssignment(final Allocation enableAssignment) {
6465
*/
6566
public AssignmentDecision canAssign() {
6667
if (enableAssignment == Allocation.NONE) {
67-
return new AssignmentDecision(AssignmentDecision.Type.NO, "no persistent task assignments are allowed due to cluster settings");
68+
return new AssignmentDecision(AssignmentDecision.Type.NO, ALLOCATION_NONE_EXPLANATION);
6869
}
6970
return AssignmentDecision.YES;
7071
}

x-pack/plugin/ml/qa/native-multi-node-tests/src/test/java/org/elasticsearch/xpack/ml/integration/MlJobIT.java

+36
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,42 @@ public void testCreateJob_WithClashingFieldMappingsFails() throws Exception {
398398
"avoid the clash by assigning a dedicated results index"));
399399
}
400400

401+
public void testOpenJobFailsWhenPersistentTaskAssignmentDisabled() throws Exception {
402+
String jobId = "open-job-with-persistent-task-assignment-disabled";
403+
createFarequoteJob(jobId);
404+
405+
Request disablePersistentTaskAssignmentRequest = new Request("PUT", "_cluster/settings");
406+
disablePersistentTaskAssignmentRequest.setJsonEntity("{\n" +
407+
" \"transient\": {\n" +
408+
" \"cluster.persistent_tasks.allocation.enable\": \"none\"\n" +
409+
" }\n" +
410+
"}");
411+
Response disablePersistentTaskAssignmentResponse = client().performRequest(disablePersistentTaskAssignmentRequest);
412+
assertThat(entityAsMap(disablePersistentTaskAssignmentResponse), hasEntry("acknowledged", true));
413+
414+
try {
415+
ResponseException exception = expectThrows(
416+
ResponseException.class,
417+
() -> client().performRequest(
418+
new Request("POST", MachineLearning.BASE_PATH + "anomaly_detectors/" + jobId + "/_open")));
419+
assertThat(exception.getResponse().getStatusLine().getStatusCode(), equalTo(429));
420+
assertThat(EntityUtils.toString(exception.getResponse().getEntity()),
421+
containsString("Cannot open jobs because persistent task assignment is disabled by the " +
422+
"[cluster.persistent_tasks.allocation.enable] setting"));
423+
} finally {
424+
// Try to revert the cluster setting change even if the test fails,
425+
// because otherwise this setting will cause many other tests to fail
426+
Request enablePersistentTaskAssignmentRequest = new Request("PUT", "_cluster/settings");
427+
enablePersistentTaskAssignmentRequest.setJsonEntity("{\n" +
428+
" \"transient\": {\n" +
429+
" \"cluster.persistent_tasks.allocation.enable\": \"all\"\n" +
430+
" }\n" +
431+
"}");
432+
Response enablePersistentTaskAssignmentResponse = client().performRequest(disablePersistentTaskAssignmentRequest);
433+
assertThat(entityAsMap(enablePersistentTaskAssignmentResponse), hasEntry("acknowledged", true));
434+
}
435+
}
436+
401437
public void testDeleteJob() throws Exception {
402438
String jobId = "delete-job-job";
403439
String indexName = AnomalyDetectorsIndexFields.RESULTS_INDEX_PREFIX + AnomalyDetectorsIndexFields.RESULTS_INDEX_DEFAULT;

x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/action/TransportOpenJobAction.java

+15-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.elasticsearch.persistent.PersistentTasksCustomMetaData;
3737
import org.elasticsearch.persistent.PersistentTasksExecutor;
3838
import org.elasticsearch.persistent.PersistentTasksService;
39+
import org.elasticsearch.persistent.decider.EnableAssignmentDecider;
3940
import org.elasticsearch.rest.RestStatus;
4041
import org.elasticsearch.tasks.TaskId;
4142
import org.elasticsearch.threadpool.ThreadPool;
@@ -558,7 +559,13 @@ public boolean test(PersistentTasksCustomMetaData.PersistentTask<?> persistentTa
558559
assignment.isAssigned() == false) {
559560
OpenJobAction.JobParams params = (OpenJobAction.JobParams) persistentTask.getParams();
560561
// Assignment has failed on the master node despite passing our "fast fail" validation
561-
exception = makeNoSuitableNodesException(logger, params.getJobId(), assignment.getExplanation());
562+
if (assignment.equals(AWAITING_UPGRADE)) {
563+
exception = makeCurrentlyBeingUpgradedException(logger, params.getJobId(), assignment.getExplanation());
564+
} else if (assignment.getExplanation().contains("[" + EnableAssignmentDecider.ALLOCATION_NONE_EXPLANATION + "]")) {
565+
exception = makeAssignmentsNotAllowedException(logger, params.getJobId());
566+
} else {
567+
exception = makeNoSuitableNodesException(logger, params.getJobId(), assignment.getExplanation());
568+
}
562569
// The persistent task should be cancelled so that the observed outcome is the
563570
// same as if the "fast fail" validation on the coordinating node had failed
564571
shouldCancel = true;
@@ -598,6 +605,13 @@ static ElasticsearchException makeNoSuitableNodesException(Logger logger, String
598605
RestStatus.TOO_MANY_REQUESTS, detail);
599606
}
600607

608+
static ElasticsearchException makeAssignmentsNotAllowedException(Logger logger, String jobId) {
609+
String msg = "Cannot open jobs because persistent task assignment is disabled by the ["
610+
+ EnableAssignmentDecider.CLUSTER_TASKS_ALLOCATION_ENABLE_SETTING.getKey() + "] setting";
611+
logger.warn("[{}] {}", jobId, msg);
612+
return new ElasticsearchStatusException(msg, RestStatus.TOO_MANY_REQUESTS);
613+
}
614+
601615
static ElasticsearchException makeCurrentlyBeingUpgradedException(Logger logger, String jobId, String explanation) {
602616
String msg = "Cannot open jobs when upgrade mode is enabled";
603617
logger.warn("[{}] {}", jobId, msg);

x-pack/plugin/src/test/resources/rest-api-spec/test/ml/jobs_crud.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1425,7 +1425,7 @@
14251425
- match: { job_id: "persistent-task-allocation-allowed-test" }
14261426

14271427
- do:
1428-
catch: /no persistent task assignments are allowed due to cluster settings/
1428+
catch: /Cannot open jobs because persistent task assignment is disabled by the \[cluster.persistent_tasks.allocation.enable\] setting/
14291429
ml.open_job:
14301430
job_id: persistent-task-allocation-allowed-test
14311431

0 commit comments

Comments
 (0)