From fa8a62fb8f8da3a854764e3e24d9b7abc00204e2 Mon Sep 17 00:00:00 2001 From: Sarthak0702 Date: Mon, 23 May 2022 21:31:45 +0530 Subject: [PATCH] mgr/dashboard: stop polling when page is not visible Signed-off-by: Sarthak0702 --- .../shared/datatable/table/table.component.ts | 20 ++++++++++--------- .../rxjs/operators/page-visibilty.operator.ts | 20 +++++++++++++++++++ .../services/motd-notification.service.ts | 4 +++- .../src/app/shared/services/timer.service.ts | 4 +++- 4 files changed, 37 insertions(+), 11 deletions(-) create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/rxjs/operators/page-visibilty.operator.ts diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts index 96bf2336e92d3..3f2c6dff7baf6 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts @@ -5,7 +5,6 @@ import { Component, EventEmitter, Input, - NgZone, OnChanges, OnDestroy, OnInit, @@ -24,7 +23,7 @@ import { TableColumnProp } from '@swimlane/ngx-datatable'; import _ from 'lodash'; -import { Observable, Subject, Subscription, timer as observableTimer } from 'rxjs'; +import { Observable, of, Subject, Subscription } from 'rxjs'; import { TableStatus } from '~/app/shared/classes/table-status'; import { CellTemplate } from '~/app/shared/enum/cell-template.enum'; @@ -35,6 +34,7 @@ import { CdTableColumnFiltersChange } from '~/app/shared/models/cd-table-column- import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context'; import { CdTableSelection } from '~/app/shared/models/cd-table-selection'; import { CdUserConfig } from '~/app/shared/models/cd-user-config'; +import { TimerService } from '~/app/shared/services/timer.service'; @Component({ selector: 'cd-table', @@ -234,7 +234,11 @@ export class TableComponent implements AfterContentChecked, OnInit, OnChanges, O }); } - constructor(private ngZone: NgZone, private cdRef: ChangeDetectorRef) {} + constructor( + // private ngZone: NgZone, + private cdRef: ChangeDetectorRef, + private timerService: TimerService + ) {} static prepareSearch(search: string) { search = search.toLowerCase().replace(/,/g, ''); @@ -296,13 +300,11 @@ export class TableComponent implements AfterContentChecked, OnInit, OnChanges, O this.loadingIndicator = true; } if (_.isInteger(this.autoReload) && this.autoReload > 0) { - this.ngZone.runOutsideAngular(() => { - this.reloadSubscriber = observableTimer(0, this.autoReload).subscribe(() => { - this.ngZone.run(() => { - return this.reloadData(); - }); + this.reloadSubscriber = this.timerService + .get(() => of(0), this.autoReload) + .subscribe(() => { + this.reloadData(); }); - }); } else if (!this.autoReload) { this.reloadData(); } else { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/rxjs/operators/page-visibilty.operator.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/rxjs/operators/page-visibilty.operator.ts new file mode 100644 index 0000000000000..22644dcf20afa --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/rxjs/operators/page-visibilty.operator.ts @@ -0,0 +1,20 @@ +import { fromEvent, Observable, partition } from 'rxjs'; +import { repeatWhen, shareReplay, takeUntil } from 'rxjs/operators'; + +export function whenPageVisible() { + const visibilitychange$ = fromEvent(document, 'visibilitychange').pipe( + shareReplay({ refCount: true, bufferSize: 1 }) + ); + + const [pageVisible$, pageHidden$] = partition( + visibilitychange$, + () => document.visibilityState === 'visible' + ); + + return function (source: Observable) { + return source.pipe( + takeUntil(pageHidden$), + repeatWhen(() => pageVisible$) + ); + }; +} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/motd-notification.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/motd-notification.service.ts index 11feca26b0531..d2ee89f9cd168 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/motd-notification.service.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/motd-notification.service.ts @@ -5,6 +5,7 @@ import { BehaviorSubject, EMPTY, Observable, of, Subscription } from 'rxjs'; import { catchError, delay, mergeMap, repeat, tap } from 'rxjs/operators'; import { Motd, MotdService } from '~/app/shared/api/motd.service'; +import { whenPageVisible } from '../rxjs/operators/page-visibilty.operator'; @Injectable({ providedIn: 'root' @@ -31,7 +32,8 @@ export class MotdNotificationService implements OnDestroy { }), tap((motd: Motd | null) => this.processResponse(motd)), delay(60000), - repeat() + repeat(), + whenPageVisible() ) .subscribe(); } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/timer.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/timer.service.ts index 2ae2f4cdf5ebc..716b710968f33 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/timer.service.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/timer.service.ts @@ -3,6 +3,7 @@ import { Injectable } from '@angular/core'; import { Observable, timer } from 'rxjs'; import { observeOn, shareReplay, switchMap } from 'rxjs/operators'; +import { whenPageVisible } from '../rxjs/operators/page-visibilty.operator'; import { NgZoneSchedulerService } from './ngzone-scheduler.service'; @Injectable({ @@ -21,7 +22,8 @@ export class TimerService { return timer(dueTime, refreshInterval, this.ngZone.leave).pipe( observeOn(this.ngZone.enter), switchMap(next), - shareReplay({ refCount: true, bufferSize: 1 }) + shareReplay({ refCount: true, bufferSize: 1 }), + whenPageVisible() ); } } -- 2.39.5