Skip to content
This repository has been archived by the owner on Mar 23, 2023. It is now read-only.

feat: sync wallet data #2748

Merged
merged 29 commits into from
Sep 1, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
e8da4ca
feat: add scheduler service
clucasalcantara Aug 28, 2020
327e7ba
fix: fix types
clucasalcantara Aug 28, 2020
20f0f60
feat: apply sync on initialize, run scheduler
clucasalcantara Aug 28, 2020
b3218ba
refactor: remove other calls for sync due to initialization and sched…
clucasalcantara Aug 28, 2020
abd0752
wip
Aug 29, 2020
8c0b863
style: resolve style guide violations
faustbrian Aug 29, 2020
6dcd373
Merge branch '3.0-react' into feat/sync-wallet-data
Aug 29, 2020
1fefb17
Merge branch '3.0-react' into feat/sync-wallet-data
faustbrian Aug 29, 2020
a6b54b5
Merge branch '3.0-react' into feat/sync-wallet-data
clucasalcantara Aug 30, 2020
b689f53
Merge branch '3.0-react' into feat/sync-wallet-data
faustbrian Aug 31, 2020
eba6f19
chore: add nock for crypto compare
clucasalcantara Aug 31, 2020
67be21b
Merge branch '3.0-react' into feat/sync-wallet-data
faustbrian Aug 31, 2020
841d20a
Merge branch '3.0-react' into feat/sync-wallet-data
Aug 31, 2020
3e5156b
wip
Aug 31, 2020
275679c
tests: update snapshots
clucasalcantara Aug 31, 2020
1f8b02c
tests: wip fix address tests
clucasalcantara Aug 31, 2020
7ccf4cb
fix: duplicatated import
clucasalcantara Aug 31, 2020
b26407b
tests: update snapshots
clucasalcantara Sep 1, 2020
e42e893
Merge branch '3.0-react' into feat/sync-wallet-data
Sep 1, 2020
ffcfcba
wip
Sep 1, 2020
2d1afa0
style: resolve style guide violations
faustbrian Sep 1, 2020
6d344ef
Merge branch '3.0-react' into feat/sync-wallet-data
faustbrian Sep 1, 2020
0e1ee21
tests: ignore temp console error in tests
clucasalcantara Sep 1, 2020
103799a
tests: update tests and increse coverage
clucasalcantara Sep 1, 2020
607e189
feat: add echange ratwes sync
clucasalcantara Sep 1, 2020
51feaad
chore: use promise all settled
clucasalcantara Sep 1, 2020
289527c
chore: rename sync function for wallets data
clucasalcantara Sep 1, 2020
5a74b10
wip
Sep 1, 2020
0756d25
Merge branch '3.0-react' into feat/sync-wallet-data
Sep 1, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 30 additions & 10 deletions src/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { middlewares, RouterView, routes } from "../router";
import { EnvironmentProvider, useEnvironmentContext } from "./contexts";
import { useNetworkStatus } from "./hooks";
import { i18n } from "./i18n";
import { httpClient } from "./services";
import { httpClient, Scheduler } from "./services";

const __DEV__ = process.env.NODE_ENV !== "production";

Expand All @@ -44,7 +44,7 @@ const Main = ({ syncInterval }: Props) => {
}, [pathname]);

