use of org.opensearch.ad.transport.AnomalyDetectorJobResponse in project anomaly-detection by opensearch-project.
the class ADTaskManager method onIndexADTaskResponse.
private void onIndexADTaskResponse(IndexResponse response, ADTask adTask, BiConsumer<IndexResponse, ActionListener<AnomalyDetectorJobResponse>> function, ActionListener<AnomalyDetectorJobResponse> listener) {
if (response == null || response.getResult() != CREATED) {
String errorMsg = getShardsFailure(response);
listener.onFailure(new OpenSearchStatusException(errorMsg, response.status()));
return;
}
adTask.setTaskId(response.getId());
ActionListener<AnomalyDetectorJobResponse> delegatedListener = ActionListener.wrap(r -> {
listener.onResponse(r);
}, e -> {
handleADTaskException(adTask, e);
if (e instanceof DuplicateTaskException) {
listener.onFailure(new OpenSearchStatusException(DETECTOR_IS_RUNNING, RestStatus.BAD_REQUEST));
} else {
// realtime task cache not inited yet when create AD task, so no need to cleanup.
if (adTask.isHistoricalTask()) {
adTaskCacheManager.removeHistoricalTaskCache(adTask.getDetectorId());
}
listener.onFailure(e);
}
});
try {
// multiple start request for one historical detector.
if (adTask.isHistoricalTask()) {
adTaskCacheManager.add(adTask.getDetectorId(), adTask);
}
} catch (Exception e) {
delegatedListener.onFailure(e);
return;
}
if (function != null) {
function.accept(response, delegatedListener);
}
}
use of org.opensearch.ad.transport.AnomalyDetectorJobResponse in project anomaly-detection by opensearch-project.
the class ADTaskManager method setHCDetectorTaskDone.
/**
* Set state for HC detector level task when all entities done.
*
* The state could be FINISHED,FAILED or STOPPED.
* 1. If input task state is FINISHED, will check FINISHED entity task count. If
* there is no FINISHED entity task, will set HC detector level task as FAILED; otherwise
* set as FINISHED.
* 2. If input task state is not FINISHED, will set HC detector level task's state as the same.
*
* @param adTask AD task
* @param state AD task state
* @param listener action listener
*/
public void setHCDetectorTaskDone(ADTask adTask, ADTaskState state, ActionListener<AnomalyDetectorJobResponse> listener) {
String detectorId = adTask.getDetectorId();
String taskId = adTask.isEntityTask() ? adTask.getParentTaskId() : adTask.getTaskId();
String detectorTaskId = adTask.getDetectorLevelTaskId();
ActionListener<UpdateResponse> wrappedListener = ActionListener.wrap(response -> {
logger.info("Historical HC detector done with state: {}. Remove from cache, detector id:{}", state.name(), detectorId);
adTaskCacheManager.removeHistoricalTaskCache(detectorId);
}, e -> {
// Will reset task state when get detector with task or maintain tasks in hourly cron.
if (e instanceof LimitExceededException && e.getMessage().contains(HC_DETECTOR_TASK_IS_UPDATING)) {
logger.warn("HC task is updating, skip this update for task: " + taskId);
} else {
logger.error("Failed to update task: " + taskId, e);
}
adTaskCacheManager.removeHistoricalTaskCache(detectorId);
});
// wait for 2 seconds to acquire updating HC detector task semaphore
long timeoutInMillis = 2000;
if (state == ADTaskState.FINISHED) {
this.countEntityTasksByState(detectorTaskId, ImmutableList.of(ADTaskState.FINISHED), ActionListener.wrap(r -> {
logger.info("number of finished entity tasks: {}, for detector {}", r, adTask.getDetectorId());
// Set task as FAILED if no finished entity task; otherwise set as FINISHED
ADTaskState hcDetectorTaskState = r == 0 ? ADTaskState.FAILED : ADTaskState.FINISHED;
// execute in AD batch task thread pool in case waiting for semaphore waste any shared OpenSearch thread pool
threadPool.executor(AD_BATCH_TASK_THREAD_POOL_NAME).execute(() -> {
updateADHCDetectorTask(detectorId, taskId, ImmutableMap.of(STATE_FIELD, hcDetectorTaskState.name(), TASK_PROGRESS_FIELD, 1.0, EXECUTION_END_TIME_FIELD, Instant.now().toEpochMilli()), timeoutInMillis, wrappedListener);
});
}, e -> {
logger.error("Failed to get finished entity tasks", e);
String errorMessage = getErrorMessage(e);
threadPool.executor(AD_BATCH_TASK_THREAD_POOL_NAME).execute(() -> {
updateADHCDetectorTask(detectorId, taskId, ImmutableMap.of(STATE_FIELD, // set as FAILED if fail to get finished entity tasks.
ADTaskState.FAILED.name(), TASK_PROGRESS_FIELD, 1.0, ERROR_FIELD, errorMessage, EXECUTION_END_TIME_FIELD, Instant.now().toEpochMilli()), timeoutInMillis, wrappedListener);
});
}));
} else {
threadPool.executor(AD_BATCH_TASK_THREAD_POOL_NAME).execute(() -> {
updateADHCDetectorTask(detectorId, taskId, ImmutableMap.of(STATE_FIELD, state.name(), ERROR_FIELD, adTask.getError(), EXECUTION_END_TIME_FIELD, Instant.now().toEpochMilli()), timeoutInMillis, wrappedListener);
});
}
listener.onResponse(new AnomalyDetectorJobResponse(taskId, 0, 0, 0, RestStatus.OK));
}
use of org.opensearch.ad.transport.AnomalyDetectorJobResponse in project anomaly-detection by opensearch-project.
the class ADTaskManager method runNextEntityForHCADHistorical.
/**
* Scale task slots and check the scale delta:
* 1. If scale delta is negative, that means we need to scale down, will not start next entity.
* 2. If scale delta is positive, will start next entity in current lane.
*
* This method will be called by {@link org.opensearch.ad.transport.ForwardADTaskTransportAction}.
*
* @param adTask ad entity task
* @param transportService transport service
* @param listener action listener
*/
public void runNextEntityForHCADHistorical(ADTask adTask, TransportService transportService, ActionListener<AnomalyDetectorJobResponse> listener) {
String detectorId = adTask.getDetectorId();
int scaleDelta = scaleTaskSlots(adTask, transportService, ActionListener.wrap(r -> {
logger.debug("Scale up task slots done for detector {}, task {}", detectorId, adTask.getTaskId());
}, e -> {
logger.error("Failed to scale up task slots for task " + adTask.getTaskId(), e);
}));
if (scaleDelta < 0) {
logger.warn("Have scaled down task slots. Will not poll next entity for detector {}, task {}, task slots: {}", detectorId, adTask.getTaskId(), adTaskCacheManager.getDetectorTaskSlots(detectorId));
listener.onResponse(new AnomalyDetectorJobResponse(detectorId, 0, 0, 0, RestStatus.ACCEPTED));
return;
}
client.execute(ADBatchAnomalyResultAction.INSTANCE, new ADBatchAnomalyResultRequest(adTask), ActionListener.wrap(r -> {
String remoteOrLocal = r.isRunTaskRemotely() ? "remote" : "local";
logger.info("AD entity task {} of detector {} dispatched to {} node {}", adTask.getTaskId(), detectorId, remoteOrLocal, r.getNodeId());
AnomalyDetectorJobResponse anomalyDetectorJobResponse = new AnomalyDetectorJobResponse(detectorId, 0, 0, 0, RestStatus.OK);
listener.onResponse(anomalyDetectorJobResponse);
}, e -> {
listener.onFailure(e);
}));
}
use of org.opensearch.ad.transport.AnomalyDetectorJobResponse in project anomaly-detection by opensearch-project.
the class ADTaskManager method stopHistoricalAnalysis.
private void stopHistoricalAnalysis(String detectorId, Optional<ADTask> adTask, User user, ActionListener<AnomalyDetectorJobResponse> listener) {
if (!adTask.isPresent()) {
listener.onFailure(new ResourceNotFoundException(detectorId, "Detector not started"));
return;
}
if (adTask.get().isDone()) {
listener.onFailure(new ResourceNotFoundException(detectorId, "No running task found"));
return;
}
String taskId = adTask.get().getTaskId();
DiscoveryNode[] dataNodes = hashRing.getNodesWithSameLocalAdVersion();
String userName = user == null ? null : user.getName();
ADCancelTaskRequest cancelTaskRequest = new ADCancelTaskRequest(detectorId, taskId, userName, dataNodes);
client.execute(ADCancelTaskAction.INSTANCE, cancelTaskRequest, ActionListener.wrap(response -> {
listener.onResponse(new AnomalyDetectorJobResponse(taskId, 0, 0, 0, RestStatus.OK));
}, e -> {
logger.error("Failed to cancel AD task " + taskId + ", detector id: " + detectorId, e);
listener.onFailure(e);
}));
}
use of org.opensearch.ad.transport.AnomalyDetectorJobResponse in project anomaly-detection by opensearch-project.
the class ADTaskManager method createNewADTask.
private void createNewADTask(AnomalyDetector detector, DetectionDateRange detectionDateRange, User user, String coordinatingNode, ActionListener<AnomalyDetectorJobResponse> listener) {
String userName = user == null ? null : user.getName();
Instant now = Instant.now();
String taskType = getADTaskType(detector, detectionDateRange).name();
ADTask adTask = new ADTask.Builder().detectorId(detector.getDetectorId()).detector(detector).isLatest(true).taskType(taskType).executionStartTime(now).taskProgress(0.0f).initProgress(0.0f).state(ADTaskState.CREATED.name()).lastUpdateTime(now).startedBy(userName).coordinatingNode(coordinatingNode).detectionDateRange(detectionDateRange).user(user).build();
createADTaskDirectly(adTask, r -> onIndexADTaskResponse(r, adTask, (response, delegatedListener) -> cleanOldAdTaskDocs(response, adTask, delegatedListener), listener), listener);
}
Aggregations