From c2bf4cc63c63463fa46b0c586c377afbe46ce5c3 Mon Sep 17 00:00:00 2001 From: johngrantuk Date: Fri, 5 Jul 2024 10:32:07 +0100 Subject: [PATCH] feat: Add a refresh method on pools that should efficiently refresh a pools SG data. --- balancer-js/src/modules/data/pool/subgraph.ts | 38 ++++++++++++++++++- balancer-js/src/modules/data/types.ts | 2 +- balancer-js/src/modules/pools/index.ts | 12 ++++++ 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/balancer-js/src/modules/data/pool/subgraph.ts b/balancer-js/src/modules/data/pool/subgraph.ts index f0492ea8a..ac8d3966b 100644 --- a/balancer-js/src/modules/data/pool/subgraph.ts +++ b/balancer-js/src/modules/data/pool/subgraph.ts @@ -121,8 +121,42 @@ export class PoolsSubgraphRepository return pools.map((pool) => mapType(pool, this.chainId)); } - async find(id: string): Promise { - return await this.findBy('id', id); + /** + * Find pool data for id + * @param id + * @param refresh If true will refetch from SG and update cache + * @returns + */ + async find(id: string, refresh = false): Promise { + // If we're not refreshing and the pool exists in caches then return + if (!refresh && this.pools) { + const cachedPool = (await this.pools).find((pool) => pool.id === id); + if (cachedPool) return cachedPool; + } + + // Fetch pool data from SG, update cache and return + const logger = Logger.getInstance(); + + // SG fetch + logger.time(`fetching pool ${id}`); + const poolQuery = await this.client.Pool({ id }); + logger.timeEnd(`fetching pool ${id}`); + + if (!poolQuery.pool) return undefined; + + const pool = mapType(poolQuery.pool, this.chainId); + // If the pool is already cached, replace it with the new one + logger.time(`updating cache`); + const pools = await this.pools; + if (pools) { + const index = pools.findIndex((p) => p.address === pool.address); + if (index !== -1) { + this.pools = Promise.resolve([...pools.splice(index, 1), pool]); + } else this.pools = Promise.resolve([...pools, pool]); + } else this.pools = Promise.resolve([pool]); + logger.timeEnd(`updating cache`); + + return pool; } async findBy(param: PoolAttribute, value: string): Promise { diff --git a/balancer-js/src/modules/data/types.ts b/balancer-js/src/modules/data/types.ts index 96ae3cb8f..3ed1040ae 100644 --- a/balancer-js/src/modules/data/types.ts +++ b/balancer-js/src/modules/data/types.ts @@ -10,7 +10,7 @@ export * from './pool-shares/types'; export * from './gauge-shares/types'; export interface Findable { - find: (id: string) => Promise; + find: (id: string, refresh?: boolean) => Promise; findBy: (attribute: P, value: V) => Promise; } diff --git a/balancer-js/src/modules/pools/index.ts b/balancer-js/src/modules/pools/index.ts index d81a6b598..c6606b4bd 100644 --- a/balancer-js/src/modules/pools/index.ts +++ b/balancer-js/src/modules/pools/index.ts @@ -285,6 +285,18 @@ export class Pools implements Findable { return this.repositories.pools; } + /** + * Fetches new data from subgraph for pool + * (Will update PoolsSubgraphRepository cache) + * @param pool + * @returns + */ + async refresh(poolId: string): Promise { + const poolRefreshed = await this.repositories.pools.find(poolId, true); + if (!poolRefreshed) return poolRefreshed; + return Pools.wrap(poolRefreshed, this.networkConfig); + } + /** * Calculates APR on any pool data *