55 */
66
77import createContainer from 'constate-latest' ;
8- import { useMemo , useEffect , useState } from 'react' ;
9- import { bucketSpan , getJobId } from '../../../../common/log_analysis' ;
8+ import { useEffect , useMemo , useState } from 'react' ;
9+
10+ import { bucketSpan , getDatafeedId , getJobId , JobType } from '../../../../common/log_analysis' ;
1011import { useTrackedPromise } from '../../../utils/use_tracked_promise' ;
12+ import { callJobsSummaryAPI , FetchJobStatusResponsePayload } from './api/ml_get_jobs_summary_api' ;
1113import { callSetupMlModuleAPI , SetupMlModuleResponsePayload } from './api/ml_setup_module_api' ;
12- import { callJobsSummaryAPI } from './api/ml_get_jobs_summary_api' ;
1314
1415// combines and abstracts job and datafeed status
1516type JobStatus =
1617 | 'unknown'
1718 | 'missing'
18- | 'inconsistent '
19- | 'created '
19+ | 'initializing '
20+ | 'stopped '
2021 | 'started'
21- | 'opening'
22- | 'opened'
22+ | 'finished'
2323 | 'failed' ;
2424
25- interface AllJobStatuses {
26- [ key : string ] : JobStatus ;
27- }
28-
29- const getInitialJobStatuses = ( ) : AllJobStatuses => {
30- return {
31- logEntryRate : 'unknown' ,
32- } ;
33- } ;
34-
3525export const useLogAnalysisJobs = ( {
3626 indexPattern,
3727 sourceId,
@@ -43,14 +33,19 @@ export const useLogAnalysisJobs = ({
4333 spaceId : string ;
4434 timeField : string ;
4535} ) => {
46- const [ jobStatus , setJobStatus ] = useState < AllJobStatuses > ( getInitialJobStatuses ( ) ) ;
36+ const [ jobStatus , setJobStatus ] = useState < Record < JobType , JobStatus > > ( {
37+ 'log-entry-rate' : 'unknown' ,
38+ } ) ;
4739 const [ hasCompletedSetup , setHasCompletedSetup ] = useState < boolean > ( false ) ;
4840
4941 const [ setupMlModuleRequest , setupMlModule ] = useTrackedPromise (
5042 {
5143 cancelPreviousOn : 'resolution' ,
5244 createPromise : async ( start , end ) => {
53- setJobStatus ( getInitialJobStatuses ( ) ) ;
45+ setJobStatus ( currentJobStatus => ( {
46+ ...currentJobStatus ,
47+ 'log-entry-rate' : 'initializing' ,
48+ } ) ) ;
5449 return await callSetupMlModuleAPI (
5550 start ,
5651 end ,
@@ -62,26 +57,25 @@ export const useLogAnalysisJobs = ({
6257 ) ;
6358 } ,
6459 onResolve : ( { datafeeds, jobs } : SetupMlModuleResponsePayload ) => {
65- const hasSuccessfullyCreatedJobs = jobs . every ( job => job . success ) ;
66- const hasSuccessfullyStartedDatafeeds = datafeeds . every (
67- datafeed => datafeed . success && datafeed . started
68- ) ;
69- const hasAnyErrors =
70- jobs . some ( job => ! ! job . error ) || datafeeds . some ( datafeed => ! ! datafeed . error ) ;
71-
7260 setJobStatus ( currentJobStatus => ( {
7361 ...currentJobStatus ,
74- logEntryRate : hasAnyErrors
75- ? 'failed'
76- : hasSuccessfullyCreatedJobs
77- ? hasSuccessfullyStartedDatafeeds
62+ 'log-entry-rate' :
63+ hasSuccessfullyCreatedJob ( getJobId ( spaceId , sourceId , 'log-entry-rate' ) ) ( jobs ) &&
64+ hasSuccessfullyStartedDatafeed ( getDatafeedId ( spaceId , sourceId , 'log-entry-rate' ) ) (
65+ datafeeds
66+ )
7867 ? 'started'
79- : 'failed'
80- : 'failed' ,
68+ : 'failed' ,
8169 } ) ) ;
8270
8371 setHasCompletedSetup ( true ) ;
8472 } ,
73+ onReject : ( ) => {
74+ setJobStatus ( currentJobStatus => ( {
75+ ...currentJobStatus ,
76+ 'log-entry-rate' : 'failed' ,
77+ } ) ) ;
78+ } ,
8579 } ,
8680 [ indexPattern , spaceId , sourceId ]
8781 ) ;
@@ -90,20 +84,19 @@ export const useLogAnalysisJobs = ({
9084 {
9185 cancelPreviousOn : 'resolution' ,
9286 createPromise : async ( ) => {
93- return callJobsSummaryAPI ( spaceId , sourceId ) ;
87+ return await callJobsSummaryAPI ( spaceId , sourceId ) ;
9488 } ,
9589 onResolve : response => {
96- if ( response && response . length ) {
97- const logEntryRate = response . find (
98- ( job : any ) => job . id === getJobId ( spaceId , sourceId , 'log-entry-rate' )
99- ) ;
100- setJobStatus ( {
101- logEntryRate : logEntryRate ? logEntryRate . jobState : 'unknown' ,
102- } ) ;
103- }
90+ setJobStatus ( currentJobStatus => ( {
91+ ...currentJobStatus ,
92+ 'log-entry-rate' : getJobStatus ( getJobId ( spaceId , sourceId , 'log-entry-rate' ) ) ( response ) ,
93+ } ) ) ;
10494 } ,
105- onReject : error => {
106- // TODO: Handle errors
95+ onReject : err => {
96+ setJobStatus ( currentJobStatus => ( {
97+ ...currentJobStatus ,
98+ 'log-entry-rate' : 'unknown' ,
99+ } ) ) ;
107100 } ,
108101 } ,
109102 [ indexPattern , spaceId , sourceId ]
@@ -114,11 +107,7 @@ export const useLogAnalysisJobs = ({
114107 } , [ ] ) ;
115108
116109 const isSetupRequired = useMemo ( ( ) => {
117- const jobStates = Object . values ( jobStatus ) ;
118- return (
119- jobStates . filter ( state => [ 'opened' , 'opening' , 'created' , 'started' ] . includes ( state ) )
120- . length < jobStates . length
121- ) ;
110+ return ! Object . values ( jobStatus ) . every ( state => [ 'started' , 'finished' ] . includes ( state ) ) ;
122111 } , [ jobStatus ] ) ;
123112
124113 const isLoadingSetupStatus = useMemo ( ( ) => fetchJobStatusRequest . state === 'pending' , [
@@ -147,3 +136,52 @@ export const useLogAnalysisJobs = ({
147136} ;
148137
149138export const LogAnalysisJobs = createContainer ( useLogAnalysisJobs ) ;
139+
140+ const hasSuccessfullyCreatedJob = ( jobId : string ) => (
141+ jobSetupResponses : SetupMlModuleResponsePayload [ 'jobs' ]
142+ ) =>
143+ jobSetupResponses . filter (
144+ jobSetupResponse =>
145+ jobSetupResponse . id === jobId && jobSetupResponse . success && ! jobSetupResponse . error
146+ ) . length > 0 ;
147+
148+ const hasSuccessfullyStartedDatafeed = ( datafeedId : string ) => (
149+ datafeedSetupResponses : SetupMlModuleResponsePayload [ 'datafeeds' ]
150+ ) =>
151+ datafeedSetupResponses . filter (
152+ datafeedSetupResponse =>
153+ datafeedSetupResponse . id === datafeedId &&
154+ datafeedSetupResponse . success &&
155+ datafeedSetupResponse . started &&
156+ ! datafeedSetupResponse . error
157+ ) . length > 0 ;
158+
159+ const getJobStatus = ( jobId : string ) => ( jobSummaries : FetchJobStatusResponsePayload ) : JobStatus =>
160+ jobSummaries
161+ . filter ( jobSummary => jobSummary . id === jobId )
162+ . map (
163+ ( jobSummary ) : JobStatus => {
164+ if ( jobSummary . jobState === 'failed' ) {
165+ return 'failed' ;
166+ } else if (
167+ jobSummary . jobState === 'closed' &&
168+ jobSummary . datafeedState === 'stopped' &&
169+ jobSummary . fullJob &&
170+ jobSummary . fullJob . finished_time != null
171+ ) {
172+ return 'finished' ;
173+ } else if (
174+ jobSummary . jobState === 'closed' ||
175+ jobSummary . jobState === 'closing' ||
176+ jobSummary . datafeedState === 'stopped'
177+ ) {
178+ return 'stopped' ;
179+ } else if ( jobSummary . jobState === 'opening' ) {
180+ return 'initializing' ;
181+ } else if ( jobSummary . jobState === 'opened' && jobSummary . datafeedState === 'started' ) {
182+ return 'started' ;
183+ }
184+
185+ return 'unknown' ;
186+ }
187+ ) [ 0 ] || 'missing' ;
0 commit comments