fix race condition caused by race condition fix

This commit is contained in:
keyan 2023-07-11 13:33:13 -05:00
parent 0ff4da1a4f
commit bc9081eaab
1 changed files with 49 additions and 48 deletions

View File

@ -6,7 +6,7 @@ import ActionTooltip from './action-tooltip'
import ItemAct from './item-act' import ItemAct from './item-act'
import { useMe } from './me' import { useMe } from './me'
import Rainbow from '../lib/rainbow' import Rainbow from '../lib/rainbow'
import { useCallback, useEffect, useRef, useState } from 'react' import { useEffect, useMemo, useRef, useState } from 'react'
import LongPressable from 'react-longpressable' import LongPressable from 'react-longpressable'
import { Overlay, Popover } from 'react-bootstrap' import { Overlay, Popover } from 'react-bootstrap'
import { useShowModal } from './modal' import { useShowModal } from './modal'
@ -78,8 +78,6 @@ export default function UpVote ({ item, className, pendingSats, setPendingSats }
}` }`
) )
const fwd2me = me && Number(me?.id) === item?.fwdUserId
const setVoteShow = (yes) => { const setVoteShow = (yes) => {
if (!me) return if (!me) return
@ -117,8 +115,6 @@ export default function UpVote ({ item, className, pendingSats, setPendingSats }
} }
}`, { }`, {
update (cache, { data: { act: { sats } } }) { update (cache, { data: { act: { sats } } }) {
setPendingSats(0)
cache.modify({ cache.modify({
id: `Item:${item.id}`, id: `Item:${item.id}`,
fields: { fields: {
@ -155,60 +151,66 @@ export default function UpVote ({ item, className, pendingSats, setPendingSats }
} }
) )
// prevent updating pendingSats after unmount
useEffect(() => {
return () => { timerRef.current = null }
}, [])
// if we want to use optimistic response, we need to buffer the votes // if we want to use optimistic response, we need to buffer the votes
// because if someone votes in quick succession, responses come back out of order // because if someone votes in quick succession, responses come back out of order
// so we wait a bit to see if there are more votes coming in // so we wait a bit to see if there are more votes coming in
// this effectively performs our own debounced optimistic response // this effectively performs our own debounced optimistic response
const bufferVotes = useCallback((sats) => { useEffect(() => {
if (timerRef.current) { if (timerRef.current) {
clearTimeout(timerRef.current) clearTimeout(timerRef.current)
} }
timerRef.current = setTimeout(async (pendingSats, sats) => { if (pendingSats > 0) {
try { timerRef.current = setTimeout(async (pendingSats) => {
await act({ try {
variables: { id: item.id, sats: pendingSats + sats } timerRef.current && setPendingSats(0)
}) await act({
} catch (error) { variables: { id: item.id, sats: pendingSats },
timerRef.current && setPendingSats(0) optimisticResponse: {
if (error.toString().includes('insufficient funds')) { act: {
showModal(onClose => { sats: pendingSats
return <FundError onClose={onClose} /> }
}
}) })
return } catch (error) {
if (error.toString().includes('insufficient funds')) {
showModal(onClose => {
return <FundError onClose={onClose} />
})
return
}
throw new Error({ message: error.toString() })
} }
throw new Error({ message: error.toString() }) }, 1000, pendingSats)
}
}, 1000, pendingSats, sats)
timerRef.current && setPendingSats(pendingSats + sats)
}, [item, pendingSats, act, setPendingSats, showModal])
const meSats = (item?.meSats || 0) + pendingSats
// what should our next tip be?
let sats = me?.tipDefault || 1
if (me?.turboTipping && me) {
let raiseTip = sats
while (meSats >= raiseTip) {
raiseTip *= 10
} }
sats = raiseTip - meSats return () => {
} clearTimeout(timerRef.current)
timerRef.current = null
}
}, [item, pendingSats, act, setPendingSats, showModal])
const overlayText = () => { const disabled = useMemo(() => {
return `${sats} sat${sats > 1 ? 's' : ''}` return item?.mine || (me && Number(me.id) === item?.fwdUserId) || item?.deletedAt
} }, [me?.id, item?.fwdUserId, item?.mine, item?.deletedAt])
const disabled = item?.mine || fwd2me || item?.deletedAt const [meSats, sats, overlayText, color] = useMemo(() => {
const meSats = (item?.meSats || 0) + pendingSats
// what should our next tip be?
let sats = me?.tipDefault || 1
if (me?.turboTipping && me) {
let raiseTip = sats
while (meSats >= raiseTip) {
raiseTip *= 10
}
sats = raiseTip - meSats
}
return [meSats, sats, `${sats} sat${sats > 1 ? 's' : ''}`, getColor(meSats)]
}, [item?.meSats, pendingSats, me?.tipDefault, me?.turboDefault])
const color = getColor(meSats)
return ( return (
<LightningConsumer> <LightningConsumer>
{({ strike }) => {({ strike }) =>
@ -244,7 +246,7 @@ export default function UpVote ({ item, className, pendingSats, setPendingSats }
strike() strike()
bufferVotes(sats) setPendingSats(pendingSats + sats)
} }
: async () => await router.push({ : async () => await router.push({
pathname: '/signup', pathname: '/signup',
@ -252,10 +254,9 @@ export default function UpVote ({ item, className, pendingSats, setPendingSats }
}) })
} }
> >
<ActionTooltip notForm disable={disabled} overlayText={overlayText()}> <ActionTooltip notForm disable={disabled} overlayText={overlayText}>
<div <div
className={`${disabled ? styles.noSelfTips : ''} className={`${disabled ? styles.noSelfTips : ''} ${styles.upvoteWrapper}`}
${styles.upvoteWrapper}`}
> >
<UpBolt <UpBolt
width={24} width={24}