Skip to content

Commit

Permalink
Add support for excludedServices option, closes #4
Browse files Browse the repository at this point in the history
  • Loading branch information
felixbrucker committed May 6, 2021
1 parent 82edd5c commit c92553d
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 102 deletions.
4 changes: 4 additions & 0 deletions lib/service/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ class Config {
return this.config.chiaDaemonAddress;
}

get excludedServices() {
return this.config.excludedServices;
}

get configExists() {
return existsSync(this.configFilePath);
}
Expand Down
235 changes: 133 additions & 102 deletions lib/service/stats-collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,19 @@ class StatsCollection {
this.stats.set(service, {});
this.isServiceRunning.set(service, false);
});
this.enabledServices = allServices;
}

async init() {
if (config.excludedServices && Array.isArray(config.excludedServices)) {
config.excludedServices
.map(excludedService => constants.SERVICE[excludedService])
.filter(excludedService => !!excludedService)
.forEach(excludedService => {
this.enabledServices = this.enabledServices.filter(service => service !== excludedService);
this.deleteStatsForService(excludedService);
});
}
const chiaConfig = new ChiaConfig(config.chiaConfigDirectory);
await chiaConfig.load();
this.origin = 'chia-dashboard-satellite';
Expand Down Expand Up @@ -74,114 +84,131 @@ class StatsCollection {
// Wait a little extra till the services are started up
await new Promise(resolve => setTimeout(resolve, 5 * 1000));
}
this.fullNodeApiClient.onNewBlockchainState(async (blockchainState) => {
const fullNodeStats = this.stats.has(constants.SERVICE.fullNode) ? this.stats.get(constants.SERVICE.fullNode) : {};
fullNodeStats.blockchainState = this.getRelevantBlockchainState(blockchainState);
await this.setStatsForService(constants.SERVICE.fullNode, fullNodeStats);
});
this.fullNodeApiClient.onConnectionChange(async connections => {
const fullNodeStats = this.stats.has(constants.SERVICE.fullNode) ? this.stats.get(constants.SERVICE.fullNode) : {};
const fullNodeConnections = connections.filter(conn => conn.type === constants.SERVICE_TYPE.fullNode);
fullNodeStats.fullNodeConnections = fullNodeConnections.map(connection => this.getRelevantConnectionData(connection));
await this.setStatsForService(constants.SERVICE.fullNode, fullNodeStats);
});
this.farmerApiClient.onNewFarmingInfo(async (newFarmingInfo) => {
const farmerStats = this.stats.has(constants.SERVICE.farmer) ? this.stats.get(constants.SERVICE.farmer) : {};
if (!farmerStats.farmingInfos) {
farmerStats.farmingInfos = [];
}
const relevantFarmingInfo = this.getRelevantFarmingInfoData(newFarmingInfo);
let matchingFarmingInfo = farmerStats.farmingInfos.find(farmingInfo =>
farmingInfo.challenge === relevantFarmingInfo.challenge && farmingInfo.signagePoint === relevantFarmingInfo.signagePoint
);
if (!matchingFarmingInfo) {
matchingFarmingInfo = {
challenge: relevantFarmingInfo.challenge,
signagePoint: relevantFarmingInfo.signagePoint,
proofs: 0,
passedFilter: 0,
totalPlots: 0,
lastUpdated: new Date(),
};
farmerStats.farmingInfos.unshift(matchingFarmingInfo);
}
matchingFarmingInfo.proofs += relevantFarmingInfo.proofs;
matchingFarmingInfo.passedFilter += relevantFarmingInfo.passedFilter;
matchingFarmingInfo.totalPlots += relevantFarmingInfo.totalPlots;
matchingFarmingInfo.lastUpdated = moment.unix(relevantFarmingInfo.timestamp).toDate();

farmerStats.farmingInfos = farmerStats.farmingInfos.slice(0, 20);
await this.setStatsForService(constants.SERVICE.farmer, farmerStats);
});
const jobLogs = new Map();
this.plotterApiClient.onNewPlottingQueueStats(async queue => {
const plotterStats = this.stats.has(constants.SERVICE.plotter) ? this.stats.get(constants.SERVICE.plotter) : {};
if (!plotterStats.jobs) {
plotterStats.jobs = [];
}
let updated = false;
let jobsArrayNeedsSort = false;
queue.forEach(job => {
if (job.deleted || job.state === plotterStates.FINISHED) {
plotterStats.jobs = plotterStats.jobs.filter(curr => curr.id !== job.id);
jobLogs.delete(job.id);
updated = true;

return;
}
let existingJob = plotterStats.jobs.find(curr => curr.id === job.id);
if (!existingJob) {
existingJob = { id: job.id };
plotterStats.jobs.push(existingJob);
jobsArrayNeedsSort = true;
updated = true;
}
if (existingJob.state !== job.state) {
updateStartedAtOfJob({ existingJob, job });
existingJob.state = job.state;
updated = true;
jobsArrayNeedsSort = true;
}
if (existingJob.kSize !== job.size) {
existingJob.kSize = job.size;
updated = true;
}
if (job.log) {
jobLogs.set(job.id, job.log);
} else if (job.log_new) {
const existingLog = jobLogs.get(job.id) || '';
jobLogs.set(job.id, `${existingLog}${job.log_new}`);
if (this.isServiceEnabled(constants.SERVICE.fullNode)) {
this.fullNodeApiClient.onNewBlockchainState(async (blockchainState) => {
const fullNodeStats = this.stats.has(constants.SERVICE.fullNode) ? this.stats.get(constants.SERVICE.fullNode) : {};
fullNodeStats.blockchainState = this.getRelevantBlockchainState(blockchainState);
await this.setStatsForService(constants.SERVICE.fullNode, fullNodeStats);
});
this.fullNodeApiClient.onConnectionChange(async connections => {
const fullNodeStats = this.stats.has(constants.SERVICE.fullNode) ? this.stats.get(constants.SERVICE.fullNode) : {};
const fullNodeConnections = connections.filter(conn => conn.type === constants.SERVICE_TYPE.fullNode);
fullNodeStats.fullNodeConnections = fullNodeConnections.map(connection => this.getRelevantConnectionData(connection));
await this.setStatsForService(constants.SERVICE.fullNode, fullNodeStats);
});
}
if (this.isServiceEnabled(constants.SERVICE.farmer)) {
this.farmerApiClient.onNewFarmingInfo(async (newFarmingInfo) => {
const farmerStats = this.stats.has(constants.SERVICE.farmer) ? this.stats.get(constants.SERVICE.farmer) : {};
if (!farmerStats.farmingInfos) {
farmerStats.farmingInfos = [];
}
const progress = getProgressOfJob({ job, log: jobLogs.get(job.id) });
if (existingJob.progress !== progress) {
existingJob.progress = progress;
updated = true;
const relevantFarmingInfo = this.getRelevantFarmingInfoData(newFarmingInfo);
let matchingFarmingInfo = farmerStats.farmingInfos.find(farmingInfo =>
farmingInfo.challenge === relevantFarmingInfo.challenge && farmingInfo.signagePoint === relevantFarmingInfo.signagePoint
);
if (!matchingFarmingInfo) {
matchingFarmingInfo = {
challenge: relevantFarmingInfo.challenge,
signagePoint: relevantFarmingInfo.signagePoint,
proofs: 0,
passedFilter: 0,
totalPlots: 0,
lastUpdated: new Date(),
};
farmerStats.farmingInfos.unshift(matchingFarmingInfo);
}
matchingFarmingInfo.proofs += relevantFarmingInfo.proofs;
matchingFarmingInfo.passedFilter += relevantFarmingInfo.passedFilter;
matchingFarmingInfo.totalPlots += relevantFarmingInfo.totalPlots;
matchingFarmingInfo.lastUpdated = moment.unix(relevantFarmingInfo.timestamp).toDate();

farmerStats.farmingInfos = farmerStats.farmingInfos.slice(0, 20);
await this.setStatsForService(constants.SERVICE.farmer, farmerStats);
});
if (jobsArrayNeedsSort) {
plotterStats.jobs.sort((a, b) => {
if (a.state === plotterStates.RUNNING && b.state !== plotterStates.RUNNING) {
return -1;
}
if (this.isServiceEnabled(constants.SERVICE.plotter)) {
const jobLogs = new Map();
this.plotterApiClient.onNewPlottingQueueStats(async queue => {
const plotterStats = this.stats.has(constants.SERVICE.plotter) ? this.stats.get(constants.SERVICE.plotter) : {};
if (!plotterStats.jobs) {
plotterStats.jobs = [];
}
let updated = false;
let jobsArrayNeedsSort = false;
queue.forEach(job => {
if (job.deleted || job.state === plotterStates.FINISHED) {
plotterStats.jobs = plotterStats.jobs.filter(curr => curr.id !== job.id);
jobLogs.delete(job.id);
updated = true;

return;
}
if (a.state !== plotterStates.RUNNING && b.state === plotterStates.RUNNING) {
return 1;
let existingJob = plotterStats.jobs.find(curr => curr.id === job.id);
if (!existingJob) {
existingJob = { id: job.id };
plotterStats.jobs.push(existingJob);
jobsArrayNeedsSort = true;
updated = true;
}
if (a.state === plotterStates.RUNNING && b.state === plotterStates.RUNNING) {
return a.progress > b.progress ? -1 : 1;
if (existingJob.state !== job.state) {
updateStartedAtOfJob({ existingJob, job });
existingJob.state = job.state;
updated = true;
jobsArrayNeedsSort = true;
}
if (existingJob.kSize !== job.size) {
existingJob.kSize = job.size;
updated = true;
}
if (job.log) {
jobLogs.set(job.id, job.log);
} else if (job.log_new) {
const existingLog = jobLogs.get(job.id) || '';
jobLogs.set(job.id, `${existingLog}${job.log_new}`);
}
const progress = getProgressOfJob({ job, log: jobLogs.get(job.id) });
if (existingJob.progress !== progress) {
existingJob.progress = progress;
updated = true;
}

return 0;
});
}
if (updated) {
await this.setStatsForService(constants.SERVICE.plotter, plotterStats);
}
});
await this.walletApiClient.init();
await this.fullNodeApiClient.init();
await this.farmerApiClient.init();
await this.harvesterApiClient.init();
await this.plotterApiClient.init();
if (jobsArrayNeedsSort) {
plotterStats.jobs.sort((a, b) => {
if (a.state === plotterStates.RUNNING && b.state !== plotterStates.RUNNING) {
return -1;
}
if (a.state !== plotterStates.RUNNING && b.state === plotterStates.RUNNING) {
return 1;
}
if (a.state === plotterStates.RUNNING && b.state === plotterStates.RUNNING) {
return a.progress > b.progress ? -1 : 1;
}

return 0;
});
}
if (updated) {
await this.setStatsForService(constants.SERVICE.plotter, plotterStats);
}
});
}

if (this.isServiceEnabled(constants.SERVICE.wallet)) {
await this.walletApiClient.init();
}
if (this.isServiceEnabled(constants.SERVICE.fullNode)) {
await this.fullNodeApiClient.init();
}
if (this.isServiceEnabled(constants.SERVICE.fullNode)) {
await this.farmerApiClient.init();
}
if (this.isServiceEnabled(constants.SERVICE.harvester)) {
await this.harvesterApiClient.init();
}
if (this.isServiceEnabled(constants.SERVICE.plotter)) {
await this.plotterApiClient.init();
}
await this.updateRunningServices();
await this.updateStats();
await this.updateFullNodeStats();
Expand Down Expand Up @@ -325,7 +352,7 @@ class StatsCollection {

async updateRunningServices() {
// Ignore the plotter service here as it is only running when plotting
await Promise.all(allServices.filter(service => service !== constants.SERVICE.plotter).map(async service => {
await Promise.all(this.enabledServices.filter(service => service !== constants.SERVICE.plotter).map(async service => {
const isRunning = await this.daemonApiClient.isServiceRunning(service);

this.isServiceRunning.set(service, isRunning);
Expand All @@ -338,6 +365,10 @@ class StatsCollection {
getStats() {
return Object.fromEntries(this.stats);
}

isServiceEnabled(service) {
return this.enabledServices.some(curr => curr === service);
}
}

module.exports = new StatsCollection();

0 comments on commit c92553d

Please sign in to comment.