Streamline websockets (#56)

* Remove duplicate connection to halve websockets, then only make websocket connections for things we mostly expect to care about. Come back later for further whittling.

* Turns out we dont even need subscriptions.

* Rename variable

* Remove unused vars
This commit is contained in:
Jordan Prince 2021-06-17 18:03:25 -05:00 committed by GitHub
parent 434e1c5a11
commit bdb4c9f035
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 41 deletions

View File

@ -13,10 +13,8 @@ import { TokenAccount } from '../models';
import { chunks } from '../utils/utils'; import { chunks } from '../utils/utils';
import { EventEmitter } from '../utils/eventEmitter'; import { EventEmitter } from '../utils/eventEmitter';
import { useUserAccounts } from '../hooks/useUserAccounts'; import { useUserAccounts } from '../hooks/useUserAccounts';
import { import { WRAPPED_SOL_MINT, programIds } from '../utils/ids';
WRAPPED_SOL_MINT, import { AuctionParser } from '../actions';
programIds,
} from '../utils/ids';
const AccountsContext = React.createContext<any>(null); const AccountsContext = React.createContext<any>(null);
@ -146,6 +144,7 @@ export const cache = {
id: PublicKey | string, id: PublicKey | string,
obj: AccountInfo<Buffer>, obj: AccountInfo<Buffer>,
parser?: AccountParser, parser?: AccountParser,
isActive?: boolean | undefined | ((parsed: any) => boolean),
) => { ) => {
if (obj.data.length === 0) { if (obj.data.length === 0) {
return; return;
@ -166,10 +165,13 @@ export const cache = {
return; return;
} }
if (isActive == undefined) isActive = true;
else if (isActive instanceof Function) isActive = isActive(account);
const isNew = !genericCache.has(address); const isNew = !genericCache.has(address);
genericCache.set(address, account); genericCache.set(address, account);
cache.emitter.raiseCacheUpdated(address, isNew, deserialize); cache.emitter.raiseCacheUpdated(address, isNew, deserialize, isActive);
return account; return account;
}, },
get: (pubKey: string | PublicKey) => { get: (pubKey: string | PublicKey) => {
@ -320,7 +322,7 @@ const UseNativeAccount = () => {
const id = wallet.publicKey?.toBase58(); const id = wallet.publicKey?.toBase58();
cache.registerParser(id, TokenAccountParser); cache.registerParser(id, TokenAccountParser);
genericCache.set(id, wrapped as TokenAccount); genericCache.set(id, wrapped as TokenAccount);
cache.emitter.raiseCacheUpdated(id, false, TokenAccountParser); cache.emitter.raiseCacheUpdated(id, false, TokenAccountParser, true);
} }
} }
}, },
@ -341,7 +343,7 @@ const UseNativeAccount = () => {
return; return;
} }
const account = await connection.getAccountInfo(wallet.publicKey) const account = await connection.getAccountInfo(wallet.publicKey);
updateAccount(account); updateAccount(account);
subId = connection.onAccountChange(wallet.publicKey, updateAccount); subId = connection.onAccountChange(wallet.publicKey, updateAccount);
@ -351,7 +353,7 @@ const UseNativeAccount = () => {
if (subId) { if (subId) {
connection.removeAccountChangeListener(subId); connection.removeAccountChangeListener(subId);
} }
} };
}, [setNativeAccount, wallet, wallet?.publicKey, connection, updateCache]); }, [setNativeAccount, wallet, wallet?.publicKey, connection, updateCache]);
return { nativeAccount }; return { nativeAccount };
@ -405,7 +407,7 @@ export function AccountsProvider({ children = null as any }) {
useEffect(() => { useEffect(() => {
const subs: number[] = []; const subs: number[] = [];
cache.emitter.onCache(args => { cache.emitter.onCache(args => {
if (args.isNew) { if (args.isNew && args.isActive) {
let id = args.id; let id = args.id;
let deserialize = args.parser; let deserialize = args.parser;
connection.onAccountChange(new PublicKey(id), info => { connection.onAccountChange(new PublicKey(id), info => {
@ -435,7 +437,7 @@ export function AccountsProvider({ children = null as any }) {
programIds().token, programIds().token,
info => { info => {
// TODO: fix type in web3.js // TODO: fix type in web3.js
const id = (info.accountId as unknown) as string; const id = info.accountId as unknown as string;
// TODO: do we need a better way to identify layout (maybe a enum identifing type?) // TODO: do we need a better way to identify layout (maybe a enum identifing type?)
if (info.accountInfo.data.length === AccountLayout.span) { if (info.accountInfo.data.length === AccountLayout.span) {
const data = deserializeAccount(info.accountInfo.data); const data = deserializeAccount(info.accountInfo.data);

View File

@ -63,7 +63,6 @@ const DEFAULT = ENDPOINTS[0].endpoint;
interface ConnectionConfig { interface ConnectionConfig {
connection: Connection; connection: Connection;
sendConnection: Connection;
endpoint: string; endpoint: string;
env: ENV; env: ENV;
setEndpoint: (val: string) => void; setEndpoint: (val: string) => void;
@ -75,7 +74,6 @@ const ConnectionContext = React.createContext<ConnectionConfig>({
endpoint: DEFAULT, endpoint: DEFAULT,
setEndpoint: () => {}, setEndpoint: () => {},
connection: new Connection(DEFAULT, 'recent'), connection: new Connection(DEFAULT, 'recent'),
sendConnection: new Connection(DEFAULT, 'recent'),
env: ENDPOINTS[0].name, env: ENDPOINTS[0].name,
tokens: [], tokens: [],
tokenMap: new Map<string, TokenInfo>(), tokenMap: new Map<string, TokenInfo>(),
@ -91,10 +89,6 @@ export function ConnectionProvider({ children = undefined as any }) {
() => new Connection(endpoint, 'recent'), () => new Connection(endpoint, 'recent'),
[endpoint], [endpoint],
); );
const sendConnection = useMemo(
() => new Connection(endpoint, 'recent'),
[endpoint],
);
const env = const env =
ENDPOINTS.find(end => end.endpoint === endpoint)?.name || ENDPOINTS[0].name; ENDPOINTS.find(end => end.endpoint === endpoint)?.name || ENDPOINTS[0].name;
@ -144,30 +138,12 @@ export function ConnectionProvider({ children = undefined as any }) {
}; };
}, [connection]); }, [connection]);
useEffect(() => {
const id = sendConnection.onAccountChange(
Keypair.generate().publicKey,
() => {},
);
return () => {
sendConnection.removeAccountChangeListener(id);
};
}, [sendConnection]);
useEffect(() => {
const id = sendConnection.onSlotChange(() => null);
return () => {
sendConnection.removeSlotChangeListener(id);
};
}, [sendConnection]);
return ( return (
<ConnectionContext.Provider <ConnectionContext.Provider
value={{ value={{
endpoint, endpoint,
setEndpoint, setEndpoint,
connection, connection,
sendConnection,
tokens, tokens,
tokenMap, tokenMap,
env, env,
@ -182,10 +158,6 @@ export function useConnection() {
return useContext(ConnectionContext).connection as Connection; return useContext(ConnectionContext).connection as Connection;
} }
export function useSendConnection() {
return useContext(ConnectionContext)?.sendConnection;
}
export function useConnectionConfig() { export function useConnectionConfig() {
const context = useContext(ConnectionContext); const context = useContext(ConnectionContext);
return { return {

View File

@ -5,10 +5,12 @@ export class CacheUpdateEvent {
id: string; id: string;
parser: any; parser: any;
isNew: boolean; isNew: boolean;
constructor(id: string, isNew: boolean, parser: any) { isActive: boolean;
constructor(id: string, isNew: boolean, parser: any, isActive: boolean) {
this.id = id; this.id = id;
this.parser = parser; this.parser = parser;
this.isNew = isNew; this.isNew = isNew;
this.isActive = isActive;
} }
} }
@ -47,10 +49,15 @@ export class EventEmitter {
this.emitter.emit(MarketUpdateEvent.type, new MarketUpdateEvent(ids)); this.emitter.emit(MarketUpdateEvent.type, new MarketUpdateEvent(ids));
} }
raiseCacheUpdated(id: string, isNew: boolean, parser: any) { raiseCacheUpdated(
id: string,
isNew: boolean,
parser: any,
isActive: boolean,
) {
this.emitter.emit( this.emitter.emit(
CacheUpdateEvent.type, CacheUpdateEvent.type,
new CacheUpdateEvent(id, isNew, parser), new CacheUpdateEvent(id, isNew, parser, isActive),
); );
} }

View File

@ -27,6 +27,9 @@ import {
Vault, Vault,
setProgramIds, setProgramIds,
useConnectionConfig, useConnectionConfig,
useWallet,
walletAdapters,
AuctionState,
} from '@oyster/common'; } from '@oyster/common';
import { MintInfo } from '@solana/spl-token'; import { MintInfo } from '@solana/spl-token';
import { Connection, PublicKey, PublicKeyAndAccount } from '@solana/web3.js'; import { Connection, PublicKey, PublicKeyAndAccount } from '@solana/web3.js';
@ -112,6 +115,7 @@ const MetaContext = React.createContext<MetaContextState>({
export function MetaProvider({ children = null as any }) { export function MetaProvider({ children = null as any }) {
const connection = useConnection(); const connection = useConnection();
const { wallet } = useWallet();
const { env } = useConnectionConfig(); const { env } = useConnectionConfig();
const [metadata, setMetadata] = useState<ParsedAccount<Metadata>[]>([]); const [metadata, setMetadata] = useState<ParsedAccount<Metadata>[]>([]);
@ -226,6 +230,7 @@ export function MetaProvider({ children = null as any }) {
processAuctions( processAuctions(
accounts[i], accounts[i],
wallet,
(cb: any) => (tempCache.auctions = cb(tempCache.auctions)), (cb: any) => (tempCache.auctions = cb(tempCache.auctions)),
(cb: any) => (cb: any) =>
(tempCache.bidderMetadataByAuctionAndBidder = cb( (tempCache.bidderMetadataByAuctionAndBidder = cb(
@ -327,6 +332,7 @@ export function MetaProvider({ children = null as any }) {
setWhitelistedCreatorsByCreator, setWhitelistedCreatorsByCreator,
updateMints, updateMints,
env, env,
wallet,
]); ]);
useEffect(() => { useEffect(() => {
@ -408,6 +414,7 @@ export function MetaProvider({ children = null as any }) {
pubkey, pubkey,
account: info.accountInfo, account: info.accountInfo,
}, },
wallet,
setAuctions, setAuctions,
setBidderMetadataByAuctionAndBidder, setBidderMetadataByAuctionAndBidder,
setBidderPotsByAuctionAndBidder, setBidderPotsByAuctionAndBidder,
@ -537,6 +544,7 @@ const queryExtendedMetadata = async (
key, key,
mintAccount, mintAccount,
MintParser, MintParser,
false,
) as ParsedAccount<MintInfo>; ) as ParsedAccount<MintInfo>;
if (mint.info.supply.gt(new BN(1)) || mint.info.decimals !== 0) { if (mint.info.supply.gt(new BN(1)) || mint.info.decimals !== 0) {
// naive not NFT check // naive not NFT check
@ -576,6 +584,7 @@ function isValidHttpUrl(text: string) {
const processAuctions = ( const processAuctions = (
a: PublicKeyAndAccount<Buffer>, a: PublicKeyAndAccount<Buffer>,
wallet: any,
setAuctions: any, setAuctions: any,
setBidderMetadataByAuctionAndBidder: any, setBidderMetadataByAuctionAndBidder: any,
setBidderPotsByAuctionAndBidder: any, setBidderPotsByAuctionAndBidder: any,
@ -587,6 +596,7 @@ const processAuctions = (
a.pubkey, a.pubkey,
a.account, a.account,
AuctionParser, AuctionParser,
false,
) as ParsedAccount<AuctionData>; ) as ParsedAccount<AuctionData>;
setAuctions((e: any) => ({ setAuctions((e: any) => ({
@ -603,6 +613,7 @@ const processAuctions = (
a.pubkey, a.pubkey,
a.account, a.account,
BidderMetadataParser, BidderMetadataParser,
false,
) as ParsedAccount<BidderMetadata>; ) as ParsedAccount<BidderMetadata>;
setBidderMetadataByAuctionAndBidder((e: any) => ({ setBidderMetadataByAuctionAndBidder((e: any) => ({
...e, ...e,
@ -621,6 +632,7 @@ const processAuctions = (
a.pubkey, a.pubkey,
a.account, a.account,
BidderPotParser, BidderPotParser,
false,
) as ParsedAccount<BidderPot>; ) as ParsedAccount<BidderPot>;
setBidderPotsByAuctionAndBidder((e: any) => ({ setBidderPotsByAuctionAndBidder((e: any) => ({
@ -714,6 +726,7 @@ const processMetaplexAccounts = async (
a.pubkey, a.pubkey,
a.account, a.account,
WhitelistedCreatorParser, WhitelistedCreatorParser,
false,
) as ParsedAccount<WhitelistedCreator>; ) as ParsedAccount<WhitelistedCreator>;
const nameInfo = (names as any)[account.info.address.toBase58()]; const nameInfo = (names as any)[account.info.address.toBase58()];