mirror of
https://github.com/mempool/mempool.git
synced 2025-03-03 17:47:01 +01:00
Create indexing sticky notification that show indexing progress in all mining dashboard related pages
This commit is contained in:
parent
11cdbb3118
commit
802e10e0a9
19 changed files with 95 additions and 20 deletions
|
@ -221,9 +221,10 @@ class Blocks {
|
|||
const lastBlockToIndex = Math.max(0, currentBlockHeight - indexingBlockAmount + 1);
|
||||
|
||||
logger.debug(`Indexing blocks from #${currentBlockHeight} to #${lastBlockToIndex}`);
|
||||
loadingIndicators.setProgress('block-indexing', 0);
|
||||
|
||||
const chunkSize = 10000;
|
||||
let totaIndexed = await blocksRepository.$blockCount(null, null);
|
||||
let totaIndexed = await blocksRepository.$blockCountBetweenHeight(currentBlockHeight, lastBlockToIndex);
|
||||
let indexedThisRun = 0;
|
||||
let newlyIndexed = 0;
|
||||
const startedAt = new Date().getTime() / 1000;
|
||||
|
@ -256,6 +257,7 @@ class Blocks {
|
|||
logger.debug(`Indexing block #${blockHeight} | ~${blockPerSeconds} blocks/sec | total: ${totaIndexed}/${indexingBlockAmount} (${progress}%) | elapsed: ${runningFor} seconds | left: ~${timeLeft} seconds`);
|
||||
timer = new Date().getTime() / 1000;
|
||||
indexedThisRun = 0;
|
||||
loadingIndicators.setProgress('block-indexing', progress);
|
||||
}
|
||||
const blockHash = await bitcoinApi.$getBlockHash(blockHeight);
|
||||
const block = BitcoinApi.convertBlock(await bitcoinClient.getBlock(blockHash));
|
||||
|
@ -269,9 +271,11 @@ class Blocks {
|
|||
currentBlockHeight -= chunkSize;
|
||||
}
|
||||
logger.info(`Indexed ${newlyIndexed} blocks`);
|
||||
loadingIndicators.setProgress('block-indexing', 100);
|
||||
} catch (e) {
|
||||
logger.err('Block indexing failed. Trying again later. Reason: ' + (e instanceof Error ? e.message : e));
|
||||
this.blockIndexingStarted = false;
|
||||
loadingIndicators.setProgress('block-indexing', 100);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -188,6 +188,24 @@ class BlocksRepository {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get blocks count for a period
|
||||
*/
|
||||
public async $blockCountBetweenHeight(startHeight: number, endHeight: number): Promise<number> {
|
||||
const params: any[] = [];
|
||||
let query = `SELECT count(height) as blockCount
|
||||
FROM blocks
|
||||
WHERE height <= ${startHeight} AND height >= ${endHeight}`;
|
||||
|
||||
try {
|
||||
const [rows] = await DB.query(query, params);
|
||||
return <number>rows[0].blockCount;
|
||||
} catch (e) {
|
||||
logger.err(`Cannot count blocks for this pool (using offset). Reason: ` + (e instanceof Error ? e.message : e));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the oldest indexed block
|
||||
*/
|
||||
|
|
|
@ -76,6 +76,7 @@ import { DataCyDirective } from './data-cy.directive';
|
|||
import { BlockFeesGraphComponent } from './components/block-fees-graph/block-fees-graph.component';
|
||||
import { BlockRewardsGraphComponent } from './components/block-rewards-graph/block-rewards-graph.component';
|
||||
import { BlockFeeRatesGraphComponent } from './components/block-fee-rates-graph/block-fee-rates-graph.component';
|
||||
import { LoadingIndicatorComponent } from './components/loading-indicator/loading-indicator.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
|
@ -132,6 +133,7 @@ import { BlockFeeRatesGraphComponent } from './components/block-fee-rates-graph/
|
|||
BlockFeesGraphComponent,
|
||||
BlockRewardsGraphComponent,
|
||||
BlockFeeRatesGraphComponent,
|
||||
LoadingIndicatorComponent,
|
||||
],
|
||||
imports: [
|
||||
BrowserModule.withServerTransition({ appId: 'serverApp' }),
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
<app-loading-indicator [name]="'block-indexing'"></app-loading-indicator>
|
||||
|
||||
<div class="full-container">
|
||||
<div class="card-header mb-0 mb-md-4">
|
||||
<span i18n="mining.block-fee-rates">Block fee rates</span>
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
<app-loading-indicator [name]="'block-indexing'"></app-loading-indicator>
|
||||
|
||||
<div class="full-container">
|
||||
<div class="card-header mb-0 mb-md-4">
|
||||
<span i18n="mining.block-fees">Block fees</span>
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
<app-loading-indicator [name]="'block-indexing'"></app-loading-indicator>
|
||||
|
||||
<div class="full-container">
|
||||
|
||||
<div class="card-header mb-0 mb-md-4">
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
<app-loading-indicator [name]="'block-indexing'"></app-loading-indicator>
|
||||
|
||||
<div class="container-xl" [class]="widget ? 'widget' : 'full-height'">
|
||||
<h1 *ngIf="!widget" class="float-left" i18n="latest-blocks.blocks">Blocks</h1>
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
<app-loading-indicator [name]="'block-indexing'"></app-loading-indicator>
|
||||
|
||||
<div [class]="widget === false ? 'full-container' : ''">
|
||||
|
||||
<div *ngIf="widget">
|
||||
|
|
|
@ -136,16 +136,12 @@ export class HashrateChartComponent implements OnInit {
|
|||
prepareChartOptions(data) {
|
||||
let title: object;
|
||||
if (data.hashrates.length === 0) {
|
||||
const lastBlock = new Date(data.timestamp * 1000);
|
||||
const dd = String(lastBlock.getDate()).padStart(2, '0');
|
||||
const mm = String(lastBlock.getMonth() + 1).padStart(2, '0'); // January is 0!
|
||||
const yyyy = lastBlock.getFullYear();
|
||||
title = {
|
||||
textStyle: {
|
||||
color: 'grey',
|
||||
fontSize: 15
|
||||
},
|
||||
text: `Indexing in progess - ${yyyy}-${mm}-${dd}`,
|
||||
text: `Indexing in progess`,
|
||||
left: 'center',
|
||||
top: 'center'
|
||||
};
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
<app-loading-indicator [name]="'block-indexing'"></app-loading-indicator>
|
||||
|
||||
<div class="full-container">
|
||||
|
||||
<div class="card-header mb-0 mb-md-4">
|
||||
|
|
|
@ -150,16 +150,12 @@ export class HashrateChartPoolsComponent implements OnInit {
|
|||
prepareChartOptions(data) {
|
||||
let title: object;
|
||||
if (data.series.length === 0) {
|
||||
const lastBlock = new Date(data.timestamp * 1000);
|
||||
const dd = String(lastBlock.getDate()).padStart(2, '0');
|
||||
const mm = String(lastBlock.getMonth() + 1).padStart(2, '0'); // January is 0!
|
||||
const yyyy = lastBlock.getFullYear();
|
||||
title = {
|
||||
textStyle: {
|
||||
color: 'grey',
|
||||
fontSize: 15
|
||||
},
|
||||
text: `Indexing in progess - ${yyyy}-${mm}-${dd}`,
|
||||
text: `Indexing in progess`,
|
||||
left: 'center',
|
||||
top: 'center',
|
||||
};
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
<div *ngIf="this.indexingProgress$ | async as progress" class="sticky-loading">
|
||||
<span *ngIf="progress >= 0" class="mr-auto badge badge-pill badge-warning">Indexing blocks ({{ progress }}%)</span>
|
||||
</div>
|
|
@ -0,0 +1,14 @@
|
|||
.sticky-loading {
|
||||
position: fixed;
|
||||
right: 10px;
|
||||
z-index: 100;
|
||||
@media (width > 991px) {
|
||||
bottom: 15px;
|
||||
}
|
||||
@media (576px <= width <= 991px) {
|
||||
bottom: 60px;
|
||||
}
|
||||
@media (width <= 575px) {
|
||||
top: 17px;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-loading-indicator',
|
||||
templateUrl: './loading-indicator.component.html',
|
||||
styleUrls: ['./loading-indicator.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class LoadingIndicatorComponent implements OnInit {
|
||||
@Input() name: string;
|
||||
|
||||
public indexingProgress$: Observable<number>;
|
||||
|
||||
constructor(
|
||||
private stateService: StateService,
|
||||
private websocketService: WebsocketService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.indexingProgress$ = this.stateService.loadingIndicators$
|
||||
.pipe(
|
||||
map((indicators) => indicators[this.name] ?? -1)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
<app-loading-indicator [name]="'block-indexing'"></app-loading-indicator>
|
||||
|
||||
<div class="container-xl dashboard-container">
|
||||
|
||||
<div class="row row-cols-1 row-cols-md-2">
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { SeoService } from 'src/app/services/seo.service';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
|
||||
@Component({
|
||||
|
@ -12,8 +9,6 @@ import { WebsocketService } from 'src/app/services/websocket.service';
|
|||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class MiningDashboardComponent implements OnInit {
|
||||
private blocks = [];
|
||||
|
||||
constructor(
|
||||
private seoService: SeoService,
|
||||
private websocketService: WebsocketService,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
<app-loading-indicator [name]="'block-indexing'"></app-loading-indicator>
|
||||
|
||||
<div [class]="widget === false ? 'full-container' : ''">
|
||||
|
||||
<div *ngIf="widget">
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
<app-loading-indicator [name]="'block-indexing'"></app-loading-indicator>
|
||||
|
||||
<div class="container-xl">
|
||||
|
||||
<!-- Pool overview -->
|
||||
|
|
|
@ -111,7 +111,7 @@ export class PoolComponent implements OnInit {
|
|||
color: 'grey',
|
||||
fontSize: 15
|
||||
},
|
||||
text: `No data`,
|
||||
text: `Indexing in progress`,
|
||||
left: 'center',
|
||||
top: 'center'
|
||||
};
|
||||
|
@ -164,14 +164,14 @@ export class PoolComponent implements OnInit {
|
|||
`;
|
||||
}.bind(this)
|
||||
},
|
||||
xAxis: {
|
||||
xAxis: data.length === 0 ? undefined : {
|
||||
type: 'time',
|
||||
splitNumber: (this.isMobile()) ? 5 : 10,
|
||||
axisLabel: {
|
||||
hideOverlap: true,
|
||||
}
|
||||
},
|
||||
yAxis: [
|
||||
yAxis: data.length === 0 ? undefined : [
|
||||
{
|
||||
min: (value) => {
|
||||
return value.min * 0.9;
|
||||
|
@ -190,7 +190,7 @@ export class PoolComponent implements OnInit {
|
|||
}
|
||||
},
|
||||
],
|
||||
series: [
|
||||
series: data.length === 0 ? undefined : [
|
||||
{
|
||||
zlevel: 0,
|
||||
name: 'Hashrate',
|
||||
|
|
Loading…
Add table
Reference in a new issue