Skip to content

Commit

Permalink
Fix: Connections number (#2861)
Browse files Browse the repository at this point in the history
  • Loading branch information
tuul-wq authored Dec 13, 2024
1 parent 0209088 commit fa611de
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 64 deletions.
2 changes: 2 additions & 0 deletions src/renderer/entities/network/lib/network-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@ export const networkUtils = {
function isConnectedStatus(status: ConnectionStatus): boolean {
return status === ConnectionStatus.CONNECTED;
}

function isDisconnectedStatus(status: ConnectionStatus): boolean {
return status === ConnectionStatus.DISCONNECTED;
}

function isConnectingStatus(status: ConnectionStatus): boolean {
return status === ConnectionStatus.CONNECTING;
}

function isErrorStatus(status: ConnectionStatus): boolean {
return status === ConnectionStatus.ERROR;
}
Expand Down
84 changes: 48 additions & 36 deletions src/renderer/entities/network/model/network-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
type Metadata,
type NoID,
} from '@/shared/core';
import { series } from '@/shared/effector';
import { dictionary, nonNullable } from '@/shared/lib/utils';
import { networkUtils } from '../lib/network-utils';

Expand Down Expand Up @@ -58,11 +59,7 @@ const populateConnectionsFx = createEffect((): Promise<Connection[]> => {
});

const getDefaultStatusesFx = createEffect((chains: Record<ChainId, Chain>): Record<ChainId, ConnectionStatus> => {
return Object.values(chains).reduce<Record<ChainId, ConnectionStatus>>((acc, chain) => {
acc[chain.chainId] = ConnectionStatus.DISCONNECTED;

return acc;
}, {});
return dictionary(Object.values(chains), 'chainId', () => ConnectionStatus.DISCONNECTED);
});

type MetadataSubResult = {
Expand Down Expand Up @@ -99,12 +96,6 @@ const updateProviderMetadataFx = createEffect(({ provider, metadata }: ProviderM
provider.updateMetadata(metadata);
});

const initConnectionsFx = createEffect((chains: Record<ChainId, Chain>) => {
for (const chainId of Object.keys(chains)) {
chainConnected(chainId as ChainId);
}
});

type CreateProviderParams = {
chainId: ChainId;
nodes: string[];
Expand Down Expand Up @@ -163,10 +154,6 @@ const createProviderFx = createEffect(
},
);

const disconnectProviderFx = createEffect((provider: ProviderWithMetadata): Promise<void> => {
return provider.disconnect();
});

type CreateApiParams = {
chainId: ChainId;
providers: Record<ChainId, ProviderWithMetadata>;
Expand All @@ -183,9 +170,15 @@ const createApiFx = createEffect(async ({ chainId, providers, apis }: CreateApiP
return networkService.createApi(chainId, providers[chainId]);
});

const disconnectApiFx = createEffect(async (api: ApiPromise): Promise<ChainId> => {
type DisconnectParams = {
api: ApiPromise;
provider: ProviderWithMetadata;
};
const disconnectConnectionFx = createEffect(async ({ api, provider }: DisconnectParams): Promise<ChainId> => {
const chainId = api.genesisHash.toHex();

await api.disconnect();
await provider.disconnect();

return chainId;
});
Expand Down Expand Up @@ -236,7 +229,10 @@ sample({
sample({
clock: populateConnectionsFx.doneData,
source: $chains,
target: initConnectionsFx,
fn: (chains) => {
return Object.keys(chains).map((chainId) => chainId as ChainId);
},
target: series(chainConnected),
});

sample({
Expand Down Expand Up @@ -350,19 +346,20 @@ sample({
}),
});

sample({
clock: [disconnected, failed],
source: $apis,
fn: (apis, chainId) => apis[chainId],
target: disconnectApiFx,
});

sample({
clock: chainDisconnected,
source: $providers,
filter: (providers, chainId) => Boolean(providers[chainId]),
fn: (providers, chainId) => providers[chainId],
target: disconnectProviderFx,
source: {
apis: $apis,
providers: $providers,
},
filter: ({ apis, providers }, chainId) => {
return nonNullable(apis[chainId]) && nonNullable(providers[chainId]);
},
fn: ({ apis, providers }, chainId) => ({
api: apis[chainId],
provider: providers[chainId],
}),
target: disconnectConnectionFx,
});

// =====================================================
Expand All @@ -385,21 +382,36 @@ sample({
});

sample({
clock: disconnectApiFx.doneData,
clock: disconnectConnectionFx.doneData,
source: $metadataSubscriptions,
fn: (metadataSubscriptions, chainId) => metadataSubscriptions[chainId],
filter: (subscriptions, chainId) => nonNullable(subscriptions[chainId]),
fn: (subscriptions, chainId) => subscriptions[chainId],
target: unsubscribeMetadataFx,
});

sample({
clock: disconnectApiFx.doneData,
source: $metadataSubscriptions,
fn: (subscriptions, chainId) => {
const { [chainId]: _, ...rest } = subscriptions;
clock: disconnectConnectionFx.doneData,
source: {
apis: $apis,
providers: $providers,
subscriptions: $metadataSubscriptions,
},
fn: ({ apis, providers, subscriptions }, chainId) => {
const { [chainId]: _a, ...restApis } = apis;
const { [chainId]: _p, ...restProviders } = providers;
const { [chainId]: _s, ...restMetadataSubs } = subscriptions;

return rest;
return {
newApis: restApis,
newProviders: restProviders,
newMetadataSubs: restMetadataSubs,
};
},
target: $metadataSubscriptions,
target: spread({
newApis: $apis,
newProviders: $providers,
newMetadataSubs: $metadataSubscriptions,
}),
});

sample({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,18 @@ function getExtendedChain(
}

type Metrics = Record<'success' | 'connecting' | 'error', number>;

function getStatusMetrics(networkList: ExtendedChain[]): Metrics {
return networkList.reduce(
(acc, network) => {
if (networkUtils.isDisabledConnection(network.connection)) return acc;
const metrics = { connecting: 0, success: 0, error: 0 };

for (const network of networkList) {
if (networkUtils.isDisabledConnection(network.connection)) continue;

if (networkUtils.isConnectedStatus(network.connectionStatus)) acc.success += 1;
if (networkUtils.isConnectingStatus(network.connectionStatus)) acc.connecting += 1;
if (networkUtils.isErrorStatus(network.connectionStatus)) acc.error += 1;
if (networkUtils.isConnectedStatus(network.connectionStatus)) metrics.success += 1;
if (networkUtils.isConnectingStatus(network.connectionStatus)) metrics.connecting += 1;
if (networkUtils.isDisconnectedStatus(network.connectionStatus)) metrics.connecting += 1;
if (networkUtils.isErrorStatus(network.connectionStatus)) metrics.error += 1;
}

return acc;
},
{ success: 0, connecting: 0, error: 0 },
);
return metrics;
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ sample({
return reconnectMap[chainId] ? { disconnect: chainId } : { connect: chainId };
},
target: spread({
connect: networkModel.events.chainConnected,
disconnect: networkModel.events.chainDisconnected,
connect: networkModel.events.chainConnected,
}),
});

Expand Down
25 changes: 8 additions & 17 deletions src/renderer/shared/effector/helpers/series.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { type Effect, type EventCallable, createEvent, createStore, sample } from 'effector';

import { nonNullable, nullable } from '@/shared/lib/utils';
import { type Effect, type EventCallable, createEffect, createEvent, sample } from 'effector';

/**
* Triggers target unit on each element of the input list.
Expand All @@ -20,24 +18,17 @@ import { nonNullable, nullable } from '@/shared/lib/utils';
* ```
*/
export const series = <T>(target: EventCallable<T> | Effect<T, any>) => {
const pop = createEvent();
const push = createEvent<Iterable<T> | ArrayLike<T>>();

const $queue = createStore<T[]>([])
.on(push, (state, payload) => state.concat(Array.isArray(payload) ? payload : Array.from(payload)))
.on(pop, ([, ...rest]) => rest);
const $head = $queue.map((queue) => {
const value = queue.at(0);
if (nullable(value)) return null;
const push = createEvent<Iterable<T>>();

return { value };
const callFx = createEffect((data: Iterable<T>) => {
for (const value of data) {
target(value);
}
});
const nextHeadRetrieved = $head.updates.filter({ fn: nonNullable });

sample({
clock: nextHeadRetrieved,
fn: ({ value }) => value,
target: [target, pop],
clock: push,
target: callFx,
});

return push;
Expand Down

0 comments on commit fa611de

Please sign in to comment.