useLayoutEffect(() => {
const syncDelegates = () => {
const syncDelegates = async () => {
console.log("Running delegates sync...");
const coinsData = env.usedCoinsWithNetworks();
const coinsInUse = Object.keys(coinsData);
Expand All @@ -57,20 +57,36 @@ const Main = ({ syncInterval }: Props) => {
}
}

Promise.allSettled(delegatesPromises).then(() => {
setShowSplash(false);
});
await Promise.allSettled(delegatesPromises);
};

const syncWallets = async () => {
console.log("Running wallet data sync...");
const profiles = env.profiles().values();

for (const profile of profiles) {
const [wallet] = profile.wallets().values();
clucasalcantara marked this conversation as resolved.
Show resolved Hide resolved
try {
await wallet?.syncVotes();
await wallet?.syncIdentity();
await wallet?.syncExchangeRate();

setShowSplash(false);
} catch (error) {
console.error(`Error synchronizing wallet data ${error}`);
setShowSplash(false);
}
}
};

const boot = async () => {
await env.verify(fixtureData);
syncDelegates();

console.info("Scheduling next delegates synchronization...");
setInterval(() => syncDelegates(), syncInterval);

await syncDelegates();
await env.boot();
await syncWallets();
await persist();

Scheduler(syncInterval).schedule([syncDelegates, syncWallets], persist);
};

if (process.env.REACT_APP_BUILD_MODE === "demo") {
Expand Down Expand Up @@ -138,3 +154,7 @@ export const App = ({ syncInterval }: Props) => {
</ErrorBoundary>
);
};

App.defaultProps = {
syncInterval: 300000,
};
29 changes: 29 additions & 0 deletions src/app/services/Scheduler.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Scheduler } from "./Scheduler";

describe("Scheduler test", () => {
jest.useFakeTimers();

it("should run an action after an determined interval", () => {
const action = jest.fn();
Scheduler(100).schedule([action]);
jest.advanceTimersByTime(100);
expect(action).toHaveBeenCalled();
});

it("should run an action using the default interval", () => {
const action = jest.fn();
Scheduler().schedule([action]);
jest.advanceTimersByTime(300000);
expect(action).toHaveBeenCalled();
});

it("should run actions and the done callback", () => {
const action = jest.fn();
const done = jest.fn();
Scheduler().schedule([action], done);

jest.advanceTimersByTime(300500);
expect(action).toHaveBeenCalled();
expect(done).toHaveBeenCalled();
});
});
12 changes: 12 additions & 0 deletions src/app/services/Scheduler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const Scheduler = (interval = 300000) => ({
Copy link
Contributor

@faustbrian faustbrian Aug 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functions should always be camelCase and classes PascalClass.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think that we should create a class instead of just a function in this case to explicit that the Scheduler should be service/module ? 🤔

schedule: (actions: any, done: Function) => {
for (const action of actions) {
console.log(`Scheduling action ${action.name} for every ${interval / 60000} mins`);

setInterval(() => action(), interval);

// Run a done action once all timers runned
return done && setTimeout(() => done(), interval + 500);
}
},
});
2 changes: 2 additions & 0 deletions src/app/services/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { HttpClient } from "./HttpClient";

export const httpClient = new HttpClient(10);

export * from "./Scheduler";
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,10 @@ export const AddressRow = ({ index, wallet, isLoading, onSelect }: AddressRowPro
const getIconColor = (type: string) => (type === "Starred" ? "text-theme-warning-400" : "text-theme-neutral-600");

useEffect(() => {
const loadVotes = async () => {
const loadVotes = () => {
if (!hasProperty(wallet, "isLoading")) {
// TODO: move this to profile initialising and run it every X period
await env.coins().syncDelegates(wallet?.coinId(), wallet?.networkId());

let votes: ReadOnlyWallet[] = [];
try {
await wallet.syncVotes();

votes = wallet.votes();
} catch {
votes = [];
Expand Down
9 changes: 3 additions & 6 deletions src/domains/vote/pages/Votes/Votes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,7 @@ export const Votes = () => {
}, [activeProfile, network]);

const loadDelegates = useCallback(
async (wallet) => {
// TODO: move this to profile initialising and run it every X period
// eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain
await env.coins().syncDelegates(wallet?.coinId()!, wallet?.networkId()!);
(wallet) => {
// eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain
const delegates = env.coins().delegates(wallet?.coinId()!, wallet?.networkId()!);
const readOnlyDelegates = DelegateMapper.execute(
Expand All @@ -119,10 +116,10 @@ export const Votes = () => {
setNetwork(network!);
};

const handleSelectAddress = async (address: string) => {
const handleSelectAddress = (address: string) => {
setAddress(address);
const wallet = activeProfile.wallets().findByAddress(address);
await loadDelegates(wallet);
loadDelegates(wallet);
};

return (
Expand Down
11 changes: 0 additions & 11 deletions src/domains/wallet/pages/WalletDetails/WalletDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,6 @@ export const WalletDetails = ({ txSkeletonRowsLimit }: WalletDetailsProps) => {
let votes: ReadOnlyWallet[] = [];

try {
await activeWallet.syncVotes();

votes = activeWallet.votes();
} catch {
votes = [];
Expand All @@ -85,15 +83,6 @@ export const WalletDetails = ({ txSkeletonRowsLimit }: WalletDetailsProps) => {
fetchAllData();
}, [activeWallet, env]);

useEffect(() => {
const timer = setInterval(async () => {
await activeWallet.syncIdentity();
await persist();
}, 30000);

return () => clearInterval(timer);
}, [activeWallet, persist]);

const handleDeleteWallet = async () => {
activeProfile.wallets().forget(activeWallet.id());
await persist();
Expand Down