|
|
@@ -15,13 +15,10 @@ import org.elasticsearch.action.search.SearchResponse;
|
|
|
import org.elasticsearch.action.support.IndicesOptions;
|
|
|
import org.elasticsearch.client.Client;
|
|
|
import org.elasticsearch.client.ParentTaskAssigningClient;
|
|
|
-import org.elasticsearch.common.Nullable;
|
|
|
import org.elasticsearch.common.Strings;
|
|
|
-import org.elasticsearch.common.bytes.BytesReference;
|
|
|
import org.elasticsearch.common.settings.Settings;
|
|
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
|
|
import org.elasticsearch.index.query.QueryBuilders;
|
|
|
-import org.elasticsearch.search.SearchHit;
|
|
|
import org.elasticsearch.threadpool.ThreadPool;
|
|
|
import org.elasticsearch.xpack.core.ClientHelper;
|
|
|
import org.elasticsearch.xpack.core.ml.MlStatsIndex;
|
|
|
@@ -139,11 +136,11 @@ public class AnalyticsProcessManager {
|
|
|
}
|
|
|
|
|
|
// Fetch existing model state (if any)
|
|
|
- BytesReference state = getModelState(config);
|
|
|
+ final boolean hasState = hasModelState(config);
|
|
|
|
|
|
boolean isProcessStarted;
|
|
|
try {
|
|
|
- isProcessStarted = processContext.startProcess(dataExtractorFactory, task, state);
|
|
|
+ isProcessStarted = processContext.startProcess(dataExtractorFactory, task, hasState);
|
|
|
} catch (Exception e) {
|
|
|
processContext.stop();
|
|
|
task.setFailed(processContext.getFailureReason() == null ?
|
|
|
@@ -153,7 +150,7 @@ public class AnalyticsProcessManager {
|
|
|
|
|
|
if (isProcessStarted) {
|
|
|
executorServiceForProcess.execute(() -> processContext.resultProcessor.get().process(processContext.process.get()));
|
|
|
- executorServiceForProcess.execute(() -> processData(task, processContext, state));
|
|
|
+ executorServiceForProcess.execute(() -> processData(task, processContext, hasState));
|
|
|
} else {
|
|
|
processContextByAllocation.remove(task.getAllocationId());
|
|
|
auditor.info(config.getId(), Messages.DATA_FRAME_ANALYTICS_AUDIT_FINISHED_ANALYSIS);
|
|
|
@@ -162,23 +159,22 @@ public class AnalyticsProcessManager {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- @Nullable
|
|
|
- private BytesReference getModelState(DataFrameAnalyticsConfig config) {
|
|
|
+ private boolean hasModelState(DataFrameAnalyticsConfig config) {
|
|
|
if (config.getAnalysis().persistsState() == false) {
|
|
|
- return null;
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
try (ThreadContext.StoredContext ignore = client.threadPool().getThreadContext().stashWithOrigin(ML_ORIGIN)) {
|
|
|
SearchResponse searchResponse = client.prepareSearch(AnomalyDetectorsIndex.jobStateIndexPattern())
|
|
|
.setSize(1)
|
|
|
- .setQuery(QueryBuilders.idsQuery().addIds(config.getAnalysis().getStateDocId(config.getId())))
|
|
|
+ .setFetchSource(false)
|
|
|
+ .setQuery(QueryBuilders.idsQuery().addIds(config.getAnalysis().getStateDocIdPrefix(config.getId()) + "1"))
|
|
|
.get();
|
|
|
- SearchHit[] hits = searchResponse.getHits().getHits();
|
|
|
- return hits.length == 0 ? null : hits[0].getSourceRef();
|
|
|
+ return searchResponse.getHits().getHits().length == 1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void processData(DataFrameAnalyticsTask task, ProcessContext processContext, BytesReference state) {
|
|
|
+ private void processData(DataFrameAnalyticsTask task, ProcessContext processContext, boolean hasState) {
|
|
|
LOGGER.info("[{}] Started loading data", processContext.config.getId());
|
|
|
auditor.info(processContext.config.getId(), Messages.getMessage(Messages.DATA_FRAME_ANALYTICS_AUDIT_STARTED_LOADING_DATA));
|
|
|
|
|
|
@@ -193,7 +189,7 @@ public class AnalyticsProcessManager {
|
|
|
process.writeEndOfDataMessage();
|
|
|
process.flushStream();
|
|
|
|
|
|
- restoreState(task, config, state, process);
|
|
|
+ restoreState(task, config, process, hasState);
|
|
|
|
|
|
LOGGER.info("[{}] Started analyzing", processContext.config.getId());
|
|
|
auditor.info(processContext.config.getId(), Messages.getMessage(Messages.DATA_FRAME_ANALYTICS_AUDIT_STARTED_ANALYZING));
|
|
|
@@ -297,14 +293,14 @@ public class AnalyticsProcessManager {
|
|
|
process.writeRecord(headerRecord);
|
|
|
}
|
|
|
|
|
|
- private void restoreState(DataFrameAnalyticsTask task, DataFrameAnalyticsConfig config, @Nullable BytesReference state,
|
|
|
- AnalyticsProcess<AnalyticsResult> process) {
|
|
|
+ private void restoreState(DataFrameAnalyticsTask task, DataFrameAnalyticsConfig config, AnalyticsProcess<AnalyticsResult> process,
|
|
|
+ boolean hasState) {
|
|
|
if (config.getAnalysis().persistsState() == false) {
|
|
|
LOGGER.debug("[{}] Analysis does not support state", config.getId());
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if (state == null) {
|
|
|
+ if (hasState == false) {
|
|
|
LOGGER.debug("[{}] No model state available to restore", config.getId());
|
|
|
return;
|
|
|
}
|
|
|
@@ -313,7 +309,7 @@ public class AnalyticsProcessManager {
|
|
|
auditor.info(config.getId(), Messages.DATA_FRAME_ANALYTICS_AUDIT_RESTORING_STATE);
|
|
|
|
|
|
try (ThreadContext.StoredContext ignore = client.threadPool().getThreadContext().stashWithOrigin(ML_ORIGIN)) {
|
|
|
- process.restoreState(state);
|
|
|
+ process.restoreState(client, config.getAnalysis().getStateDocIdPrefix(config.getId()));
|
|
|
} catch (Exception e) {
|
|
|
LOGGER.error(new ParameterizedMessage("[{}] Failed to restore state", process.getConfig().jobId()), e);
|
|
|
task.setFailed(ExceptionsHelper.serverError("Failed to restore state: " + e.getMessage()));
|
|
|
@@ -321,9 +317,9 @@ public class AnalyticsProcessManager {
|
|
|
}
|
|
|
|
|
|
private AnalyticsProcess<AnalyticsResult> createProcess(DataFrameAnalyticsTask task, DataFrameAnalyticsConfig config,
|
|
|
- AnalyticsProcessConfig analyticsProcessConfig, @Nullable BytesReference state) {
|
|
|
- AnalyticsProcess<AnalyticsResult> process =
|
|
|
- processFactory.createAnalyticsProcess(config, analyticsProcessConfig, state, executorServiceForProcess, onProcessCrash(task));
|
|
|
+ AnalyticsProcessConfig analyticsProcessConfig, boolean hasState) {
|
|
|
+ AnalyticsProcess<AnalyticsResult> process = processFactory.createAnalyticsProcess(
|
|
|
+ config, analyticsProcessConfig, hasState, executorServiceForProcess, onProcessCrash(task));
|
|
|
if (process.isProcessAlive() == false) {
|
|
|
throw ExceptionsHelper.serverError("Failed to start data frame analytics process");
|
|
|
}
|
|
|
@@ -467,7 +463,7 @@ public class AnalyticsProcessManager {
|
|
|
*/
|
|
|
synchronized boolean startProcess(DataFrameDataExtractorFactory dataExtractorFactory,
|
|
|
DataFrameAnalyticsTask task,
|
|
|
- @Nullable BytesReference state) {
|
|
|
+ boolean hasState) {
|
|
|
if (task.isStopping()) {
|
|
|
// The job was stopped before we started the process so no need to start it
|
|
|
return false;
|
|
|
@@ -483,7 +479,7 @@ public class AnalyticsProcessManager {
|
|
|
LOGGER.info("[{}] no data found to analyze. Will not start analytics native process.", config.getId());
|
|
|
return false;
|
|
|
}
|
|
|
- process.set(createProcess(task, config, analyticsProcessConfig, state));
|
|
|
+ process.set(createProcess(task, config, analyticsProcessConfig, hasState));
|
|
|
resultProcessor.set(createResultProcessor(task, dataExtractorFactory));
|
|
|
return true;
|
|
|
}
|