From 6385a35f94de71b3dc335d12ee200c251f22c708 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sehyun=20Chung=20=E2=9C=8C=EF=B8=8E?= <41171808+sehyunc@users.noreply.github.com> Date: Wed, 3 Apr 2024 14:28:05 -0700 Subject: [PATCH] trade: throttle price streams for better ui --- .../contexts/PriceContext/price-context.tsx | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/trade.renegade.fi/contexts/PriceContext/price-context.tsx b/trade.renegade.fi/contexts/PriceContext/price-context.tsx index 6de4b4ba..d4b85167 100644 --- a/trade.renegade.fi/contexts/PriceContext/price-context.tsx +++ b/trade.renegade.fi/contexts/PriceContext/price-context.tsx @@ -1,10 +1,10 @@ import { Exchange, PriceReporterWs, Token } from "@renegade-fi/renegade-js" import React, { createContext, - useCallback, useContext, useEffect, - useState, + useRef, + useState } from "react" import { env } from "@/env.mjs" @@ -38,7 +38,7 @@ export const PriceProvider = ({ children }: { children: React.ReactNode }) => { null ) const [prices, setPrices] = useState>({}) - const [lastUpdate, setLastUpdate] = useState>({}) + const lastUpdateRef = useRef>({}); const [attempted, setAttempted] = useState>({}) useEffect(() => { const priceReporter = new PriceReporterWs( @@ -50,25 +50,35 @@ export const PriceProvider = ({ children }: { children: React.ReactNode }) => { } }, []) - const handleSubscribe = useCallback( + const handleSubscribe = (exchange: Exchange, base: string, quote: string, decimals: number) => { if (!priceReporter || invalid.includes(base)) return const topic = getTopic(exchange, base, quote) if (attempted[topic]) return - let lastUpdate = 0 - const now = Date.now() - if (now - lastUpdate <= UPDATE_THRESHOLD_MS) { - return - } - lastUpdate = now - priceReporter.subscribeToTokenPair( exchange, new Token({ ticker: base }), new Token({ ticker: quote || "USDT" }), (price) => { + const now = Date.now(); + const lastUpdateTime = lastUpdateRef.current[topic] || 0; + console.log("Test: ", { + now, + topic, + lastUpdate: lastUpdateRef.current, + lastUpdateTime, + UPDATE_THRESHOLD_MS, + }) + + const randomThreshold = Math.random() * (1500 - 500) + 500; + if (now - lastUpdateTime < randomThreshold) { + console.log("Skipping update for ", topic, " because it was less than ", UPDATE_THRESHOLD_MS, "ms ago") + // If less than 1 second has passed since the last update, do not accept the new price. + return; + } + setPrices((prevPrices) => { if ( prevPrices[topic]?.toFixed(decimals) !== @@ -78,13 +88,11 @@ export const PriceProvider = ({ children }: { children: React.ReactNode }) => { } return prevPrices }) - setLastUpdate((prev) => ({ ...prev, [topic]: Date.now() })) + lastUpdateRef.current[topic] = now; } ) setAttempted((prev) => ({ ...prev, [topic]: true })) - }, - [attempted, priceReporter] - ) + } const handleGetPrice = (exchange: Exchange, base: string, quote: string) => { const topic = getTopic(exchange, base, quote) @@ -97,7 +105,7 @@ export const PriceProvider = ({ children }: { children: React.ReactNode }) => { quote: string ) => { const topic = getTopic(exchange, base, quote) - return lastUpdate[topic] + return lastUpdateRef.current[topic] } return (