Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use React context for SolanaConnection #284

Merged
merged 22 commits into from
Aug 18, 2022
Merged

Use React context for SolanaConnection #284

merged 22 commits into from
Aug 18, 2022

Conversation

swimdrew
Copy link
Contributor

@swimdrew swimdrew commented Aug 11, 2022

Use React context instead for SolanaConnection. The current ReactQuery implementation recreates SolanaConnection every minute, resulting in spammy WS usage.

Also remove dummy websocket connection. It is unnecessary because

  • We include it to not close the Websocket client, but our only websocket usage is for the dummy connection.
  • The code snippet is likely out of date, in the source code, we can see that the websocket client is closed if there are not subscriptions, but it will also reconnect if it has been disconnected code.

Notion ticket: Slack thread

Checklist

  • Github project and label have been assigned
  • Tests have been added or are unnecessary
  • Docs have been updated or are unnecessary
  • Preview deployment works (visit the Cloudflare preview URL)
  • Manual testing in #product-testing completed or unnecessary

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Aug 11, 2022

Deploying with  Cloudflare Pages  Cloudflare Pages

Latest commit: c7803cd
Status:🚫  Build failed.

View logs

@swimdrew swimdrew added the bug Something isn't working label Aug 11, 2022
@swimdrew swimdrew changed the title UI/solana context Use React context for SolanaConnection Aug 11, 2022
@swimdrew swimdrew requested review from ramenuncle, nicomiicro and wormat and removed request for nicomiicro August 11, 2022 19:26
@swimdrew swimdrew marked this pull request as ready for review August 11, 2022 19:30
Comment on lines 9 to 28
export const useSolanaConnection = (): SolanaConnection => {
const { env } = useEnvironment();
const { chains } = useEnvironment(selectConfig, shallow);
const [chain] = chains[Protocol.Solana];
const { endpoints } = chain;

const queryClient = useQueryClient();
const queryKey = [env, "solanaConnection"];

const connection =
// used as context cache to avoid multiple instances
queryClient.getQueryData<SolanaConnection>(queryKey) ||
(function createSolanaConnection(): SolanaConnection {
const solanaConnection = new SolanaConnection(endpoints);
queryClient.setQueryData(queryKey, solanaConnection);
return solanaConnection;
})();

return connection;
};
Copy link
Contributor

@ramenuncle ramenuncle Aug 12, 2022

Choose a reason for hiding this comment

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

Keep this file and move the useSolanaConnection hook here to avoid many code changes

export const useSolanaConnection = (): SolanaConnection => {
  const context = useContext(SolanaConnectionContext);
  if (!context) {
    throw new Error("Missing Solana connection context");
  }
  return context;
};

It will also prevent test failing

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed, thanks for the cleaner PR.

// used as context cache to avoid multiple instances
queryClient.getQueryData<SolanaConnection>(queryKey) ||
(function createSolanaConnection(): SolanaConnection {
const solanaConnection = new SolanaConnection(endpoints);
Copy link
Contributor

Choose a reason for hiding this comment

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

I've added console.log around here but doesn't see the connection recreate per min.
Maybe the root cause is from somewhere else?

Copy link
Contributor

Choose a reason for hiding this comment

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

@ramenuncle I think it is related to the react-query refetch on window focus, try switching tabs after 1 min, it should be triggered

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you have a strong preference against useContext, the change I feel most strongly about is removing the dummy subscription in SolanaConnection.ts.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@swimdrew How confident are you we don't need that anymore?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Checkout this code block, the dummy subscription should be defunct: https://github.com/solana-labs/solana-web3.js/blob/7d05857/src/connection.ts#L4634-L4664

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could iterate through all actions our app does, but I feel very confident that removing the dummy connection is safe.

  1. I've read the web3.js Connection class and only the following methods use the class's rpcWsClient:
  • onAccountChange
  • onProgramAccountChange
  • onLogs
  • onSlot{Change, Update}
  • onSignature{WithOptions}
  • onRootChange

Of these methods, we use onAccountChange to establish the dummy connection to keep rpcWsClient alive, thus there is no actual need to keep rpcWsClient alive.

  1. In our /apps/ui/node_modules/.../@solana/web3.js/src/connection.ts, the rpcWsClient has the missing code that the serum code was accounting for, and I thus feel confident that the Connection class correctly opens and closes its WS client.

Copy link
Collaborator

@wormat wormat Aug 15, 2022

Choose a reason for hiding this comment

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

OK let's do some manual testing and ask testers to try leaving the app open for a while in between interactions, then let's try it (after a positive review obvs).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, it turns out our app DOES use onSignature when bridging tokens from Solana to another chain (from the wormhole library) (tested by Kenny). The swap hangs waiting to confirm the bridge, but it does not hang when swapping from Solana to BSC. Likewise, I don't know with certainty why the dummy connection is still necessary, but restoring it made my AVAX swap go through.

My proposal is to do another round of testing with the dummy connection, and keep the Solana context.

Copy link
Collaborator

Choose a reason for hiding this comment

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

OK do you want to make a follow-up issue to investigate the dummy connection?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah maybe Thor can give me his bug, and itll be a bit low priority for me.

@github-actions
Copy link

github-actions bot commented Aug 15, 2022

✨ Deployment complete! Take a peek over at https://c9abffb8.ui-storybook.pages.dev

@swimdrew swimdrew merged commit 94eb4a7 into master Aug 18, 2022
@swimdrew swimdrew deleted the ui/solanaContext branch August 18, 2022 17:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants