From 31cf041f4aea4762c04a380d4909ec179c688e01 Mon Sep 17 00:00:00 2001 From: rbrtj Date: Fri, 4 Oct 2024 16:32:37 +0200 Subject: [PATCH 1/7] remove query sizing based on previous query cardinality --- .../anomaly_swimlane/initialize_swim_lane_data_fetcher.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_data_fetcher.ts b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_data_fetcher.ts index 268a17fca4a81..14da40e040a21 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_data_fetcher.ts +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_data_fetcher.ts @@ -29,7 +29,6 @@ import { SWIMLANE_TYPE, } from '../../application/explorer/explorer_constants'; import type { OverallSwimlaneData } from '../../application/explorer/explorer_utils'; -import { isViewBySwimLaneData } from '../../application/explorer/swimlane_container'; import { CONTROLLED_BY_SWIM_LANE_FILTER } from '../../ui_actions/constants'; import { getJobsObservable } from '../common/get_jobs_observable'; import { processFilters } from '../common/process_filters'; @@ -114,12 +113,7 @@ export const initializeSwimLaneDataFetcher = ( const { earliest, latest } = overallSwimlaneData; if (overallSwimlaneData && swimlaneType === SWIMLANE_TYPE.VIEW_BY) { - const swimlaneData = swimLaneData$.value; - - let swimLaneLimit = ANOMALY_SWIM_LANE_HARD_LIMIT; - if (isViewBySwimLaneData(swimlaneData) && viewBy === swimlaneData.fieldName) { - swimLaneLimit = swimlaneData.cardinality; - } + const swimLaneLimit = ANOMALY_SWIM_LANE_HARD_LIMIT; return from( anomalyTimelineService.loadViewBySwimlane( From 133ece2afbfc87d6b0b8e9abe421dc730762ed10 Mon Sep 17 00:00:00 2001 From: rbrtj Date: Tue, 8 Oct 2024 11:03:27 +0200 Subject: [PATCH 2/7] fix querying across vaious pagination pages --- .../initialize_swim_lane_data_fetcher.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_data_fetcher.ts b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_data_fetcher.ts index 14da40e040a21..5694bdab383b6 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_data_fetcher.ts +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_data_fetcher.ts @@ -6,7 +6,7 @@ */ import type { estypes } from '@elastic/elasticsearch'; -import type { TimeRange } from '@kbn/es-query'; +import { isOfQueryType, type TimeRange } from '@kbn/es-query'; import type { PublishesUnifiedSearch } from '@kbn/presentation-publishing'; import { BehaviorSubject, @@ -95,6 +95,14 @@ export const initializeSwimLaneDataFetcher = ( const { viewBy, swimlaneType, perPage, fromPage } = input; + let isEmptyQuery = true; + + if (isOfQueryType(query)) { + isEmptyQuery = !query.query; + } else { + isEmptyQuery = !query?.esql; + } + let appliedFilters: estypes.QueryDslQueryContainer; try { if (filters || query) { @@ -123,7 +131,7 @@ export const initializeSwimLaneDataFetcher = ( viewBy!, swimLaneLimit, perPage!, - fromPage, + isEmptyQuery ? fromPage : 1, undefined, appliedFilters, bucketInterval From 868dd88134912db5db1a07f42508217e6cbf7ca5 Mon Sep 17 00:00:00 2001 From: rbrtj Date: Tue, 8 Oct 2024 15:42:08 +0200 Subject: [PATCH 3/7] modify swimLaneInput based on emitted values --- .../initialize_swim_lane_data_fetcher.ts | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_data_fetcher.ts b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_data_fetcher.ts index 5694bdab383b6..3eaa313dd368f 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_data_fetcher.ts +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_data_fetcher.ts @@ -6,7 +6,7 @@ */ import type { estypes } from '@elastic/elasticsearch'; -import { isOfQueryType, type TimeRange } from '@kbn/es-query'; +import { type TimeRange } from '@kbn/es-query'; import type { PublishesUnifiedSearch } from '@kbn/presentation-publishing'; import { BehaviorSubject, @@ -23,6 +23,8 @@ import { startWith, switchMap, tap, + distinctUntilChanged, + merge, } from 'rxjs'; import { ANOMALY_SWIM_LANE_HARD_LIMIT, @@ -61,7 +63,14 @@ export const initializeSwimLaneDataFetcher = ( swimlaneType: swimLaneApi.swimlaneType, viewBy: swimLaneApi.viewBy, perPage: swimLaneApi.perPage, - fromPage: swimLaneApi.fromPage, + fromPage: merge( + query$.pipe(map(() => 1)), + swimLaneApi.fromPage, + filters$.pipe(map(() => 1)) + ).pipe( + distinctUntilChanged(), + tap((fromPage) => swimLaneApi.updatePagination({ fromPage })) + ), }); const bucketInterval$ = combineLatest([selectedJobs$, chartWidth$, appliedTimeRange$]).pipe( @@ -95,14 +104,6 @@ export const initializeSwimLaneDataFetcher = ( const { viewBy, swimlaneType, perPage, fromPage } = input; - let isEmptyQuery = true; - - if (isOfQueryType(query)) { - isEmptyQuery = !query.query; - } else { - isEmptyQuery = !query?.esql; - } - let appliedFilters: estypes.QueryDslQueryContainer; try { if (filters || query) { @@ -131,7 +132,7 @@ export const initializeSwimLaneDataFetcher = ( viewBy!, swimLaneLimit, perPage!, - isEmptyQuery ? fromPage : 1, + fromPage, undefined, appliedFilters, bucketInterval @@ -167,6 +168,7 @@ export const initializeSwimLaneDataFetcher = ( swimLaneData$, onDestroy: () => { subscription.unsubscribe(); + query$.unsubscribe(); }, }; }; From fdcfc26fc4233daf1ad76150ce0a85e18f5f4695 Mon Sep 17 00:00:00 2001 From: Robert Jaszczurek <92210485+rbrtj@users.noreply.github.com> Date: Tue, 8 Oct 2024 16:32:36 +0200 Subject: [PATCH 4/7] cleanup --- .../anomaly_swimlane/initialize_swim_lane_data_fetcher.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_data_fetcher.ts b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_data_fetcher.ts index 3eaa313dd368f..c37f7091e881d 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_data_fetcher.ts +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_data_fetcher.ts @@ -168,7 +168,6 @@ export const initializeSwimLaneDataFetcher = ( swimLaneData$, onDestroy: () => { subscription.unsubscribe(); - query$.unsubscribe(); }, }; }; From 5a95ba0cd847f1cc290f05a9c89878d500d336bd Mon Sep 17 00:00:00 2001 From: rbrtj Date: Wed, 9 Oct 2024 12:10:56 +0200 Subject: [PATCH 5/7] swimlane controls handle external deps --- .../anomaly_swimlane_embeddable_factory.tsx | 10 ++++++++-- .../anomaly_swimlane/initialize_swim_lane_controls.ts | 11 ++++++++--- .../initialize_swim_lane_data_fetcher.ts | 11 +---------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.tsx b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.tsx index 34390075f927b..e787d396d8981 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.tsx +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.tsx @@ -26,7 +26,7 @@ import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render'; import React, { useCallback, useState } from 'react'; import useUnmount from 'react-use/lib/useUnmount'; import type { Observable } from 'rxjs'; -import { BehaviorSubject, combineLatest, map, of, Subscription } from 'rxjs'; +import { BehaviorSubject, combineLatest, map, merge, of, Subscription } from 'rxjs'; import type { AnomalySwimlaneEmbeddableServices } from '..'; import { ANOMALY_SWIMLANE_EMBEDDABLE_TYPE } from '..'; import type { MlDependencies } from '../../application/app'; @@ -117,6 +117,10 @@ export const getAnomalySwimLaneEmbeddableFactory = ( // @ts-ignore (state.query ? new BehaviorSubject(state.filters) : parentApi?.filters$) ?? new BehaviorSubject(undefined); + const timeRange$ = + // @ts-ignore + (state.timeRange ? new BehaviorSubject(state.timeRange) : parentApi?.timeRange$) ?? + new BehaviorSubject(undefined); const refresh$ = new BehaviorSubject(undefined); @@ -127,12 +131,14 @@ export const getAnomalySwimLaneEmbeddableFactory = ( serialize: serializeTimeRange, } = initializeTimeRange(state); + const swimlaneControlsDependencies$ = merge(query$, filters$, timeRange$); + const { swimLaneControlsApi, serializeSwimLaneState, swimLaneComparators, onSwimLaneDestroy, - } = initializeSwimLaneControls(state, titlesApi); + } = initializeSwimLaneControls(state, titlesApi, swimlaneControlsDependencies$); // Helpers for swim lane data fetching const chartWidth$ = new BehaviorSubject(undefined); diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_controls.ts b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_controls.ts index 1301b29f80661..79693cad6ea6b 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_controls.ts +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_controls.ts @@ -8,7 +8,8 @@ import type { StateComparators } from '@kbn/presentation-publishing'; import type { TitlesApi } from '@kbn/presentation-publishing/interfaces/titles/titles_api'; import fastIsEqual from 'fast-deep-equal'; -import { BehaviorSubject, combineLatest } from 'rxjs'; +import type { Observable } from 'rxjs'; +import { BehaviorSubject, combineLatest, merge } from 'rxjs'; import type { AnomalySwimlaneEmbeddableUserInput } from '..'; import type { JobId } from '../../../common/types/anomaly_detection_jobs'; import type { SwimlaneType } from '../../application/explorer/explorer_constants'; @@ -22,7 +23,8 @@ export type AnomalySwimLaneControlsState = Pick< export const initializeSwimLaneControls = ( rawState: AnomalySwimLaneEmbeddableState, - titlesApi: TitlesApi + titlesApi: TitlesApi, + swimlaneControlsDependencies$: Observable ) => { const jobIds = new BehaviorSubject(rawState.jobIds); const swimlaneType = new BehaviorSubject(rawState.swimlaneType); @@ -46,7 +48,10 @@ export const initializeSwimLaneControls = ( } }; - const subscription = combineLatest([jobIds, swimlaneType, viewBy]).subscribe(() => { + const subscription = merge( + combineLatest([jobIds, swimlaneType, viewBy]), + swimlaneControlsDependencies$ + ).subscribe(() => { updatePagination({ fromPage: 1 }); }); diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_data_fetcher.ts b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_data_fetcher.ts index c37f7091e881d..be678af02a65b 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_data_fetcher.ts +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_data_fetcher.ts @@ -23,8 +23,6 @@ import { startWith, switchMap, tap, - distinctUntilChanged, - merge, } from 'rxjs'; import { ANOMALY_SWIM_LANE_HARD_LIMIT, @@ -63,14 +61,7 @@ export const initializeSwimLaneDataFetcher = ( swimlaneType: swimLaneApi.swimlaneType, viewBy: swimLaneApi.viewBy, perPage: swimLaneApi.perPage, - fromPage: merge( - query$.pipe(map(() => 1)), - swimLaneApi.fromPage, - filters$.pipe(map(() => 1)) - ).pipe( - distinctUntilChanged(), - tap((fromPage) => swimLaneApi.updatePagination({ fromPage })) - ), + fromPage: swimLaneApi.fromPage, }); const bucketInterval$ = combineLatest([selectedJobs$, chartWidth$, appliedTimeRange$]).pipe( From ab9b4454f64310a10032a04b4721d472e0317a3a Mon Sep 17 00:00:00 2001 From: rbrtj Date: Wed, 9 Oct 2024 15:37:02 +0200 Subject: [PATCH 6/7] use fetch$ --- .../anomaly_swimlane_embeddable_factory.tsx | 26 +++++++++++++------ .../initialize_swim_lane_controls.ts | 11 +++----- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.tsx b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.tsx index e787d396d8981..2a76dcddb1a53 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.tsx +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.tsx @@ -18,6 +18,7 @@ import { apiHasExecutionContext, apiHasParentApi, apiPublishesTimeRange, + fetch$, initializeTimeRange, initializeTitles, useBatchedPublishingSubjects, @@ -26,7 +27,8 @@ import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render'; import React, { useCallback, useState } from 'react'; import useUnmount from 'react-use/lib/useUnmount'; import type { Observable } from 'rxjs'; -import { BehaviorSubject, combineLatest, map, merge, of, Subscription } from 'rxjs'; +import { BehaviorSubject, combineLatest, distinctUntilChanged, map, of, Subscription } from 'rxjs'; +import fastIsEqual from 'fast-deep-equal'; import type { AnomalySwimlaneEmbeddableServices } from '..'; import { ANOMALY_SWIMLANE_EMBEDDABLE_TYPE } from '..'; import type { MlDependencies } from '../../application/app'; @@ -117,10 +119,6 @@ export const getAnomalySwimLaneEmbeddableFactory = ( // @ts-ignore (state.query ? new BehaviorSubject(state.filters) : parentApi?.filters$) ?? new BehaviorSubject(undefined); - const timeRange$ = - // @ts-ignore - (state.timeRange ? new BehaviorSubject(state.timeRange) : parentApi?.timeRange$) ?? - new BehaviorSubject(undefined); const refresh$ = new BehaviorSubject(undefined); @@ -131,14 +129,12 @@ export const getAnomalySwimLaneEmbeddableFactory = ( serialize: serializeTimeRange, } = initializeTimeRange(state); - const swimlaneControlsDependencies$ = merge(query$, filters$, timeRange$); - const { swimLaneControlsApi, serializeSwimLaneState, swimLaneComparators, onSwimLaneDestroy, - } = initializeSwimLaneControls(state, titlesApi, swimlaneControlsDependencies$); + } = initializeSwimLaneControls(state, titlesApi); // Helpers for swim lane data fetching const chartWidth$ = new BehaviorSubject(undefined); @@ -241,6 +237,19 @@ export const getAnomalySwimLaneEmbeddableFactory = ( anomalySwimLaneServices ); + const fetchSubscription = fetch$(api) + .pipe( + map((fetchContext) => ({ + query: fetchContext.query, + filters: fetchContext.filters, + timeRange: fetchContext.timeRange, + })), + distinctUntilChanged(fastIsEqual) + ) + .subscribe(() => { + api.updatePagination({ fromPage: 1 }); + }); + const onRenderComplete = () => {}; return { @@ -266,6 +275,7 @@ export const getAnomalySwimLaneEmbeddableFactory = ( onSwimLaneDestroy(); onDestroy(); subscriptions.unsubscribe(); + fetchSubscription.unsubscribe(); }); const [fromPage, perPage, swimlaneType, swimlaneData, error] = diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_controls.ts b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_controls.ts index 79693cad6ea6b..1301b29f80661 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_controls.ts +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/initialize_swim_lane_controls.ts @@ -8,8 +8,7 @@ import type { StateComparators } from '@kbn/presentation-publishing'; import type { TitlesApi } from '@kbn/presentation-publishing/interfaces/titles/titles_api'; import fastIsEqual from 'fast-deep-equal'; -import type { Observable } from 'rxjs'; -import { BehaviorSubject, combineLatest, merge } from 'rxjs'; +import { BehaviorSubject, combineLatest } from 'rxjs'; import type { AnomalySwimlaneEmbeddableUserInput } from '..'; import type { JobId } from '../../../common/types/anomaly_detection_jobs'; import type { SwimlaneType } from '../../application/explorer/explorer_constants'; @@ -23,8 +22,7 @@ export type AnomalySwimLaneControlsState = Pick< export const initializeSwimLaneControls = ( rawState: AnomalySwimLaneEmbeddableState, - titlesApi: TitlesApi, - swimlaneControlsDependencies$: Observable + titlesApi: TitlesApi ) => { const jobIds = new BehaviorSubject(rawState.jobIds); const swimlaneType = new BehaviorSubject(rawState.swimlaneType); @@ -48,10 +46,7 @@ export const initializeSwimLaneControls = ( } }; - const subscription = merge( - combineLatest([jobIds, swimlaneType, viewBy]), - swimlaneControlsDependencies$ - ).subscribe(() => { + const subscription = combineLatest([jobIds, swimlaneType, viewBy]).subscribe(() => { updatePagination({ fromPage: 1 }); }); From 55c3e67035b099f068d289119e9634e25ebc659c Mon Sep 17 00:00:00 2001 From: rbrtj Date: Wed, 9 Oct 2024 17:34:24 +0200 Subject: [PATCH 7/7] use existing subscription --- .../anomaly_swimlane_embeddable_factory.tsx | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.tsx b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.tsx index 2a76dcddb1a53..464b5bd196675 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.tsx +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.tsx @@ -237,18 +237,20 @@ export const getAnomalySwimLaneEmbeddableFactory = ( anomalySwimLaneServices ); - const fetchSubscription = fetch$(api) - .pipe( - map((fetchContext) => ({ - query: fetchContext.query, - filters: fetchContext.filters, - timeRange: fetchContext.timeRange, - })), - distinctUntilChanged(fastIsEqual) - ) - .subscribe(() => { - api.updatePagination({ fromPage: 1 }); - }); + subscriptions.add( + fetch$(api) + .pipe( + map((fetchContext) => ({ + query: fetchContext.query, + filters: fetchContext.filters, + timeRange: fetchContext.timeRange, + })), + distinctUntilChanged(fastIsEqual) + ) + .subscribe(() => { + api.updatePagination({ fromPage: 1 }); + }) + ); const onRenderComplete = () => {}; @@ -275,7 +277,6 @@ export const getAnomalySwimLaneEmbeddableFactory = ( onSwimLaneDestroy(); onDestroy(); subscriptions.unsubscribe(); - fetchSubscription.unsubscribe(); }); const [fromPage, perPage, swimlaneType, swimlaneData, error] =