Merge pull request #4556 from mempool/mononaut/smooth-mempool-blocks
Smooth out irregular mempool block updates
This commit is contained in:
commit
f9dfb3b2b1
@ -11,7 +11,7 @@ export default class BlockScene {
|
|||||||
getColor: ((tx: TxView) => Color) = defaultColorFunction;
|
getColor: ((tx: TxView) => Color) = defaultColorFunction;
|
||||||
orientation: string;
|
orientation: string;
|
||||||
flip: boolean;
|
flip: boolean;
|
||||||
animationDuration: number = 1000;
|
animationDuration: number = 900;
|
||||||
configAnimationOffset: number | null;
|
configAnimationOffset: number | null;
|
||||||
animationOffset: number;
|
animationOffset: number;
|
||||||
highlightingEnabled: boolean;
|
highlightingEnabled: boolean;
|
||||||
|
@ -3,8 +3,8 @@ import { Component, ComponentRef, ViewChild, HostListener, Input, Output, EventE
|
|||||||
import { StateService } from '../../services/state.service';
|
import { StateService } from '../../services/state.service';
|
||||||
import { MempoolBlockDelta, TransactionStripped } from '../../interfaces/websocket.interface';
|
import { MempoolBlockDelta, TransactionStripped } from '../../interfaces/websocket.interface';
|
||||||
import { BlockOverviewGraphComponent } from '../../components/block-overview-graph/block-overview-graph.component';
|
import { BlockOverviewGraphComponent } from '../../components/block-overview-graph/block-overview-graph.component';
|
||||||
import { Subscription, BehaviorSubject, merge, of } from 'rxjs';
|
import { Subscription, BehaviorSubject, merge, of, timer } from 'rxjs';
|
||||||
import { switchMap, filter } from 'rxjs/operators';
|
import { switchMap, filter, concatMap, map } from 'rxjs/operators';
|
||||||
import { WebsocketService } from '../../services/websocket.service';
|
import { WebsocketService } from '../../services/websocket.service';
|
||||||
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
|
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
@ -33,7 +33,9 @@ export class MempoolBlockOverviewComponent implements OnInit, OnDestroy, OnChang
|
|||||||
poolDirection: string = 'left';
|
poolDirection: string = 'left';
|
||||||
|
|
||||||
blockSub: Subscription;
|
blockSub: Subscription;
|
||||||
deltaSub: Subscription;
|
rateLimit = 1000;
|
||||||
|
private lastEventTime = Date.now() - this.rateLimit;
|
||||||
|
private subId = 0;
|
||||||
|
|
||||||
firstLoad: boolean = true;
|
firstLoad: boolean = true;
|
||||||
|
|
||||||
@ -55,11 +57,39 @@ export class MempoolBlockOverviewComponent implements OnInit, OnDestroy, OnChang
|
|||||||
|
|
||||||
ngAfterViewInit(): void {
|
ngAfterViewInit(): void {
|
||||||
this.blockSub = merge(
|
this.blockSub = merge(
|
||||||
of(true),
|
this.stateService.mempoolBlockTransactions$,
|
||||||
this.stateService.connectionState$.pipe(filter((state) => state === 2))
|
this.stateService.mempoolBlockDelta$,
|
||||||
)
|
).pipe(
|
||||||
.pipe(switchMap(() => this.stateService.mempoolBlockTransactions$))
|
concatMap(update => {
|
||||||
.subscribe((transactionsStripped) => {
|
const now = Date.now();
|
||||||
|
const timeSinceLastEvent = now - this.lastEventTime;
|
||||||
|
this.lastEventTime = Math.max(now, this.lastEventTime + this.rateLimit);
|
||||||
|
|
||||||
|
const subId = this.subId;
|
||||||
|
|
||||||
|
// If time since last event is less than X seconds, delay this event
|
||||||
|
if (timeSinceLastEvent < this.rateLimit) {
|
||||||
|
return timer(this.rateLimit - timeSinceLastEvent).pipe(
|
||||||
|
// Emit the event after the timer
|
||||||
|
map(() => ({ update, subId }))
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// If enough time has passed, emit the event immediately
|
||||||
|
return of({ update, subId });
|
||||||
|
}
|
||||||
|
})
|
||||||
|
).subscribe(({ update, subId }) => {
|
||||||
|
// discard stale updates after a block transition
|
||||||
|
if (subId !== this.subId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// process update
|
||||||
|
if (update['added']) {
|
||||||
|
// delta
|
||||||
|
this.updateBlock(update as MempoolBlockDelta);
|
||||||
|
} else {
|
||||||
|
const transactionsStripped = update as TransactionStripped[];
|
||||||
|
// new transactions
|
||||||
if (this.firstLoad) {
|
if (this.firstLoad) {
|
||||||
this.replaceBlock(transactionsStripped);
|
this.replaceBlock(transactionsStripped);
|
||||||
} else {
|
} else {
|
||||||
@ -94,14 +124,13 @@ export class MempoolBlockOverviewComponent implements OnInit, OnDestroy, OnChang
|
|||||||
added
|
added
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
this.deltaSub = this.stateService.mempoolBlockDelta$.subscribe((delta) => {
|
|
||||||
this.updateBlock(delta);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes): void {
|
ngOnChanges(changes): void {
|
||||||
if (changes.index) {
|
if (changes.index) {
|
||||||
|
this.subId++;
|
||||||
this.firstLoad = true;
|
this.firstLoad = true;
|
||||||
if (this.blockGraph) {
|
if (this.blockGraph) {
|
||||||
this.blockGraph.clear(changes.index.currentValue > changes.index.previousValue ? this.chainDirection : this.poolDirection);
|
this.blockGraph.clear(changes.index.currentValue > changes.index.previousValue ? this.chainDirection : this.poolDirection);
|
||||||
@ -113,7 +142,6 @@ export class MempoolBlockOverviewComponent implements OnInit, OnDestroy, OnChang
|
|||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
this.blockSub.unsubscribe();
|
this.blockSub.unsubscribe();
|
||||||
this.deltaSub.unsubscribe();
|
|
||||||
this.timeLtrSubscription.unsubscribe();
|
this.timeLtrSubscription.unsubscribe();
|
||||||
this.websocketService.stopTrackMempoolBlock();
|
this.websocketService.stopTrackMempoolBlock();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user