Skip to content
This repository has been archived by the owner on Jan 24, 2023. It is now read-only.

Commit

Permalink
Merge pull request #2561 from cloudfoundry-incubator/pagination-obs-p…
Browse files Browse the repository at this point in the history
…erformance

Pagination obs performance
  • Loading branch information
Irfan Habib committed Jul 2, 2018
2 parents 6323111 + d768ee0 commit 3d94b9b
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 32 deletions.
19 changes: 4 additions & 15 deletions src/frontend/app/shared/monitors/entity-monitor.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,9 @@

import {interval as observableInterval, combineLatest , Observable } from 'rxjs';
import { Store } from '@ngrx/store';
import { denormalize, schema } from 'normalizr';
import { combineLatest, interval as observableInterval, Observable } from 'rxjs';
import { tag } from 'rxjs-spy/operators/tag';
import {
distinctUntilChanged,
filter,
map,
publishReplay,
refCount,
share,
startWith,
tap,
withLatestFrom,
} from 'rxjs/operators';

import { distinctUntilChanged, filter, map, publishReplay, refCount, share, startWith, tap, withLatestFrom } from 'rxjs/operators';
import { getAPIRequestDataState, selectEntity, selectRequestInfo } from '../../store/selectors/api.selectors';
import { IRequestDataState } from '../../store/types/entity.types';
import { AppState } from './../../store/app-state';
Expand All @@ -23,7 +12,7 @@ import {
getDefaultActionState,
getDefaultRequestState,
RequestInfoState,
UpdatingSection,
UpdatingSection
} from './../../store/reducers/api-request-reducer/types';

export class EntityMonitor<T = any> {
Expand Down Expand Up @@ -113,7 +102,7 @@ export class EntityMonitor<T = any> {
}),
withLatestFrom(entities$),
map(([
[entity, entityRequestInfo],
[entity],
entities
]) => {
return entity ? denormalize(entity, schema, entities) : null;
Expand Down
52 changes: 37 additions & 15 deletions src/frontend/app/shared/monitors/pagination-monitor.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { Store } from '@ngrx/store';
import { denormalize, schema } from 'normalizr';
import { Observable, combineLatest } from 'rxjs';
import { filter, map, publishReplay, refCount, pairwise, tap, distinctUntilChanged, publish, withLatestFrom } from 'rxjs/operators';

import { getAPIRequestDataState, selectEntities } from '../../store/selectors/api.selectors';
import { asapScheduler, Observable } from 'rxjs';
import { tag } from 'rxjs-spy/operators';
import { distinctUntilChanged, filter, map, observeOn, publishReplay, refCount, withLatestFrom } from 'rxjs/operators';
import { getAPIRequestDataState } from '../../store/selectors/api.selectors';
import { selectPaginationState } from '../../store/selectors/pagination.selectors';
import { AppState } from './../../store/app-state';
import { ActionState } from './../../store/reducers/api-request-reducer/types';
import { PaginationEntityState } from './../../store/types/pagination.types';


export class PaginationMonitor<T = any> {
/**
* Emits the current page of entities.
Expand Down Expand Up @@ -44,7 +45,14 @@ export class PaginationMonitor<T = any> {
* @param pagination
*/
private hasPage(pagination: PaginationEntityState) {
const hasPage = pagination && pagination.ids[pagination.currentPage];
if (!pagination) {
return false;
}
const currentPage = pagination.ids[pagination.currentPage];
const hasPageIds = !!currentPage;
const requestInfo = pagination.pageRequests[pagination.clientPagination.currentPage];
const hasPageRequestInfo = !!requestInfo;
const hasPage = hasPageIds && hasPageRequestInfo && !requestInfo.busy;
return hasPage;
}

Expand Down Expand Up @@ -84,7 +92,6 @@ export class PaginationMonitor<T = any> {
paginationKey
);
this.currentPage$ = this.createPageObservable(
store,
this.pagination$,
schema
);
Expand All @@ -98,27 +105,42 @@ export class PaginationMonitor<T = any> {
paginationKey: string
) {
return store.select(selectPaginationState(entityKey, paginationKey))
.pipe(distinctUntilChanged(), filter(pag => !!pag));
.pipe(
distinctUntilChanged(),
filter(pag => !!pag)
);
}



private createPageObservable(
store: Store<AppState>,
pagination$: Observable<PaginationEntityState>,
schema: schema.Entity
) {
return combineLatest(
pagination$,
this.store.select(selectEntities<T>(this.schema.key)).pipe(distinctUntilChanged()),
).pipe(
filter(([pagination, entities]) => this.hasPage(pagination)),
return pagination$.pipe(
// Improve efficiency
observeOn(asapScheduler),
filter((pagination) => this.hasPage(pagination)),
distinctUntilChanged(this.isPageSameIsh),
withLatestFrom(this.store.select(getAPIRequestDataState)),
map(([[pagination, entities], allEntities]) => {
map(([pagination, allEntities]) => {
const page = pagination.ids[pagination.currentPage] || [];
return page.length ? denormalize(page, [schema], allEntities).filter(ent => !!ent) : [];
})
}),
tag('de-norming ' + schema.key),
publishReplay(1),
refCount(),
);
}

private isPageSameIsh(x: PaginationEntityState, y: PaginationEntityState) {
const samePage = x.currentPage === y.currentPage;
// It's possible that we need to compare the whole page request object but busy will do for now.
const samePageBusyState = samePage && x.pageRequests[x.currentPage].busy === y.pageRequests[y.currentPage].busy;
const samePageIdList = samePage && x.ids[x.currentPage] === y.ids[y.currentPage];
return samePageIdList && samePageBusyState;
}

private createErrorObservable(pagination$: Observable<PaginationEntityState>) {
return pagination$.pipe(
map(pagination => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ function getObservables<T = any>(
));
}
}),
switchMap(() => paginationMonitor.currentPage$),
);
switchMap(() => paginationMonitor.currentPage$)
);

return {
pagination$: pagination$.pipe(
Expand Down

0 comments on commit 3d94b9b

Please sign in to comment.