Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions x-pack/plugins/ml/common/types/modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export interface KibanaObjectResponse extends ResultItem {

export interface DatafeedResponse extends ResultItem {
started: boolean;
awaitingMlNodeAllocation?: boolean;
error?: ErrorType;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import React, { Fragment, FC } from 'react';

import { EuiCallOut, EuiSpacer } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { isCloud } from '../../services/ml_server_info';
import { lazyMlNodesAvailable } from '../../ml_nodes_check';

interface Props {
jobCount: number;
}

export const JobsAwaitingNodeWarning: FC<Props> = ({ jobCount }) => {
if (isCloud() === false || jobCount === 0) {
if (lazyMlNodesAvailable() === false || jobCount === 0) {
return null;
}

Expand All @@ -26,7 +26,7 @@ export const JobsAwaitingNodeWarning: FC<Props> = ({ jobCount }) => {
title={
<FormattedMessage
id="xpack.ml.jobsAwaitingNodeWarning.title"
defaultMessage="Awaiting ML node provisioning"
defaultMessage="Awaiting machine learning node"
/>
}
color="primary"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,24 @@ import React, { Fragment, FC } from 'react';
import { EuiCallOut, EuiSpacer } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { JobType } from '../../../../common/types/saved_objects';
import { lazyMlNodesAvailable } from '../../ml_nodes_check';

interface Props {
jobType: JobType;
}

export const NewJobAwaitingNodeWarning: FC<Props> = () => {
if (lazyMlNodesAvailable() === false) {
return null;
}

return (
<Fragment>
<EuiCallOut
title={
<FormattedMessage
id="xpack.ml.jobsAwaitingNodeWarning.title"
defaultMessage="Awaiting ML node provisioning"
defaultMessage="Awaiting machine learning node"
/>
}
color="primary"
Expand All @@ -31,7 +36,7 @@ export const NewJobAwaitingNodeWarning: FC<Props> = () => {
<div>
<FormattedMessage
id="xpack.ml.newJobAwaitingNodeWarning.noMLNodesAvailableDescription"
defaultMessage="Job cannot be started straight away, an ML node needs to be started. This will happen automatically."
defaultMessage="There are currently no nodes that can run the job, therefore it will remain in OPENING state until an appropriate node becomes available."
/>
</div>
</EuiCallOut>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import { TimeRange } from '../common/components';
import { JobId } from '../../../../../common/types/anomaly_detection_jobs';
import { ML_PAGES } from '../../../../../common/constants/ml_url_generator';
import { TIME_FORMAT } from '../../../../../common/constants/time_format';
import { JobsAwaitingNodeWarning } from '../../../components/jobs_awaiting_node_warning';

export interface ModuleJobUI extends ModuleJob {
datafeedResult?: DatafeedResponse;
Expand Down Expand Up @@ -84,6 +85,7 @@ export const Page: FC<PageProps> = ({ moduleId, existingGroupIds }) => {
const [saveState, setSaveState] = useState<SAVE_STATE>(SAVE_STATE.NOT_SAVED);
const [resultsUrl, setResultsUrl] = useState<string>('');
const [existingGroups, setExistingGroups] = useState(existingGroupIds);
const [jobsAwaitingNodeCount, setJobsAwaitingNodeCount] = useState(0);
// #endregion

const {
Expand Down Expand Up @@ -204,9 +206,19 @@ export const Page: FC<PageProps> = ({ moduleId, existingGroupIds }) => {
});

setResultsUrl(url);
const failedJobsCount = jobsResponse.reduce((count, { success }) => {
return success ? count : count + 1;
}, 0);
const failedJobsCount = jobsResponse.reduce(
(count, { success }) => (success ? count : count + 1),
0
);

const lazyJobsCount = datafeedsResponse.reduce(
(count, { awaitingMlNodeAllocation }) =>
awaitingMlNodeAllocation === true ? count + 1 : count,
0
);

setJobsAwaitingNodeCount(lazyJobsCount);

setSaveState(
failedJobsCount === 0
? SAVE_STATE.SAVED
Expand Down Expand Up @@ -291,6 +303,8 @@ export const Page: FC<PageProps> = ({ moduleId, existingGroupIds }) => {
</>
)}

{jobsAwaitingNodeCount > 0 && <JobsAwaitingNodeWarning jobCount={jobsAwaitingNodeCount} />}

<EuiFlexGroup wrap={true} gutterSize="m">
<EuiFlexItem grow={1}>
<EuiPanel grow={false}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ export function mlNodesAvailable() {
return mlNodeCount !== 0 || lazyMlNodeCount !== 0;
}

export function currentMlNodesAvailable() {
return mlNodeCount !== 0;
}

export function lazyMlNodesAvailable() {
return lazyMlNodeCount !== 0;
}

export function permissionToViewMlNodeCount() {
return userHasPermissionToViewMlNodeCount;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ export {
checkMlNodesAvailable,
getMlNodeCount,
mlNodesAvailable,
lazyMlNodesAvailable,
permissionToViewMlNodeCount,
} from './check_ml_nodes';
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
import { JOB_STATE } from '../../../../../common/constants/states';
import { FORECAST_DURATION_MAX_DAYS } from './forecasting_modal';
import { ForecastProgress } from './forecast_progress';
import { mlNodesAvailable } from '../../../ml_nodes_check/check_ml_nodes';
import { currentMlNodesAvailable } from '../../../ml_nodes_check/check_ml_nodes';
import {
checkPermission,
createPermissionFailureMessage,
Expand All @@ -41,7 +41,7 @@ function getRunInputDisabledState(job, isForecastRequested) {
// - No canForecastJob permission
// - Job is not in an OPENED or CLOSED state
// - A new forecast has been requested
if (mlNodesAvailable() === false) {
if (currentMlNodesAvailable() === false) {
return {
isDisabled: true,
isDisabledToolTipText: i18n.translate(
Expand Down
13 changes: 11 additions & 2 deletions x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@ export class DataRecognizer {
const startedDatafeed = startResults[df.id];
if (startedDatafeed !== undefined) {
df.started = startedDatafeed.started;
df.awaitingMlNodeAllocation = startedDatafeed.awaitingMlNodeAllocation;
if (startedDatafeed.error !== undefined) {
df.error = startedDatafeed.error;
}
Expand Down Expand Up @@ -811,11 +812,18 @@ export class DataRecognizer {
duration.end = (end as unknown) as string;
}

await this._mlClient.startDatafeed({
const {
body: { started, node },
} = await this._mlClient.startDatafeed<{
started: boolean;
node: string;
}>({
datafeed_id: datafeed.id,
...duration,
});
result.started = true;

result.started = started;
result.awaitingMlNodeAllocation = node?.length === 0;
} catch ({ body }) {
result.started = false;
result.error = body;
Expand Down Expand Up @@ -845,6 +853,7 @@ export class DataRecognizer {
if (d.id === d2.id) {
d.success = d2.success;
d.started = d2.started;
d.awaitingMlNodeAllocation = d2.awaitingMlNodeAllocation;
if (d2.error !== undefined) {
d.error = d2.error;
}
Expand Down