Cache promises (#17)

This commit is contained in:
Armani Ferrante 2021-05-20 16:29:42 -07:00 committed by GitHub
parent cecf600e58
commit 599e54c415
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 53 deletions

View File

@ -1,6 +1,6 @@
{
"name": "@project-serum/swap-ui",
"version": "0.1.0-alpha.10",
"version": "0.1.0-alpha.11",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"homepage": ".",

View File

@ -27,8 +27,6 @@ export const BASE_TAKER_FEE_BPS = 0.0022;
type DexContext = {
// Maps market address to open orders accounts.
openOrders: Map<string, Array<OpenOrders>>;
marketCache: Map<string, Market>;
setMarketCache: (c: Map<string, Market>) => void;
swapClient: SwapClient;
};
const _DexContext = React.createContext<DexContext | null>(null);
@ -37,9 +35,6 @@ export function DexContextProvider(props: any) {
const [ooAccounts, setOoAccounts] = useState<Map<string, Array<OpenOrders>>>(
new Map()
);
const [marketCache, setMarketCache] = useState<Map<string, Market>>(
new Map()
);
const swapClient = props.swapClient;
// Two operations:
@ -73,31 +68,35 @@ export function DexContextProvider(props: any) {
"Too many markets. Please file an issue to update this"
);
}
const marketAccounts = (
(
await anchor.utils.getMultipleAccounts(
swapClient.program.provider.connection,
// @ts-ignore
[...markets].map((m) => new PublicKey(m))
)
).map((programAccount) => {
return {
publicKey: programAccount?.publicKey,
account: new Market(
Market.getLayout(DEX_PID).decode(programAccount?.account.data),
-1, // Not used so don't bother fetching.
-1, // Not used so don't bother fetching.
swapClient.program.provider.opts,
DEX_PID
),
};
});
setMarketCache((marketCache) => {
const newMarketCache = new Map(marketCache);
marketAccounts.forEach((m) => {
newMarketCache.set(m.publicKey!.toString(), m.account);
)
.map((programAccount) => {
return {
publicKey: programAccount?.publicKey,
account: new Promise<Market>((resolve) =>
resolve(
new Market(
Market.getLayout(DEX_PID).decode(
programAccount?.account.data
),
-1, // Not used so don't bother fetching.
-1, // Not used so don't bother fetching.
swapClient.program.provider.opts,
DEX_PID
)
)
),
};
})
.forEach((m) => {
_MARKET_CACHE.set(m.publicKey!.toString(), m.account);
});
return newMarketCache;
});
setOoAccounts(newOoAccounts);
});
}, [
@ -109,8 +108,6 @@ export function DexContextProvider(props: any) {
<_DexContext.Provider
value={{
openOrders: ooAccounts,
marketCache,
setMarketCache,
swapClient,
}}
>
@ -134,28 +131,25 @@ export function useOpenOrders(): Map<string, Array<OpenOrders>> {
// Lazy load a given market.
export function useMarket(market?: PublicKey): Market | undefined {
const ctx = useDexContext();
const { swapClient } = useDexContext();
const asyncMarket = useAsync(async () => {
if (!market) {
return undefined;
}
if (ctx.marketCache.get(market.toString())) {
return ctx.marketCache.get(market.toString());
if (_MARKET_CACHE.get(market.toString())) {
return _MARKET_CACHE.get(market.toString());
}
const marketClient = await Market.load(
ctx.swapClient.program.provider.connection,
const marketClient = Market.load(
swapClient.program.provider.connection,
market,
undefined,
DEX_PID
);
let cache = new Map(ctx.marketCache);
cache.set(market.toString(), marketClient);
ctx.setMarketCache(cache);
_MARKET_CACHE.set(market.toString(), marketClient);
return marketClient;
}, [ctx.swapClient.program.provider.connection, market]);
}, [swapClient.program.provider.connection, market]);
if (asyncMarket.result) {
return asyncMarket.result;
@ -178,15 +172,17 @@ export function useOrderbook(market?: PublicKey): Orderbook | undefined {
return _ORDERBOOK_CACHE.get(market.toString());
}
const [bids, asks] = await Promise.all([
marketClient.loadBids(swapClient.program.provider.connection),
marketClient.loadAsks(swapClient.program.provider.connection),
]);
const orderbook = new Promise<Orderbook>(async (resolve) => {
const [bids, asks] = await Promise.all([
marketClient.loadBids(swapClient.program.provider.connection),
marketClient.loadAsks(swapClient.program.provider.connection),
]);
const orderbook = {
bids,
asks,
};
resolve({
bids,
asks,
});
});
_ORDERBOOK_CACHE.set(market.toString(), orderbook);
@ -199,9 +195,9 @@ export function useOrderbook(market?: PublicKey): Orderbook | undefined {
if (marketClient?.bidsAddress) {
listener = swapClient.program.provider.connection.onAccountChange(
marketClient?.bidsAddress,
(info) => {
async (info) => {
const bids = OrderbookSide.decode(marketClient, info.data);
const orderbook = _ORDERBOOK_CACHE.get(
const orderbook = await _ORDERBOOK_CACHE.get(
marketClient.address.toString()
);
const oldBestBid = orderbook?.bids.items(true).next().value;
@ -237,9 +233,9 @@ export function useOrderbook(market?: PublicKey): Orderbook | undefined {
if (marketClient?.asksAddress) {
listener = swapClient.program.provider.connection.onAccountChange(
marketClient?.asksAddress,
(info) => {
async (info) => {
const asks = OrderbookSide.decode(marketClient, info.data);
const orderbook = _ORDERBOOK_CACHE.get(
const orderbook = await _ORDERBOOK_CACHE.get(
marketClient.address.toString()
);
const oldBestOffer = orderbook?.asks.items(false).next().value;
@ -276,8 +272,6 @@ export function useOrderbook(market?: PublicKey): Orderbook | undefined {
return undefined;
}
const _ORDERBOOK_CACHE = new Map<string, Orderbook>();
export function useMarketName(market: PublicKey): string | null {
const tokenMap = useTokenMap();
const marketClient = useMarket(market);
@ -538,3 +532,6 @@ type Bbo = {
bestOffer?: number;
mid?: number;
};
const _ORDERBOOK_CACHE = new Map<string, Promise<Orderbook>>();
const _MARKET_CACHE = new Map<string, Promise<Market>>();

View File

@ -130,7 +130,7 @@ export function useMint(mint?: PublicKey): MintInfo | undefined | null {
TOKEN_PROGRAM_ID,
new Account()
);
const mintInfo = await mintClient.getMintInfo();
const mintInfo = mintClient.getMintInfo();
_MINT_CACHE.set(mint.toString(), mintInfo);
return mintInfo;
}, [provider.connection, mint]);
@ -148,4 +148,4 @@ const _OWNED_TOKEN_ACCOUNTS_CACHE: Array<{
}> = [];
// Cache storing all previously fetched mint infos.
const _MINT_CACHE = new Map<string, MintInfo>();
const _MINT_CACHE = new Map<string, Promise<MintInfo>>();