dispatch `FAIL`

- stops client on failed initialization
- displays failed message
This commit is contained in:
Felicio Mununga 2022-11-27 17:07:58 +01:00
parent d4bec26bcc
commit c925efbaf5
No known key found for this signature in database
GPG Key ID: 0EB8D75C775AB6F1
3 changed files with 95 additions and 43 deletions

View File

@ -87,52 +87,65 @@ class Client {
} }
} }
static async start(options: ClientOptions) { static async start(options: ClientOptions): Promise<Client> {
// Waku
const { environment = 'production' } = options const { environment = 'production' } = options
const waku = await createLightNode({ let waku: WakuLight | undefined
defaultBootstrap: false, let client: Client | undefined
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
emitSelf: true,
pingKeepAlive: 15,
relayKeepAlive: 0,
libp2p: {
peerDiscovery: [
/**
* >only connects to 1 remote node because of the limited number of nodes
* >run by Status and the limited number of connections provided by these nodes
* >
* >@see https://forum.vac.dev/t/waku-v2-scalability-studies/142/2
*/
new PeerDiscoveryStaticPeers(peers[environment], { maxPeers: 1 }),
],
},
})
await waku.start()
await waitForRemotePeer(
waku,
[Protocols.Store, Protocols.Filter, Protocols.LightPush],
10 * 1000
)
const wakuDisconnectionTimer = setInterval(async () => {
const connectionsToClose: Promise<void>[] = []
for (const connection of waku.libp2p.connectionManager.getConnections()) { try {
if (!connection.streams.length) { // Waku
connectionsToClose.push(connection.close()) waku = await createLightNode({
defaultBootstrap: false,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
emitSelf: true,
pingKeepAlive: 15,
relayKeepAlive: 0,
libp2p: {
peerDiscovery: [
/**
* >only connects to 1 remote node because of the limited number of nodes
* >run by Status and the limited number of connections provided by these nodes
* >
* >@see https://forum.vac.dev/t/waku-v2-scalability-studies/142/2
*/
new PeerDiscoveryStaticPeers(peers[environment], { maxPeers: 1 }),
],
},
})
await waku.start()
await waitForRemotePeer(
waku,
[Protocols.Store, Protocols.Filter, Protocols.LightPush],
10 * 1000
)
const wakuDisconnectionTimer = setInterval(async () => {
const connectionsToClose: Promise<void>[] = []
for (const connection of waku!.libp2p.connectionManager.getConnections()) {
if (!connection.streams.length) {
connectionsToClose.push(connection.close())
}
} }
await Promise.allSettled(connectionsToClose)
}, 10 * 1000)
// Client
client = new Client(waku, wakuDisconnectionTimer, options)
// Community
await client.community.start()
} catch (error) {
if (client) {
await client.stop()
} else if (waku) {
await waku.stop()
} }
await Promise.allSettled(connectionsToClose) throw error
}, 10 * 1000) }
// Client
const client = new Client(waku, wakuDisconnectionTimer, options)
// Community
await client.community.start()
return client return client
} }

View File

@ -0,0 +1,22 @@
import React from 'react'
import { Text } from '../../system'
export const Failed = () => {
return (
<Text
size="15"
color="gray"
weight="400"
align="center"
css={{
margin: 'auto',
position: 'relative',
top: '50%',
transform: 'translateY(-50%)',
}}
>
Failed to connect. Try reloading.
</Text>
)
}

View File

@ -2,6 +2,7 @@ import React, { createContext, useEffect, useReducer } from 'react'
import { createClient } from '@status-im/js' import { createClient } from '@status-im/js'
import { Failed } from '../components/failed'
import { Loading } from '../components/loading' import { Loading } from '../components/loading'
import type { Account, Client, ClientOptions, Community } from '@status-im/js' import type { Account, Client, ClientOptions, Community } from '@status-im/js'
@ -10,6 +11,7 @@ export const Context = createContext<State | undefined>(undefined)
export type State = { export type State = {
loading: boolean loading: boolean
failed: boolean
client: Client | undefined client: Client | undefined
community: Community['description'] | undefined community: Community['description'] | undefined
account: Account | undefined account: Account | undefined
@ -20,6 +22,7 @@ export type Action =
| { type: 'INIT'; client: Client } | { type: 'INIT'; client: Client }
| { type: 'UPDATE_COMMUNITY'; community: Community['description'] } | { type: 'UPDATE_COMMUNITY'; community: Community['description'] }
| { type: 'SET_ACCOUNT'; account: Account | undefined } | { type: 'SET_ACCOUNT'; account: Account | undefined }
| { type: 'FAIL' }
interface Props { interface Props {
options: ClientOptions options: ClientOptions
@ -44,6 +47,9 @@ const reducer = (state: State, action: Action): State => {
case 'SET_ACCOUNT': { case 'SET_ACCOUNT': {
return { ...state, account: action.account } return { ...state, account: action.account }
} }
case 'FAIL': {
return { ...state, failed: true, loading: false }
}
} }
} }
@ -56,15 +62,22 @@ export const ProtocolProvider = (props: Props) => {
community: undefined, community: undefined,
account: undefined, account: undefined,
dispatch: undefined, dispatch: undefined,
failed: false,
}) })
const { client, loading } = state const { client, loading, failed } = state
useEffect(() => { useEffect(() => {
const loadClient = async () => { const loadClient = async () => {
const client = await createClient(options) try {
const client = await createClient(options)
dispatch({ type: 'INIT', client }) dispatch({ type: 'INIT', client })
} catch (error) {
console.error(error)
dispatch({ type: 'FAIL' })
}
} }
loadClient() loadClient()
@ -89,6 +102,10 @@ export const ProtocolProvider = (props: Props) => {
} }
}, [client]) }, [client])
if (failed) {
return <Failed />
}
if (loading) { if (loading) {
return <Loading /> return <Loading />
} }