[ML] Fork on management thread when really opening the job
Original commit: elastic/x-pack-elasticsearch@e528912c23
This commit is contained in:
parent
99e3508267
commit
1bed557911
|
@ -389,22 +389,11 @@ public class OpenJobAction extends Action<OpenJobAction.Request, OpenJobAction.R
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to fork, otherwise we open a job on a network thread:
|
autodetectProcessManager.openJob(request.getJobId(), task.getPersistentTaskId(), request.isIgnoreDowntime(), e2 -> {
|
||||||
threadPool.executor(ThreadPool.Names.MANAGEMENT).execute(new AbstractRunnable() {
|
if (e2 == null) {
|
||||||
@Override
|
listener.onResponse(new TransportResponse.Empty());
|
||||||
public void onFailure(Exception e) {
|
} else {
|
||||||
listener.onFailure(e);
|
listener.onFailure(e2);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doRun() throws Exception {
|
|
||||||
autodetectProcessManager.openJob(request.getJobId(), task.getPersistentTaskId(), request.isIgnoreDowntime(), e2 -> {
|
|
||||||
if (e2 == null) {
|
|
||||||
listener.onResponse(new TransportResponse.Empty());
|
|
||||||
} else {
|
|
||||||
listener.onFailure(e2);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,6 +13,7 @@ import org.elasticsearch.common.collect.Tuple;
|
||||||
import org.elasticsearch.common.component.AbstractComponent;
|
import org.elasticsearch.common.component.AbstractComponent;
|
||||||
import org.elasticsearch.common.settings.Setting;
|
import org.elasticsearch.common.settings.Setting;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.common.util.concurrent.AbstractRunnable;
|
||||||
import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException;
|
import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException;
|
||||||
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
||||||
import org.elasticsearch.rest.RestStatus;
|
import org.elasticsearch.rest.RestStatus;
|
||||||
|
@ -205,20 +206,31 @@ public class AutodetectProcessManager extends AbstractComponent {
|
||||||
|
|
||||||
public void openJob(String jobId, long taskId, boolean ignoreDowntime, Consumer<Exception> handler) {
|
public void openJob(String jobId, long taskId, boolean ignoreDowntime, Consumer<Exception> handler) {
|
||||||
gatherRequiredInformation(jobId, (dataCounts, modelSnapshot, quantiles, filters) -> {
|
gatherRequiredInformation(jobId, (dataCounts, modelSnapshot, quantiles, filters) -> {
|
||||||
try {
|
// We need to fork, otherwise we restore model state from a network thread (several GET api calls):
|
||||||
AutodetectCommunicator communicator = autoDetectCommunicatorByJob.computeIfAbsent(jobId, id ->
|
threadPool.executor(ThreadPool.Names.MANAGEMENT).execute(new AbstractRunnable() {
|
||||||
create(id, taskId, dataCounts, modelSnapshot, quantiles, filters, ignoreDowntime, handler));
|
@Override
|
||||||
communicator.writeJobInputHeader();
|
public void onFailure(Exception e) {
|
||||||
setJobState(taskId, jobId, JobState.OPENED);
|
handler.accept(e);
|
||||||
} catch (Exception e1) {
|
|
||||||
if (e1 instanceof ElasticsearchStatusException) {
|
|
||||||
logger.info(e1.getMessage());
|
|
||||||
} else {
|
|
||||||
String msg = String.format(Locale.ROOT, "[%s] exception while opening job", jobId);
|
|
||||||
logger.error(msg, e1);
|
|
||||||
}
|
}
|
||||||
setJobState(taskId, JobState.FAILED, e2 -> handler.accept(e1));
|
|
||||||
}
|
@Override
|
||||||
|
protected void doRun() throws Exception {
|
||||||
|
try {
|
||||||
|
AutodetectCommunicator communicator = autoDetectCommunicatorByJob.computeIfAbsent(jobId, id ->
|
||||||
|
create(id, taskId, dataCounts, modelSnapshot, quantiles, filters, ignoreDowntime, handler));
|
||||||
|
communicator.writeJobInputHeader();
|
||||||
|
setJobState(taskId, jobId, JobState.OPENED);
|
||||||
|
} catch (Exception e1) {
|
||||||
|
if (e1 instanceof ElasticsearchStatusException) {
|
||||||
|
logger.info(e1.getMessage());
|
||||||
|
} else {
|
||||||
|
String msg = String.format(Locale.ROOT, "[%s] exception while opening job", jobId);
|
||||||
|
logger.error(msg, e1);
|
||||||
|
}
|
||||||
|
setJobState(taskId, JobState.FAILED, e2 -> handler.accept(e1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}, e1 -> {
|
}, e1 -> {
|
||||||
logger.warn("Failed to gather information required to open job [" + jobId + "]", e1);
|
logger.warn("Failed to gather information required to open job [" + jobId + "]", e1);
|
||||||
setJobState(taskId, JobState.FAILED, e2 -> handler.accept(e1));
|
setJobState(taskId, JobState.FAILED, e2 -> handler.accept(e1));
|
||||||
|
|
|
@ -14,7 +14,6 @@ import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException;
|
||||||
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.xpack.ml.MachineLearning;
|
|
||||||
import org.elasticsearch.xpack.ml.job.JobManager;
|
import org.elasticsearch.xpack.ml.job.JobManager;
|
||||||
import org.elasticsearch.xpack.ml.job.config.AnalysisConfig;
|
import org.elasticsearch.xpack.ml.job.config.AnalysisConfig;
|
||||||
import org.elasticsearch.xpack.ml.job.config.DataDescription;
|
import org.elasticsearch.xpack.ml.job.config.DataDescription;
|
||||||
|
@ -153,8 +152,7 @@ public class AutodetectProcessManagerTests extends ESTestCase {
|
||||||
ThreadPool threadPool = mock(ThreadPool.class);
|
ThreadPool threadPool = mock(ThreadPool.class);
|
||||||
ThreadPool.Cancellable cancellable = mock(ThreadPool.Cancellable.class);
|
ThreadPool.Cancellable cancellable = mock(ThreadPool.Cancellable.class);
|
||||||
when(threadPool.scheduleWithFixedDelay(any(), any(), any())).thenReturn(cancellable);
|
when(threadPool.scheduleWithFixedDelay(any(), any(), any())).thenReturn(cancellable);
|
||||||
when(threadPool.executor(MachineLearning.AUTODETECT_PROCESS_THREAD_POOL_NAME))
|
when(threadPool.executor(anyString())).thenReturn(EsExecutors.newDirectExecutorService());
|
||||||
.thenReturn(EsExecutors.newDirectExecutorService());
|
|
||||||
AutodetectProcess autodetectProcess = mock(AutodetectProcess.class);
|
AutodetectProcess autodetectProcess = mock(AutodetectProcess.class);
|
||||||
when(autodetectProcess.isProcessAlive()).thenReturn(true);
|
when(autodetectProcess.isProcessAlive()).thenReturn(true);
|
||||||
when(autodetectProcess.readAutodetectResults()).thenReturn(Collections.emptyIterator());
|
when(autodetectProcess.readAutodetectResults()).thenReturn(Collections.emptyIterator());
|
||||||
|
@ -344,6 +342,7 @@ public class AutodetectProcessManagerTests extends ESTestCase {
|
||||||
private AutodetectProcessManager createManager(AutodetectCommunicator communicator, Client client,
|
private AutodetectProcessManager createManager(AutodetectCommunicator communicator, Client client,
|
||||||
PersistentTasksService persistentTasksService) {
|
PersistentTasksService persistentTasksService) {
|
||||||
ThreadPool threadPool = mock(ThreadPool.class);
|
ThreadPool threadPool = mock(ThreadPool.class);
|
||||||
|
when(threadPool.executor(anyString())).thenReturn(EsExecutors.newDirectExecutorService());
|
||||||
AutodetectProcessFactory autodetectProcessFactory = mock(AutodetectProcessFactory.class);
|
AutodetectProcessFactory autodetectProcessFactory = mock(AutodetectProcessFactory.class);
|
||||||
AutodetectProcessManager manager = new AutodetectProcessManager(Settings.EMPTY, client,
|
AutodetectProcessManager manager = new AutodetectProcessManager(Settings.EMPTY, client,
|
||||||
threadPool, jobManager, jobProvider, jobResultsPersister, jobDataCountsPersister,
|
threadPool, jobManager, jobProvider, jobResultsPersister, jobDataCountsPersister,
|
||||||
|
|
Loading…
Reference in New Issue