Skip to content
Snippets Groups Projects
Commit 1ed1bbac authored by capossele's avatar capossele
Browse files

:construction: dRNG dashboard tab WIP

parent cac95695
No related branches found
No related tags found
No related merge requests found
package spa
import (
"time"
"github.com/iotaledger/hive.go/daemon"
"github.com/iotaledger/hive.go/events"
"github.com/iotaledger/hive.go/workerpool"
"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
"github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle"
"github.com/iotaledger/goshimmer/packages/shutdown"
"github.com/iotaledger/goshimmer/plugins/messagelayer"
)
var drngLiveFeedWorkerCount = 1
var drngLiveFeedWorkerQueueSize = 50
var drngLiveFeedWorkerPool *workerpool.WorkerPool
func configureDrngLiveFeed() {
liveFeedWorkerPool = workerpool.New(func(task workerpool.Task) {
task.Param(0).(*message.CachedMessage).Consume(func(message *message.Message) {
sendToAllWSClient(&msg{MsgTypeTx, &tx{message.Id().String(), 0}})
})
task.Return(nil)
}, workerpool.WorkerCount(drngLiveFeedWorkerCount), workerpool.QueueSize(drngLiveFeedWorkerQueueSize))
}
func runDrngLiveFeed() {
newMsgRateLimiter := time.NewTicker(time.Second / 10)
notifyNewMsg := events.NewClosure(func(message *message.CachedMessage, metadata *tangle.CachedMessageMetadata) {
metadata.Release()
select {
case <-newMsgRateLimiter.C:
drngLiveFeedWorkerPool.TrySubmit(message)
default:
message.Release()
}
})
daemon.BackgroundWorker("SPA[DrngUpdater]", func(shutdownSignal <-chan struct{}) {
messagelayer.Tangle.Events.TransactionAttached.Attach(notifyNewMsg)
drngLiveFeedWorkerPool.Start()
<-shutdownSignal
log.Info("Stopping SPA[DrngUpdater] ...")
messagelayer.Tangle.Events.TransactionAttached.Detach(notifyNewMsg)
newMsgRateLimiter.Stop()
drngLiveFeedWorkerPool.Stop()
log.Info("Stopping SPA[DrngUpdater] ... done")
}, shutdown.ShutdownPrioritySPA)
}
This diff is collapsed.
......@@ -13,6 +13,10 @@
"license": "MIT",
"devDependencies": {
"@babel/core": "^7.2.2",
"@jimp/custom": "^0.10.1",
"@jimp/plugin-blur": "^0.10.1",
"@jimp/plugin-color": "^0.10.1",
"@jimp/plugin-resize": "^0.10.1",
"@types/classnames": "^2.2.7",
"@types/react": "^16.7.20",
"@types/react-dom": "^16.0.11",
......@@ -23,8 +27,10 @@
"file-loader": "^3.0.1",
"html-loader": "^1.0.0-alpha.0",
"html-webpack-plugin": "^3.2.0",
"jquery": "^3.4.1",
"mini-css-extract-plugin": "^0.5.0",
"mobx-react-devtools": "^6.0.3",
"popper.js": "^1.16.1",
"postcss": "^7.0.13",
"postcss-browser-reporter": "^0.5.0",
"postcss-import": "^12.0.1",
......@@ -58,9 +64,11 @@
"classnames": "^2.2.6",
"dateformat": "^3.0.3",
"favicons-webpack-plugin": "^2.1.0",
"history": "^4.10.1",
"mobx": "^5.15.0",
"mobx-react": "^5.4.3",
"mobx-react-router": "^4.0.5",
"moment": "^2.24.0",
"prettysize": "^2.0.0",
"react": "^16.7.0",
"react-apexcharts": "^1.3.3",
......
import * as React from 'react';
import Container from "react-bootstrap/Container";
import NodeStore from "app/stores/NodeStore";
import {inject, observer} from "mobx-react";
import {DrngLiveFeed} from "app/components/DrngLiveFeed";
interface Props {
nodeStore?: NodeStore;
}
@inject("nodeStore")
@observer
export class Drng extends React.Component<Props, any> {
render() {
return (
<Container>
<h3>dRNG Explorer</h3>
<DrngLiveFeed/>
</Container>
);
}
}
import * as React from 'react';
import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";
import NodeStore from "app/stores/NodeStore";
import {inject, observer} from "mobx-react";
import Card from "react-bootstrap/Card";
import DrngStore from "app/stores/DrngStore";
import Table from "react-bootstrap/Table";
interface Props {
nodeStore?: NodeStore;
drngStore?: DrngStore;
}
@inject("nodeStore")
@inject("drngStore")
@observer
export class DrngLiveFeed extends React.Component<Props, any> {
render() {
let {msgsLiveFeed} = this.props.drngStore;
return (
<Row className={"mb-3"}>
<Col>
<Card>
<Card.Body>
<Card.Title>Live Feed</Card.Title>
<Row className={"mb-3"}>
<Col xs={12}>
<h6>Messages</h6>
<Table>
<thead>
<tr>
<td>ID</td>
<td>Random value</td>
</tr>
</thead>
<tbody>
{msgsLiveFeed}
</tbody>
</Table>
</Col>
</Row>
</Card.Body>
</Card>
</Col>
</Row>
);
}
}
......@@ -6,6 +6,7 @@ import Nav from "react-bootstrap/Nav";
import {Dashboard} from "app/components/Dashboard";
import Badge from "react-bootstrap/Badge";
import {RouterStore} from 'mobx-react-router';
import {Drng} from "app/components/Drng";
import {Explorer} from "app/components/Explorer";
import {NavExplorerSearchbar} from "app/components/NavExplorerSearchbar";
import {Redirect, Route, Switch} from 'react-router-dom';
......@@ -53,6 +54,11 @@ export class Root extends React.Component<Props, any> {
Tangle Explorer
</Nav.Link>
</LinkContainer>
<LinkContainer to="/drng">
<Nav.Link>
dRNG Explorer
</Nav.Link>
</LinkContainer>
</Nav>
<Navbar.Collapse className="justify-content-end">
<NavExplorerSearchbar/>
......@@ -70,6 +76,7 @@ export class Root extends React.Component<Props, any> {
<Route exact path="/explorer/addr/:hash" component={ExplorerAddressQueryResult}/>
<Route exact path="/explorer/404/:search" component={Explorer404}/>
<Route exact path="/explorer" component={Explorer}/>
<Route exact path="/drng" component={Drng}/>
<Redirect to="/dashboard"/>
</Switch>
{this.props.children}
......
......@@ -3,6 +3,7 @@ export enum WSMsgType {
TPSMetrics,
Tx,
NeighborStats,
Drng,
}
export interface WSMessage {
......
import {action, computed, observable} from 'mobx';
import {registerHandler, WSMsgType} from "app/misc/WS";
import * as React from "react";
import {Link} from 'react-router-dom';
import {RouterStore} from "mobx-react-router";
export class DrngMessage {
instanceId: number;
round: number;
value: number;
timestamp: number;
}
class Msg {
hash: string;
randomValue: number;
}
const liveFeedSize = 10;
export class DrngStore {
// live feed
@observable latest_msgs: Array<Msg> = [];
// queries
@observable msg: DrngMessage = null;
// loading
@observable query_loading: boolean = false;
@observable query_err: any = null;
routerStore: RouterStore;
constructor(routerStore: RouterStore) {
this.routerStore = routerStore;
registerHandler(WSMsgType.Drng, this.addLiveFeed);
}
@action
addLiveFeed = (msg: Msg) => {
// prevent duplicates (should be fast with only size 10)
if (this.latest_msgs.findIndex((t) => t.hash == msg.hash) === -1) {
if (this.latest_msgs.length >= liveFeedSize) {
this.latest_msgs.shift();
}
this.latest_msgs.push(msg);
}
};
@computed
get msgsLiveFeed() {
let feed = [];
for (let i = this.latest_msgs.length - 1; i >= 0; i--) {
let msg = this.latest_msgs[i];
feed.push(
<tr key={msg.hash}>
<td>
<Link to={`/drng/msg/${msg.hash}`}>
{msg.hash.substr(0, 35)}
</Link>
</td>
<td>
{msg.randomValue}
</td>
</tr>
);
}
return feed;
}
}
export default DrngStore;
\ No newline at end of file
......@@ -8,15 +8,18 @@ import {RouterStore, syncHistoryWithStore} from 'mobx-react-router';
import {Router} from 'react-router-dom';
import NodeStore from "app/stores/NodeStore";
import ExplorerStore from "app/stores/ExplorerStore";
import DrngStore from "app/stores/DrngStore";
// prepare MobX stores
const routerStore = new RouterStore();
const nodeStore = new NodeStore();
const explorerStore = new ExplorerStore(routerStore);
const drngStore = new DrngStore(routerStore);
const stores = {
"routerStore": routerStore,
"nodeStore": nodeStore,
"explorerStore": explorerStore,
"drngStore": drngStore,
};
const browserHistory = createBrowserHistory();
......
......@@ -126,6 +126,7 @@ const (
MsgTypeTPSMetric
MsgTypeTx
MsgTypeNeighborMetric
MsgTypeDrng
)
type msg struct {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment