Apply chunking to era{Exposure, Prefs, Slashes} (#4620)

* Apply chunking to era{Exposure, Prefs, Slashes}

* CHANGELOG

* Failsafe return location

* typo
This commit is contained in:
Jaco
2022-03-06 10:26:43 +02:00
committed by GitHub
parent 8fcda8cd54
commit 8be52dec13
2 changed files with 37 additions and 5 deletions
+36 -5
View File
@@ -7,12 +7,40 @@ import type { EraIndex } from '@polkadot/types/interfaces';
import type { ExactDerive } from '../derive';
import type { DeriveApi } from '../types';
import { combineLatest, of, switchMap } from 'rxjs';
import { BehaviorSubject, combineLatest, map, of, switchMap, tap, toArray } from 'rxjs';
import { arrayChunk, arrayFlatten } from '@polkadot/util';
import { memo } from '../util';
type ApplyReturn<T extends keyof ExactDerive['staking']> = ReturnType<ExactDerive['staking'][T]>;
// only retrieve a maximum of 14 eras (84 / 6) at a time
// (This is not empirically calculated. Rather smaller sizes take longer
// time due to the serial nature, large sizes may tie up the RPCs)
const ERA_CHUNK_SIZE = 14;
function chunkEras <T> (eras: EraIndex[], fn: (eras: EraIndex[]) => Observable<T[]>): Observable<T[]> {
const chunked = arrayChunk(eras, ERA_CHUNK_SIZE);
let index = 0;
const startSubject = new BehaviorSubject<EraIndex[]>(chunked[index]);
return startSubject.pipe(
switchMap(fn),
tap((): void => {
setTimeout((): void => {
index++;
index === chunked.length
? startSubject.complete()
: startSubject.next(chunked[index]);
}, 0);
}),
toArray(),
map(arrayFlatten)
);
}
export function filterEras <T extends { era: EraIndex }> (eras: EraIndex[], list: T[]): EraIndex[] {
return eras.filter((e) => !list.some(({ era }) => e.eq(era)));
}
@@ -53,9 +81,12 @@ export function combineEras <F extends '_eraExposure' | '_eraPrefs' | '_eraSlash
// Cannot quite get the typing right, but it is right in the code
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
memo(instanceId, (eras: EraIndex[], withActive: boolean) =>
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
eras.length
? combineLatest(eras.map((e) => api.derive.staking[fn](e, withActive)))
: of([])
!eras.length
? of([])
: chunkEras(eras, (eras) =>
combineLatest(
eras.map((e) => api.derive.staking[fn](e, withActive))
)
)
) as any;
}