mirror of
https://github.com/trezor/trezor-wallet
synced 2024-12-02 13:18:19 +00:00
auto reconnect to the backend
This commit is contained in:
parent
f8e7320bf2
commit
8d399ff327
@ -1,6 +1,7 @@
|
|||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
import * as BLOCKCHAIN from 'actions/constants/blockchain';
|
import * as BLOCKCHAIN from 'actions/constants/blockchain';
|
||||||
|
import * as DiscoveryActions from 'actions/DiscoveryActions';
|
||||||
import * as EthereumBlockchainActions from 'actions/ethereum/BlockchainActions';
|
import * as EthereumBlockchainActions from 'actions/ethereum/BlockchainActions';
|
||||||
import * as RippleBlockchainActions from 'actions/ripple/BlockchainActions';
|
import * as RippleBlockchainActions from 'actions/ripple/BlockchainActions';
|
||||||
|
|
||||||
@ -19,6 +20,10 @@ export type BlockchainAction =
|
|||||||
| {
|
| {
|
||||||
type: typeof BLOCKCHAIN.START_SUBSCRIBE,
|
type: typeof BLOCKCHAIN.START_SUBSCRIBE,
|
||||||
shortcut: string,
|
shortcut: string,
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: typeof BLOCKCHAIN.FAIL_SUBSCRIBE,
|
||||||
|
shortcut: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Conditionally subscribe to blockchain backend
|
// Conditionally subscribe to blockchain backend
|
||||||
@ -128,6 +133,8 @@ export const onError = (
|
|||||||
const network = config.networks.find(c => c.shortcut === shortcut);
|
const network = config.networks.find(c => c.shortcut === shortcut);
|
||||||
if (!network) return;
|
if (!network) return;
|
||||||
|
|
||||||
|
dispatch(autoReconnect(shortcut));
|
||||||
|
|
||||||
switch (network.type) {
|
switch (network.type) {
|
||||||
case 'ethereum':
|
case 'ethereum':
|
||||||
await dispatch(EthereumBlockchainActions.onError(shortcut));
|
await dispatch(EthereumBlockchainActions.onError(shortcut));
|
||||||
@ -140,3 +147,28 @@ export const onError = (
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const autoReconnect = (shortcut: string): PromiseAction<void> => async (
|
||||||
|
dispatch: Dispatch,
|
||||||
|
getState: GetState
|
||||||
|
): Promise<void> => {
|
||||||
|
const MAX_ATTEMPTS = 4;
|
||||||
|
let blockchain = getState().blockchain.find(b => b.shortcut === shortcut);
|
||||||
|
// try to automatically reconnect and wait after each attemp (5s * #attempt) untill max number of attemps is reached
|
||||||
|
for (let i = 0; i < MAX_ATTEMPTS; i++) {
|
||||||
|
const waitTime = 5000 * (i + 1); /// 5s * #attempt
|
||||||
|
if (!blockchain || blockchain.connected) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockchain = getState().blockchain.find(b => b.shortcut === shortcut);
|
||||||
|
|
||||||
|
// reconnect with 7s timeout
|
||||||
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
await dispatch(DiscoveryActions.reconnect(shortcut, 7000));
|
||||||
|
|
||||||
|
// wait before next try
|
||||||
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
await new Promise(resolve => setTimeout(resolve, waitTime));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
import TrezorConnect, { UI } from 'trezor-connect';
|
import TrezorConnect, { UI } from 'trezor-connect';
|
||||||
|
import * as BLOCKCHAIN_ACTION from 'actions/constants/blockchain';
|
||||||
import * as DISCOVERY from 'actions/constants/discovery';
|
import * as DISCOVERY from 'actions/constants/discovery';
|
||||||
import * as ACCOUNT from 'actions/constants/account';
|
import * as ACCOUNT from 'actions/constants/account';
|
||||||
import * as NOTIFICATION from 'actions/constants/notification';
|
import * as NOTIFICATION from 'actions/constants/notification';
|
||||||
@ -325,11 +326,27 @@ const finish = (device: TrezorDevice, discoveryProcess: Discovery): AsyncAction
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const reconnect = (network: string): PromiseAction<void> => async (
|
export const reconnect = (network: string, timeout: number = 30): PromiseAction<void> => async (
|
||||||
dispatch: Dispatch
|
dispatch: Dispatch
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
await dispatch(BlockchainActions.subscribe(network));
|
// Runs two promises.
|
||||||
|
// First promise is a subscribe action which will never resolve in case of completely lost connection to the backend
|
||||||
|
// That's why there is a second promise that rejects after the specified timeout.
|
||||||
|
return Promise.race([
|
||||||
|
dispatch(BlockchainActions.subscribe(network)),
|
||||||
|
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout)),
|
||||||
|
])
|
||||||
|
.catch(() => {
|
||||||
|
// catch error from first promises that rejects (most likely timeout)
|
||||||
|
dispatch({
|
||||||
|
type: BLOCKCHAIN_ACTION.FAIL_SUBSCRIBE,
|
||||||
|
shortcut: network,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
// dispatch restore when subscribe promise resolves
|
||||||
dispatch(restore());
|
dispatch(restore());
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Called after DEVICE.CONNECT ('trezor-connect') or CONNECT.AUTH_DEVICE actions in WalletService
|
// Called after DEVICE.CONNECT ('trezor-connect') or CONNECT.AUTH_DEVICE actions in WalletService
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
export const START_SUBSCRIBE: 'blockchain__start_subscribe' = 'blockchain__start_subscribe';
|
export const START_SUBSCRIBE: 'blockchain__start_subscribe' = 'blockchain__start_subscribe';
|
||||||
|
export const FAIL_SUBSCRIBE: 'blockchain__fail_subscribe' = 'blockchain__fail_subscribe';
|
||||||
export const READY: 'blockchain__ready' = 'blockchain__ready';
|
export const READY: 'blockchain__ready' = 'blockchain__ready';
|
||||||
export const UPDATE_FEE: 'blockchain__update_fee' = 'blockchain__update_fee';
|
export const UPDATE_FEE: 'blockchain__update_fee' = 'blockchain__update_fee';
|
||||||
|
@ -48,6 +48,30 @@ const onStartSubscribe = (state: State, shortcut: string): State => {
|
|||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onFailSubscribe = (state: State, shortcut: string): State => {
|
||||||
|
const network = state.find(b => b.shortcut === shortcut);
|
||||||
|
if (network) {
|
||||||
|
const others = state.filter(b => b !== network);
|
||||||
|
return others.concat([
|
||||||
|
{
|
||||||
|
...network,
|
||||||
|
connecting: false,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return state.concat([
|
||||||
|
{
|
||||||
|
shortcut,
|
||||||
|
connected: false,
|
||||||
|
connecting: false,
|
||||||
|
block: 0,
|
||||||
|
feeTimestamp: 0,
|
||||||
|
feeLevels: [],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
const onConnect = (state: State, action: BlockchainConnect): State => {
|
const onConnect = (state: State, action: BlockchainConnect): State => {
|
||||||
const shortcut = action.payload.coin.shortcut.toLowerCase();
|
const shortcut = action.payload.coin.shortcut.toLowerCase();
|
||||||
const network = state.find(b => b.shortcut === shortcut);
|
const network = state.find(b => b.shortcut === shortcut);
|
||||||
@ -136,6 +160,8 @@ export default (state: State = initialState, action: Action): State => {
|
|||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case BLOCKCHAIN_ACTION.START_SUBSCRIBE:
|
case BLOCKCHAIN_ACTION.START_SUBSCRIBE:
|
||||||
return onStartSubscribe(state, action.shortcut);
|
return onStartSubscribe(state, action.shortcut);
|
||||||
|
case BLOCKCHAIN_ACTION.FAIL_SUBSCRIBE:
|
||||||
|
return onFailSubscribe(state, action.shortcut);
|
||||||
case BLOCKCHAIN_EVENT.CONNECT:
|
case BLOCKCHAIN_EVENT.CONNECT:
|
||||||
return onConnect(state, action);
|
return onConnect(state, action);
|
||||||
case BLOCKCHAIN_EVENT.ERROR:
|
case BLOCKCHAIN_EVENT.ERROR:
|
||||||
|
Loading…
Reference in New Issue
Block a user