Skip to content

Commit

Permalink
[ML] DF Analytics: ensure job state is up to date (#61678) (#61855)
Browse files Browse the repository at this point in the history
* classification results: fetch job state on load

* regression results: fetch job state on load

* outlier results: fetch job state on load

* remove deprecated code adding jobStatus to url

* update outlier result test
  • Loading branch information
alvarezmelissa87 authored Mar 30, 2020
1 parent a902c72 commit b7f1c29
Show file tree
Hide file tree
Showing 13 changed files with 88 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { getIndexPatternIdFromName } from '../../../../../util/index_utils';
import { IIndexPattern } from '../../../../../../../../../../src/plugins/data/common/index_patterns';
import { newJobCapsService } from '../../../../../services/new_job_capabilities_service';
import { useMlContext } from '../../../../../contexts/ml';
import { isGetDataFrameAnalyticsStatsResponseOk } from '../../../analytics_management/services/analytics_service/get_analytics';

export const ExplorationTitle: React.FC<{ jobId: string }> = ({ jobId }) => (
<EuiTitle size="xs">
Expand Down Expand Up @@ -47,11 +48,11 @@ const jobCapsErrorTitle = i18n.translate(

interface Props {
jobId: string;
jobStatus: DATA_FRAME_TASK_STATE;
}

export const ClassificationExploration: FC<Props> = ({ jobId, jobStatus }) => {
export const ClassificationExploration: FC<Props> = ({ jobId }) => {
const [jobConfig, setJobConfig] = useState<DataFrameAnalyticsConfig | undefined>(undefined);
const [jobStatus, setJobStatus] = useState<DATA_FRAME_TASK_STATE | undefined>(undefined);
const [isLoadingJobConfig, setIsLoadingJobConfig] = useState<boolean>(false);
const [isInitialized, setIsInitialized] = useState<boolean>(false);
const [jobConfigErrorMessage, setJobConfigErrorMessage] = useState<undefined | string>(undefined);
Expand All @@ -65,6 +66,15 @@ export const ClassificationExploration: FC<Props> = ({ jobId, jobStatus }) => {
setIsLoadingJobConfig(true);
try {
const analyticsConfigs = await ml.dataFrameAnalytics.getDataFrameAnalytics(jobId);
const analyticsStats = await ml.dataFrameAnalytics.getDataFrameAnalyticsStats(jobId);
const stats = isGetDataFrameAnalyticsStatsResponseOk(analyticsStats)
? analyticsStats.data_frame_analytics[0]
: undefined;

if (stats !== undefined && stats.state) {
setJobStatus(stats.state);
}

if (
Array.isArray(analyticsConfigs.data_frame_analytics) &&
analyticsConfigs.data_frame_analytics.length > 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const defaultPanelWidth = 500;

interface Props {
jobConfig: DataFrameAnalyticsConfig;
jobStatus: DATA_FRAME_TASK_STATE;
jobStatus?: DATA_FRAME_TASK_STATE;
searchQuery: ResultsSearchQuery;
}

Expand Down Expand Up @@ -318,9 +318,11 @@ export const EvaluatePanel: FC<Props> = ({ jobConfig, jobStatus, searchQuery })
</span>
</EuiTitle>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<span>{getTaskStateBadge(jobStatus)}</span>
</EuiFlexItem>
{jobStatus !== undefined && (
<EuiFlexItem grow={false}>
<span>{getTaskStateBadge(jobStatus)}</span>
</EuiFlexItem>
)}
<EuiFlexItem>
<EuiSpacer />
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ const showingFirstDocs = i18n.translate(

interface Props {
jobConfig: DataFrameAnalyticsConfig;
jobStatus: DATA_FRAME_TASK_STATE;
jobStatus?: DATA_FRAME_TASK_STATE;
setEvaluateSearchQuery: React.Dispatch<React.SetStateAction<object>>;
}

Expand Down Expand Up @@ -381,9 +381,11 @@ export const ResultsTable: FC<Props> = React.memo(
<EuiFlexItem grow={false}>
<ExplorationTitle jobId={jobConfig.id} />
</EuiFlexItem>
<EuiFlexItem grow={false}>
<span>{getTaskStateBadge(jobStatus)}</span>
</EuiFlexItem>
{jobStatus !== undefined && (
<EuiFlexItem grow={false}>
<span>{getTaskStateBadge(jobStatus)}</span>
</EuiFlexItem>
)}
</EuiFlexGroup>
<EuiCallOut
title={i18n.translate('xpack.ml.dataframe.analytics.regressionExploration.indexError', {
Expand Down Expand Up @@ -415,9 +417,11 @@ export const ResultsTable: FC<Props> = React.memo(
<EuiFlexItem grow={false}>
<ExplorationTitle jobId={jobConfig.id} />
</EuiFlexItem>
<EuiFlexItem grow={false}>
<span>{getTaskStateBadge(jobStatus)}</span>
</EuiFlexItem>
{jobStatus !== undefined && (
<EuiFlexItem grow={false}>
<span>{getTaskStateBadge(jobStatus)}</span>
</EuiFlexItem>
)}
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import { shallow } from 'enzyme';
import React from 'react';
import { DATA_FRAME_TASK_STATE } from '../../../analytics_management/components/analytics_list/common';
import { MlContext } from '../../../../../contexts/ml';
import { kibanaContextValueMock } from '../../../../../contexts/ml/__mocks__/kibana_context_value';

Expand All @@ -22,7 +21,7 @@ describe('Data Frame Analytics: <Exploration />', () => {
test('Minimal initialization', () => {
const wrapper = shallow(
<MlContext.Provider value={kibanaContextValueMock}>
<OutlierExploration jobId="the-job-id" jobStatus={DATA_FRAME_TASK_STATE.STOPPED} />
<OutlierExploration jobId="the-job-id" />
</MlContext.Provider>
);
// Without the jobConfig being loaded, the component will just return empty.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import {

import { sortColumns, INDEX_STATUS, defaultSearchQuery } from '../../../../common';

import { DATA_FRAME_TASK_STATE } from '../../../analytics_management/components/analytics_list/common';
import { getTaskStateBadge } from '../../../analytics_management/components/analytics_list/columns';

import { useExploreData, TableItem } from '../../hooks/use_explore_data';
Expand All @@ -50,7 +49,6 @@ const ExplorationTitle: FC<{ jobId: string }> = ({ jobId }) => (

interface ExplorationProps {
jobId: string;
jobStatus: DATA_FRAME_TASK_STATE;
}

const getFeatureCount = (resultsField: string, tableItems: TableItem[] = []) => {
Expand All @@ -63,11 +61,12 @@ const getFeatureCount = (resultsField: string, tableItems: TableItem[] = []) =>
).length;
};

export const OutlierExploration: FC<ExplorationProps> = React.memo(({ jobId, jobStatus }) => {
export const OutlierExploration: FC<ExplorationProps> = React.memo(({ jobId }) => {
const {
errorMessage,
indexPattern,
jobConfig,
jobStatus,
pagination,
searchQuery,
selectedFields,
Expand Down Expand Up @@ -173,9 +172,11 @@ export const OutlierExploration: FC<ExplorationProps> = React.memo(({ jobId, job
<EuiFlexItem grow={false}>
<ExplorationTitle jobId={jobConfig.id} />
</EuiFlexItem>
<EuiFlexItem grow={false}>
<span>{getTaskStateBadge(jobStatus)}</span>
</EuiFlexItem>
{jobStatus !== undefined && (
<EuiFlexItem grow={false}>
<span>{getTaskStateBadge(jobStatus)}</span>
</EuiFlexItem>
)}
</EuiFlexGroup>
<EuiHorizontalRule margin="xs" />
{(columns.length > 0 || searchQuery !== defaultSearchQuery) && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import {

interface Props {
jobConfig: DataFrameAnalyticsConfig;
jobStatus: DATA_FRAME_TASK_STATE;
jobStatus?: DATA_FRAME_TASK_STATE;
searchQuery: ResultsSearchQuery;
}

Expand Down Expand Up @@ -248,9 +248,11 @@ export const EvaluatePanel: FC<Props> = ({ jobConfig, jobStatus, searchQuery })
</span>
</EuiTitle>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<span>{getTaskStateBadge(jobStatus)}</span>
</EuiFlexItem>
{jobStatus !== undefined && (
<EuiFlexItem grow={false}>
<span>{getTaskStateBadge(jobStatus)}</span>
</EuiFlexItem>
)}
<EuiFlexItem>
<EuiSpacer />
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { getIndexPatternIdFromName } from '../../../../../util/index_utils';
import { IIndexPattern } from '../../../../../../../../../../src/plugins/data/common/index_patterns';
import { newJobCapsService } from '../../../../../services/new_job_capabilities_service';
import { useMlContext } from '../../../../../contexts/ml';
import { isGetDataFrameAnalyticsStatsResponseOk } from '../../../analytics_management/services/analytics_service/get_analytics';

export const ExplorationTitle: React.FC<{ jobId: string }> = ({ jobId }) => (
<EuiTitle size="xs">
Expand Down Expand Up @@ -47,11 +48,11 @@ const jobCapsErrorTitle = i18n.translate(

interface Props {
jobId: string;
jobStatus: DATA_FRAME_TASK_STATE;
}

export const RegressionExploration: FC<Props> = ({ jobId, jobStatus }) => {
export const RegressionExploration: FC<Props> = ({ jobId }) => {
const [jobConfig, setJobConfig] = useState<DataFrameAnalyticsConfig | undefined>(undefined);
const [jobStatus, setJobStatus] = useState<DATA_FRAME_TASK_STATE | undefined>(undefined);
const [isLoadingJobConfig, setIsLoadingJobConfig] = useState<boolean>(false);
const [isInitialized, setIsInitialized] = useState<boolean>(false);
const [jobConfigErrorMessage, setJobConfigErrorMessage] = useState<undefined | string>(undefined);
Expand All @@ -65,6 +66,15 @@ export const RegressionExploration: FC<Props> = ({ jobId, jobStatus }) => {
setIsLoadingJobConfig(true);
try {
const analyticsConfigs = await ml.dataFrameAnalytics.getDataFrameAnalytics(jobId);
const analyticsStats = await ml.dataFrameAnalytics.getDataFrameAnalyticsStats(jobId);
const stats = isGetDataFrameAnalyticsStatsResponseOk(analyticsStats)
? analyticsStats.data_frame_analytics[0]
: undefined;

if (stats !== undefined && stats.state) {
setJobStatus(stats.state);
}

if (
Array.isArray(analyticsConfigs.data_frame_analytics) &&
analyticsConfigs.data_frame_analytics.length > 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ const showingFirstDocs = i18n.translate(

interface Props {
jobConfig: DataFrameAnalyticsConfig;
jobStatus: DATA_FRAME_TASK_STATE;
jobStatus?: DATA_FRAME_TASK_STATE;
setEvaluateSearchQuery: React.Dispatch<React.SetStateAction<object>>;
}

Expand Down Expand Up @@ -381,9 +381,11 @@ export const ResultsTable: FC<Props> = React.memo(
<EuiFlexItem grow={false}>
<ExplorationTitle jobId={jobConfig.id} />
</EuiFlexItem>
<EuiFlexItem grow={false}>
<span>{getTaskStateBadge(jobStatus)}</span>
</EuiFlexItem>
{jobStatus !== undefined && (
<EuiFlexItem grow={false}>
<span>{getTaskStateBadge(jobStatus)}</span>
</EuiFlexItem>
)}
</EuiFlexGroup>
<EuiCallOut
title={i18n.translate('xpack.ml.dataframe.analytics.regressionExploration.indexError', {
Expand Down Expand Up @@ -411,9 +413,11 @@ export const ResultsTable: FC<Props> = React.memo(
<EuiFlexItem grow={false}>
<ExplorationTitle jobId={jobConfig.id} />
</EuiFlexItem>
<EuiFlexItem grow={false}>
<span>{getTaskStateBadge(jobStatus)}</span>
</EuiFlexItem>
{jobStatus !== undefined && (
<EuiFlexItem grow={false}>
<span>{getTaskStateBadge(jobStatus)}</span>
</EuiFlexItem>
)}
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { newJobCapsService } from '../../../../../services/new_job_capabilities_
import { getIndexPatternIdFromName } from '../../../../../util/index_utils';
import { getNestedProperty } from '../../../../../util/object_utils';
import { useMlContext } from '../../../../../contexts/ml';
import { isGetDataFrameAnalyticsStatsResponseOk } from '../../../analytics_management/services/analytics_service/get_analytics';

import {
getDefaultSelectableFields,
Expand All @@ -31,6 +32,7 @@ import {
import { isKeywordAndTextType } from '../../../../common/fields';

import { getOutlierScoreFieldName } from './common';
import { DATA_FRAME_TASK_STATE } from '../../../analytics_management/components/analytics_list/common';

export type TableItem = Record<string, any>;

Expand All @@ -40,6 +42,7 @@ interface UseExploreDataReturnType {
errorMessage: string;
indexPattern: IndexPattern | undefined;
jobConfig: DataFrameAnalyticsConfig | undefined;
jobStatus: DATA_FRAME_TASK_STATE | undefined;
pagination: Pagination;
searchQuery: SavedSearchQuery;
selectedFields: EsFieldName[];
Expand Down Expand Up @@ -74,6 +77,7 @@ export const useExploreData = (jobId: string): UseExploreDataReturnType => {

const [indexPattern, setIndexPattern] = useState<IndexPattern | undefined>(undefined);
const [jobConfig, setJobConfig] = useState<DataFrameAnalyticsConfig | undefined>(undefined);
const [jobStatus, setJobStatus] = useState<DATA_FRAME_TASK_STATE | undefined>(undefined);
const [errorMessage, setErrorMessage] = useState('');
const [status, setStatus] = useState(INDEX_STATUS.UNUSED);

Expand All @@ -90,6 +94,15 @@ export const useExploreData = (jobId: string): UseExploreDataReturnType => {
useEffect(() => {
(async function() {
const analyticsConfigs = await ml.dataFrameAnalytics.getDataFrameAnalytics(jobId);
const analyticsStats = await ml.dataFrameAnalytics.getDataFrameAnalyticsStats(jobId);
const stats = isGetDataFrameAnalyticsStatsResponseOk(analyticsStats)
? analyticsStats.data_frame_analytics[0]
: undefined;

if (stats !== undefined && stats.state) {
setJobStatus(stats.state);
}

if (
Array.isArray(analyticsConfigs.data_frame_analytics) &&
analyticsConfigs.data_frame_analytics.length > 0
Expand Down Expand Up @@ -215,6 +228,7 @@ export const useExploreData = (jobId: string): UseExploreDataReturnType => {
errorMessage,
indexPattern,
jobConfig,
jobStatus,
pagination,
rowCount,
searchQuery,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,11 @@ import { RegressionExploration } from './components/regression_exploration';
import { ClassificationExploration } from './components/classification_exploration';

import { ANALYSIS_CONFIG_TYPE } from '../../common/analytics';
import { DATA_FRAME_TASK_STATE } from '../analytics_management/components/analytics_list/common';

export const Page: FC<{
jobId: string;
analysisType: ANALYSIS_CONFIG_TYPE;
jobStatus: DATA_FRAME_TASK_STATE;
}> = ({ jobId, analysisType, jobStatus }) => (
}> = ({ jobId, analysisType }) => (
<Fragment>
<NavigationMenu tabId="data_frame_analytics" />
<EuiPage data-test-subj="mlPageDataFrameAnalyticsExploration">
Expand Down Expand Up @@ -68,13 +66,13 @@ export const Page: FC<{
<EuiPageContentBody style={{ maxWidth: 'calc(100% - 0px)' }}>
<EuiSpacer size="l" />
{analysisType === ANALYSIS_CONFIG_TYPE.OUTLIER_DETECTION && (
<OutlierExploration jobId={jobId} jobStatus={jobStatus} />
<OutlierExploration jobId={jobId} />
)}
{analysisType === ANALYSIS_CONFIG_TYPE.REGRESSION && (
<RegressionExploration jobId={jobId} jobStatus={jobStatus} />
<RegressionExploration jobId={jobId} />
)}
{analysisType === ANALYSIS_CONFIG_TYPE.CLASSIFICATION && (
<ClassificationExploration jobId={jobId} jobStatus={jobStatus} />
<ClassificationExploration jobId={jobId} />
)}
</EuiPageContentBody>
</EuiPageBody>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,12 @@ export const AnalyticsViewAction = {
isPrimary: true,
render: (item: DataFrameAnalyticsListRow) => {
const analysisType = getAnalysisType(item.config.analysis);
const jobStatus = item.stats.state;
const isDisabled =
!isRegressionAnalysis(item.config.analysis) &&
!isOutlierAnalysis(item.config.analysis) &&
!isClassificationAnalysis(item.config.analysis);

const url = getResultsUrl(item.id, analysisType, jobStatus);
const url = getResultsUrl(item.id, analysisType);
return (
<EuiButtonEmpty
isDisabled={isDisabled}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,6 @@ export function isCompletedAnalyticsJob(stats: DataFrameAnalyticsStats) {
return stats.state === DATA_FRAME_TASK_STATE.STOPPED && progress === 100;
}

export function getResultsUrl(jobId: string, analysisType: string, status: DATA_FRAME_TASK_STATE) {
return `ml#/data_frame_analytics/exploration?_g=(ml:(jobId:${jobId},analysisType:${analysisType},jobStatus:${status}))`;
export function getResultsUrl(jobId: string, analysisType: string) {
return `ml#/data_frame_analytics/exploration?_g=(ml:(jobId:${jobId},analysisType:${analysisType}))`;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { useResolver } from '../../use_resolver';
import { basicResolvers } from '../../resolvers';
import { Page } from '../../../data_frame_analytics/pages/analytics_exploration';
import { ANALYSIS_CONFIG_TYPE } from '../../../data_frame_analytics/common/analytics';
import { DATA_FRAME_TASK_STATE } from '../../../data_frame_analytics/pages/analytics_management/components/analytics_list/common';
import { ML_BREADCRUMB } from '../../breadcrumbs';

const breadcrumbs = [
Expand Down Expand Up @@ -46,11 +45,10 @@ const PageWrapper: FC<PageProps> = ({ location, deps }) => {
}
const jobId: string = globalState.ml.jobId;
const analysisType: ANALYSIS_CONFIG_TYPE = globalState.ml.analysisType;
const jobStatus: DATA_FRAME_TASK_STATE = globalState.ml.jobStatus;

return (
<PageLoader context={context}>
<Page {...{ jobId, analysisType, jobStatus }} />
<Page {...{ jobId, analysisType }} />
</PageLoader>
);
};

0 comments on commit b7f1c29

Please sign in to comment.