Pub sub blocks (#6139)

* fun start

* playin

* linting

* cleanup kk 1

* cleanup kk 2

* package

* oops

* grumbles

* lint

* lint 2

* all-possible-cases

* conflict resolution

* conflict resolution

* ready

* lint

* remove package-lock

* Restart subscription on transport close.

* Bring back the formatter.

* Fix formatter.
This commit is contained in:
Craig O'Connor 2017-09-01 06:23:41 -04:00 committed by Tomasz Drwięga
parent 47f7366a5c
commit 56f46edab8
6 changed files with 92 additions and 144 deletions

View File

@ -155,7 +155,6 @@ impl HardwareWalletManager {
self.ledger.lock().set_key_path(key_path); self.ledger.lock().set_key_path(key_path);
} }
/// List connected wallets. This only returns wallets that are ready to be used. /// List connected wallets. This only returns wallets that are ready to be used.
pub fn list_wallets(&self) -> Vec<WalletInfo> { pub fn list_wallets(&self) -> Vec<WalletInfo> {
self.ledger.lock().list_devices() self.ledger.lock().list_devices()

4
js/package-lock.json generated
View File

@ -7722,7 +7722,7 @@
"minimatch": { "minimatch": {
"version": "3.0.4", "version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"requires": { "requires": {
"brace-expansion": "1.1.8" "brace-expansion": "1.1.8"
} }
@ -10081,7 +10081,7 @@
"react-qr-reader": { "react-qr-reader": {
"version": "1.1.3", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/react-qr-reader/-/react-qr-reader-1.1.3.tgz", "resolved": "https://registry.npmjs.org/react-qr-reader/-/react-qr-reader-1.1.3.tgz",
"integrity": "sha1-dDmnZvyZPLj17u/HLCnblh1AswI=", "integrity": "sha512-ruBF8KaSwUW9nbzjO4rA7/HOCGYZuNUz9od7uBRy8SRBi24nwxWWmwa2z8R6vPGDRglA0y2Qk1aVBuC1olTnHw==",
"requires": { "requires": {
"jsqr": "git+https://github.com/JodusNodus/jsQR.git#5ba1acefa1cbb9b2bc92b49f503f2674e2ec212b", "jsqr": "git+https://github.com/JodusNodus/jsQR.git#5ba1acefa1cbb9b2bc92b49f503f2674e2ec212b",
"prop-types": "15.5.10", "prop-types": "15.5.10",

View File

@ -183,16 +183,17 @@ export default class Parity extends PubsubBase {
localTransactions (callback) { localTransactions (callback) {
return this.addListener(this._api, 'parity_localTransactions', (error, transactions) => { return this.addListener(this._api, 'parity_localTransactions', (error, transactions) => {
error if (error) {
? callback(error) return callback(error);
: callback(null, transactions => { }
Object.values(transactions) Object.values(transactions)
.filter(tx => tx.transaction) .filter(tx => tx.transaction)
.map(tx => { .map(tx => {
tx.transaction = outTransaction(tx.transaction); tx.transaction = outTransaction(tx.transaction);
}); });
return transactions;
}); callback(null, transactions);
}); });
} }

View File

@ -25,11 +25,13 @@ export default class SignerStore {
constructor (api, withLocalTransactions = false, externalLink = '') { constructor (api, withLocalTransactions = false, externalLink = '') {
this._api = api; this._api = api;
this._timeoutId = 0;
this.externalLink = externalLink; this.externalLink = externalLink;
if (withLocalTransactions) { if (withLocalTransactions) {
this.fetchLocalTransactions(); this._api.transport.on('close', () => {
this.subscribeLocalTransactions();
});
this.subscribeLocalTransactions();
} }
} }
@ -49,9 +51,7 @@ export default class SignerStore {
} }
@action unsubscribe () { @action unsubscribe () {
if (this._timeoutId) { this.subscription.then(id => this._api.pubsub.unsubscribe([id]));
clearTimeout(this._timeoutId);
}
} }
fetchBalance (address) { fetchBalance (address) {
@ -87,21 +87,17 @@ export default class SignerStore {
}); });
} }
fetchLocalTransactions = () => { subscribeLocalTransactions = () => {
const nextTimeout = () => { this.subscription = this._api.pubsub.parity.localTransactions((error, transactions) => {
this._timeoutId = setTimeout(this.fetchLocalTransactions, 1500); if (error) {
}; console.warn('subscribeLocalTransactions', error);
return;
this._api.parity }
.localTransactions()
.then((localTransactions) => {
const keys = Object const keys = Object
.keys(localTransactions) .keys(transactions)
.filter((key) => localTransactions[key].status !== 'canceled'); .filter((key) => transactions[key].status !== 'canceled');
this.setLocalHashes(keys); this.setLocalHashes(keys);
}) });
.then(() => nextTimeout())
.catch(() => nextTimeout());
} }
} }

View File

@ -18,7 +18,7 @@ import bytes from 'bytes';
import moment from 'moment'; import moment from 'moment';
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux'; import { observer } from 'mobx-react';
import { Container, ContainerTitle, Input } from '~/ui'; import { Container, ContainerTitle, Input } from '~/ui';
@ -27,18 +27,12 @@ import StatusStore from './store';
import styles from './nodeStatus.css'; import styles from './nodeStatus.css';
@observer
class NodeStatus extends Component { class NodeStatus extends Component {
static contextTypes = { static contextTypes = {
api: PropTypes.object.isRequired api: PropTypes.object.isRequired
}; };
static propTypes = {
blockNumber: PropTypes.object,
blockTimestamp: PropTypes.object,
netChain: PropTypes.string,
netPeers: PropTypes.object
};
statusStore = new StatusStore(this.context.api); statusStore = new StatusStore(this.context.api);
componentWillMount () { componentWillMount () {
@ -50,8 +44,7 @@ class NodeStatus extends Component {
} }
render () { render () {
const { blockNumber, blockTimestamp, netPeers } = this.props; const { blockNumber, blockTimestamp, netPeers, hashrate } = this.statusStore;
const { hashrate } = this.statusStore;
if (!netPeers || !blockNumber) { if (!netPeers || !blockNumber) {
return null; return null;
@ -157,8 +150,7 @@ class NodeStatus extends Component {
} }
renderSettings () { renderSettings () {
const { netChain } = this.props; const { chain, enode, rpcSettings, netPort = '' } = this.statusStore;
const { enode, rpcSettings, netPort = '' } = this.statusStore;
if (!rpcSettings) { if (!rpcSettings) {
return null; return null;
@ -185,7 +177,7 @@ class NodeStatus extends Component {
defaultMessage='chain' defaultMessage='chain'
/> />
} }
value={ netChain } value={ chain }
/> />
<div className={ styles.row }> <div className={ styles.row }>
<div className={ styles.col6 }> <div className={ styles.col6 }>
@ -279,23 +271,4 @@ class NodeStatus extends Component {
} }
} }
function mapStateToProps (state) { export default NodeStatus;
const {
blockNumber,
blockTimestamp,
netChain,
netPeers
} = state.nodeStatus;
return {
blockNumber,
blockTimestamp,
netChain,
netPeers
};
}
export default connect(
mapStateToProps,
null
)(NodeStatus);

View File

@ -15,11 +15,15 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import { action, observable, transaction } from 'mobx'; import { action, observable } from 'mobx';
export default class StatusStore { export default class StatusStore {
@observable defaultExtraData = ''; @observable defaultExtraData = '';
@observable enode = ''; @observable enode = '';
@observable blockNumber = new BigNumber(0);
@observable blockTimestamp = new Date();
@observable chain = '';
@observable netPeers = new BigNumber(0);
@observable hashrate = new BigNumber(0); @observable hashrate = new BigNumber(0);
@observable netPort = new BigNumber(0); @observable netPort = new BigNumber(0);
@observable nodeName = ''; @observable nodeName = '';
@ -35,39 +39,68 @@ export default class StatusStore {
constructor (api) { constructor (api) {
this.api = api; this.api = api;
this.api.transport.on('close', () => {
if (this.isPolling) {
this.startPolling();
}
});
} }
@action setLongStatus ({ defaultExtraData, enode, netPort, rpcSettings }) { @action setStatuses ({ chain, defaultExtraData, enode, netPeers, netPort, rpcSettings, hashrate }) {
transaction(() => { this.chain = chain;
this.defaultExtraData = defaultExtraData; this.defaultExtraData = defaultExtraData;
this.enode = enode; this.enode = enode;
this.netPeers = netPeers;
this.netPort = netPort; this.netPort = netPort;
this.rpcSettings = rpcSettings; this.rpcSettings = rpcSettings;
});
}
@action setStatus ({ hashrate }) {
transaction(() => {
this.hashrate = hashrate; this.hashrate = hashrate;
});
} }
@action setMinerSettings ({ coinbase, extraData, gasFloorTarget, minGasPrice }) { @action setMinerSettings ({ coinbase, extraData, gasFloorTarget, minGasPrice }) {
transaction(() => {
this.coinbase = coinbase; this.coinbase = coinbase;
this.extraData = extraData; this.extraData = extraData;
this.gasFloorTarget = gasFloorTarget; this.gasFloorTarget = gasFloorTarget;
this.minGasPrice = minGasPrice; this.minGasPrice = minGasPrice;
});
}
startPolling () {
this._pollStatus();
this._pollLongStatus();
} }
stopPolling () { stopPolling () {
Object.keys(this._timeoutIds).forEach((key) => clearTimeout(this._timeoutIds[key])); this.isPolling = false;
this.subscription.then(id => this.api.pubsub.unsubscribe([id]));
}
startPolling () {
this.isPolling = true;
this.subscription = this.api.pubsub.parity.getBlockHeaderByNumber((error, block) => {
if (error) {
console.warn('_startPolling', error);
return;
}
this.subscribed = true;
this.blockNumber = block.number;
this.blockTimestamp = block.timestamp;
this._pollMinerSettings();
Promise
.all([
this.api.parity.chain(),
this.api.parity.defaultExtraData(),
this.api.parity.enode().then((enode) => enode).catch(() => '-'),
this.api.parity.netPeers(),
this.api.parity.netPort(),
this.api.parity.rpcSettings(),
this.api.eth.hashrate()
])
.then(([
chain, defaultExtraData, enode, netPeers, netPort, rpcSettings, hashrate
]) => {
this.setStatuses({
chain, defaultExtraData, enode, netPeers, netPort, rpcSettings, hashrate
});
})
.catch((error) => {
console.error('_pollStatuses', error);
return;
});
});
} }
/** /**
@ -100,60 +133,6 @@ export default class StatusStore {
}); });
} }
_pollStatus () {
const nextTimeout = (timeout = 1000) => {
clearTimeout(this._timeoutIds.short);
this._timeoutIds.short = setTimeout(() => this._pollStatus(), timeout);
};
return Promise
.all([
this.api.eth.hashrate()
])
.then(([
hashrate
]) => {
this.setStatus({
hashrate
});
})
.catch((error) => {
console.error('_pollStatus', error);
})
.then(() => {
nextTimeout();
});
}
_pollLongStatus () {
const nextTimeout = (timeout = 30000) => {
clearTimeout(this._timeoutIds.long);
this._timeoutIds.long = setTimeout(() => this._pollLongStatus(), timeout);
};
this._pollMinerSettings();
return Promise
.all([
this.api.parity.defaultExtraData(),
this.api.parity.enode().then((enode) => enode).catch(() => '-'),
this.api.parity.netPort(),
this.api.parity.rpcSettings()
])
.then(([
defaultExtraData, enode, netPort, rpcSettings
]) => {
this.setLongStatus({
defaultExtraData, enode, netPort, rpcSettings
});
})
.catch((error) => {
console.error('_pollLongStatus', error);
})
.then(() => {
nextTimeout();
});
}
handleUpdateSetting = () => { handleUpdateSetting = () => {
return this._pollMinerSettings(); return this._pollMinerSettings();
}; };