[8.6] [ML] Fix polling for notifications after leaving the ML app (#146203) (#146292)

# Backport

This will backport the following commits from `main` to `8.6`:
- [[ML] Fix polling for notifications after leaving the ML app
(#146203)](https://github.com/elastic/kibana/pull/146203)

<!--- Backport version: 8.9.7 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Dima
Arnautov","email":"dmitrii.arnautov@elastic.co"},"sourceCommit":{"committedDate":"2022-11-24T14:08:33Z","message":"[ML]
Fix polling for notifications after leaving the ML app (#146203)\n\n##
Summary\r\n\r\nFixes notifications count polling on app leave. The issue
was with the\r\n`useMount` hook that doesn't support a callback
execution on unmount.\r\n\r\n### Checklist\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios","sha":"93c594aa56ceda86d39f5ad9657d2ba45ddb138f","branchLabelMapping":{"^v8.7.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":[":ml","release_note:skip","Team:ML","v8.6.0","v8.7.0"],"number":146203,"url":"https://github.com/elastic/kibana/pull/146203","mergeCommit":{"message":"[ML]
Fix polling for notifications after leaving the ML app (#146203)\n\n##
Summary\r\n\r\nFixes notifications count polling on app leave. The issue
was with the\r\n`useMount` hook that doesn't support a callback
execution on unmount.\r\n\r\n### Checklist\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios","sha":"93c594aa56ceda86d39f5ad9657d2ba45ddb138f"}},"sourceBranch":"main","suggestedTargetBranches":["8.6"],"targetPullRequestStates":[{"branch":"8.6","label":"v8.6.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.7.0","labelRegex":"^v8.7.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/146203","number":146203,"mergeCommit":{"message":"[ML]
Fix polling for notifications after leaving the ML app (#146203)\n\n##
Summary\r\n\r\nFixes notifications count polling on app leave. The issue
was with the\r\n`useMount` hook that doesn't support a callback
execution on unmount.\r\n\r\n### Checklist\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios","sha":"93c594aa56ceda86d39f5ad9657d2ba45ddb138f"}}]}]
BACKPORT-->

Co-authored-by: Dima Arnautov <dmitrii.arnautov@elastic.co>
This commit is contained in:
Kibana Machine 2022-11-24 10:11:14 -05:00 committed by GitHub
parent 9f0e2d6874
commit 08e61997d5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 25 deletions

View file

@ -209,6 +209,25 @@ describe('useMlNotifications', () => {
expect(result.current.lastCheckedAt).toEqual(1664551009292);
});
test('stops fetching notifications on leave', () => {
const { unmount } = renderHook(useMlNotifications, {
wrapper: MlNotificationsContextProvider,
});
act(() => {
jest.advanceTimersByTime(0);
});
expect(mockCountMessages).toHaveBeenCalledTimes(1);
unmount();
act(() => {
jest.advanceTimersByTime(60001);
});
expect(mockCountMessages).toHaveBeenCalledTimes(1);
});
test('does not start polling if requires capabilities are missing', () => {
mockKibana.services.application.capabilities.ml = {
canGetJobs: true,

View file

@ -5,12 +5,11 @@
* 2.0.
*/
import React, { FC, useContext, useState } from 'react';
import React, { FC, useContext, useState, useEffect } from 'react';
import { combineLatest, timer } from 'rxjs';
import { switchMap, map, tap, retry } from 'rxjs/operators';
import moment from 'moment';
import { isPopulatedObject } from '@kbn/ml-is-populated-object';
import useMount from 'react-use/lib/useMount';
import { useMlKibana } from '../kibana';
import { useStorage } from '../storage';
import { ML_NOTIFICATIONS_LAST_CHECKED_AT } from '../../../../common/types/storage';
@ -56,31 +55,34 @@ export const MlNotificationsContextProvider: FC = ({ children }) => {
const [notificationsCounts, setNotificationsCounts] =
useState<NotificationsCountResponse>(defaultCounts);
useMount(function startPollingNotifications() {
if (!canGetNotifications) return;
useEffect(
function startPollingNotifications() {
if (!canGetNotifications) return;
const subscription = combineLatest([lastCheckedAt$, timer(0, NOTIFICATIONS_CHECK_INTERVAL)])
.pipe(
// Use the latest check time or 7 days ago by default.
map(([lastChecked]) => lastChecked ?? moment().subtract(7, 'd').valueOf()),
tap((lastCheckedAtQuery) => {
setLatestRequestedAt(lastCheckedAtQuery);
}),
switchMap((lastCheckedAtQuery) =>
mlApiServices.notifications.countMessages$({
lastCheckedAt: lastCheckedAtQuery,
})
),
retry({ delay: NOTIFICATIONS_CHECK_INTERVAL })
)
.subscribe((response) => {
setNotificationsCounts(isPopulatedObject(response) ? response : defaultCounts);
});
const subscription = combineLatest([lastCheckedAt$, timer(0, NOTIFICATIONS_CHECK_INTERVAL)])
.pipe(
// Use the latest check time or 7 days ago by default.
map(([lastChecked]) => lastChecked ?? moment().subtract(7, 'd').valueOf()),
tap((lastCheckedAtQuery) => {
setLatestRequestedAt(lastCheckedAtQuery);
}),
switchMap((lastCheckedAtQuery) =>
mlApiServices.notifications.countMessages$({
lastCheckedAt: lastCheckedAtQuery,
})
),
retry({ delay: NOTIFICATIONS_CHECK_INTERVAL })
)
.subscribe((response) => {
setNotificationsCounts(isPopulatedObject(response) ? response : defaultCounts);
});
return () => {
subscription.unsubscribe();
};
});
return () => {
subscription.unsubscribe();
};
},
[canGetNotifications, lastCheckedAt$, mlApiServices.notifications]
);
return (
<MlNotificationsContext.Provider