Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
Fix Secure API hangs (#3927)
Browse files Browse the repository at this point in the history
* Use proxy for WS in dev

* Update SecureAPI

* Update webpack config

* Fix dev contract

* Update webpack

* Linting fixes

* Refactor Secure API logic : Promise based, no wastes of req

* Fix tests

* Add try 'intitial' token
  • Loading branch information
ngotchac authored and gavofyork committed Dec 21, 2016
1 parent a9f89b0 commit aba3872
Show file tree
Hide file tree
Showing 15 changed files with 216 additions and 183 deletions.
3 changes: 2 additions & 1 deletion js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
"react-hot-loader": "3.0.0-beta.6",
"react-intl-aggregate-webpack-plugin": "0.0.1",
"rucksack-css": "0.9.1",
"script-ext-html-webpack-plugin": "1.3.4",
"serviceworker-webpack-plugin": "0.1.7",
"sinon": "1.17.6",
"sinon-as-promised": "4.0.2",
Expand All @@ -125,7 +126,7 @@
"stylelint": "7.6.0",
"stylelint-config-standard": "15.0.0",
"url-loader": "0.5.7",
"webpack": "2.1.0-beta.27",
"webpack": "2.2.0-rc.1",
"webpack-dev-middleware": "1.8.4",
"webpack-error-notification": "0.1.6",
"webpack-hot-middleware": "2.13.2",
Expand Down
61 changes: 49 additions & 12 deletions js/src/api/transport/ws/ws.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import TransportError from '../error';

/* global WebSocket */
export default class Ws extends JsonRpcBase {
constructor (url, token) {
constructor (url, token, connect = true) {
super();

this._url = url;
Expand All @@ -32,23 +32,34 @@ export default class Ws extends JsonRpcBase {
this._connecting = false;
this._connected = false;
this._lastError = null;
this._autoConnect = true;
this._autoConnect = false;
this._retries = 0;
this._reconnectTimeoutId = null;

this._connect();
this._connectPromise = null;
this._connectPromiseFunctions = {};

if (connect) {
this.connect();
}
}

updateToken (token) {
updateToken (token, connect = true) {
this._token = token;
this._autoConnect = true;
// this._autoConnect = true;

this._connect();
if (connect) {
this.connect();
}
}

_connect () {
connect () {
if (this._connected) {
return Promise.resolve();
}

if (this._connecting) {
return;
return this._connectPromise || Promise.resolve();
}

if (this._reconnectTimeoutId) {
Expand Down Expand Up @@ -104,10 +115,17 @@ export default class Ws extends JsonRpcBase {

window._parityWS = this;
}

this._connectPromise = new Promise((resolve, reject) => {
this._connectPromiseFunctions = { resolve, reject };
});

return this._connectPromise;
}

_onOpen = (event) => {
console.log('ws:onOpen', event);
console.log('ws:onOpen');

this._connected = true;
this._connecting = false;
this._autoConnect = true;
Expand All @@ -116,6 +134,11 @@ export default class Ws extends JsonRpcBase {
Object.keys(this._messages)
.filter((id) => this._messages[id].queued)
.forEach(this._send);

this._connectPromiseFunctions.resolve();

this._connectPromise = null;
this._connectPromiseFunctions = {};
}

_onClose = (event) => {
Expand All @@ -135,24 +158,38 @@ export default class Ws extends JsonRpcBase {
console.log('ws:onClose', `trying again in ${time}...`);

this._reconnectTimeoutId = setTimeout(() => {
this._connect();
this.connect();
}, timeout);

return;
}

console.log('ws:onClose', event);
if (this._connectPromise) {
this._connectPromiseFunctions.reject(event);

this._connectPromise = null;
this._connectPromiseFunctions = {};
}

console.log('ws:onClose');
}

_onError = (event) => {
// Only print error if the WS is connected
// ie. don't print if error == closed
window.setTimeout(() => {
if (this._connected) {
console.error('ws:onError', event);
console.error('ws:onError');

event.timestamp = Date.now();
this._lastError = event;

if (this._connectPromise) {
this._connectPromiseFunctions.reject(event);

this._connectPromise = null;
this._connectPromiseFunctions = {};
}
}
}, 50);
}
Expand Down
7 changes: 1 addition & 6 deletions js/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,7 @@ if (process.env.NODE_ENV === 'development') {
}

const AUTH_HASH = '#/auth?';
const parityUrl = process.env.PARITY_URL ||
(
process.env.NODE_ENV === 'production'
? window.location.host
: '127.0.0.1:8180'
);
const parityUrl = process.env.PARITY_URL || window.location.host;

let token = null;
if (window.location.hash && window.location.hash.indexOf(AUTH_HASH) === 0) {
Expand Down
55 changes: 0 additions & 55 deletions js/src/redux/providers/status.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,18 @@ export default class Status {
this._api = api;
this._store = store;

this._pingable = false;
this._apiStatus = {};
this._status = {};
this._longStatus = {};
this._minerSettings = {};

this._pollPingTimeoutId = null;
this._longStatusTimeoutId = null;

this._timestamp = Date.now();
}

start () {
this._subscribeBlockNumber();
this._pollPing();
this._pollStatus();
this._pollLongStatus();
this._pollLogs();
Expand Down Expand Up @@ -65,50 +62,6 @@ export default class Status {
});
}

/**
* Pinging should be smart. It should only
* be used when the UI is connecting or the
* Node is deconnected.
*
* @see src/views/Connection/connection.js
*/
_shouldPing = () => {
const { isConnected } = this._apiStatus;
return !isConnected;
}

_stopPollPing = () => {
if (!this._pollPingTimeoutId) {
return;
}

clearTimeout(this._pollPingTimeoutId);
this._pollPingTimeoutId = null;
}

_pollPing = () => {
// Already pinging, don't try again
if (this._pollPingTimeoutId) {
return;
}

const dispatch = (pingable, timeout = 1000) => {
if (pingable !== this._pingable) {
this._pingable = pingable;
this._store.dispatch(statusCollection({ isPingable: pingable }));
}

this._pollPingTimeoutId = setTimeout(() => {
this._stopPollPing();
this._pollPing();
}, timeout);
};

fetch('/', { method: 'HEAD' })
.then((response) => dispatch(!!response.ok))
.catch(() => dispatch(false));
}

_pollTraceMode = () => {
return this._api.trace.block()
.then(blockTraces => {
Expand Down Expand Up @@ -137,21 +90,13 @@ export default class Status {

if (gotConnected) {
this._pollLongStatus();
this._store.dispatch(statusCollection({ isPingable: true }));
}

if (!isEqual(apiStatus, this._apiStatus)) {
this._store.dispatch(statusCollection(apiStatus));
this._apiStatus = apiStatus;
}

// Ping if necessary, otherwise stop pinging
if (this._shouldPing()) {
this._pollPing();
} else {
this._stopPollPing();
}

if (!isConnected) {
return nextTimeout(250);
}
Expand Down
1 change: 0 additions & 1 deletion js/src/redux/providers/statusReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ const initialState = {
syncing: true,
isConnected: false,
isConnecting: false,
isPingable: false,
isTest: undefined,
refreshStatus: false,
traceMode: undefined
Expand Down
Loading

0 comments on commit aba3872

Please sign in to comment.