mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
Small refactors & optimizations (#863)
* proper cancelation Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * fix more leaks Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * remove redundant check Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * fix consume Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * fix assetactions Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * fix consume Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * remove unnecessary usage of ocean Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * small fixed in profile Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * fix
This commit is contained in:
parent
aee246cf7a
commit
fdac6d8039
@ -9,6 +9,7 @@ import { getAssetsFromDidList } from '../../utils/aquarius'
|
||||
import { getAssetsBestPrices, AssetListPrices } from '../../utils/subgraph'
|
||||
import axios, { CancelToken } from 'axios'
|
||||
import { useSiteMetadata } from '../../hooks/useSiteMetadata'
|
||||
import { useCancelToken } from '../../hooks/useCancelToken'
|
||||
|
||||
async function getAssetsBookmarked(
|
||||
bookmarks: string[],
|
||||
@ -60,12 +61,10 @@ export default function Bookmarks(): ReactElement {
|
||||
const [pinned, setPinned] = useState<AssetListPrices[]>()
|
||||
const [isLoading, setIsLoading] = useState<boolean>()
|
||||
const { chainIds } = useUserPreferences()
|
||||
|
||||
const newCancelToken = useCancelToken()
|
||||
useEffect(() => {
|
||||
if (!appConfig?.metadataCacheUri || bookmarks === []) return
|
||||
|
||||
const source = axios.CancelToken.source()
|
||||
|
||||
async function init() {
|
||||
if (!bookmarks?.length) {
|
||||
setPinned([])
|
||||
@ -78,7 +77,7 @@ export default function Bookmarks(): ReactElement {
|
||||
const resultPinned = await getAssetsBookmarked(
|
||||
bookmarks,
|
||||
chainIds,
|
||||
source.token
|
||||
newCancelToken()
|
||||
)
|
||||
const pinnedAssets: AssetListPrices[] = await getAssetsBestPrices(
|
||||
resultPinned?.results
|
||||
@ -91,11 +90,7 @@ export default function Bookmarks(): ReactElement {
|
||||
setIsLoading(false)
|
||||
}
|
||||
init()
|
||||
|
||||
return () => {
|
||||
source.cancel()
|
||||
}
|
||||
}, [bookmarks, chainIds, appConfig?.metadataCacheUri])
|
||||
}, [appConfig?.metadataCacheUri, bookmarks, chainIds, newCancelToken])
|
||||
|
||||
return (
|
||||
<Table
|
||||
|
@ -8,15 +8,16 @@ import { InputProps } from '../../../atoms/Input'
|
||||
import { fileinfo } from '../../../../utils/provider'
|
||||
import { useWeb3 } from '../../../../providers/Web3'
|
||||
import { getOceanConfig } from '../../../../utils/ocean'
|
||||
import { useCancelToken } from '../../../../hooks/useCancelToken'
|
||||
|
||||
export default function FilesInput(props: InputProps): ReactElement {
|
||||
const [field, meta, helpers] = useField(props.name)
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [fileUrl, setFileUrl] = useState<string>()
|
||||
const { chainId } = useWeb3()
|
||||
const newCancelToken = useCancelToken()
|
||||
|
||||
function loadFileInfo() {
|
||||
const source = axios.CancelToken.source()
|
||||
const config = getOceanConfig(chainId || 1)
|
||||
|
||||
async function validateUrl() {
|
||||
@ -25,7 +26,7 @@ export default function FilesInput(props: InputProps): ReactElement {
|
||||
const checkedFile = await fileinfo(
|
||||
fileUrl,
|
||||
config?.providerUri,
|
||||
source.token
|
||||
newCancelToken()
|
||||
)
|
||||
checkedFile && helpers.setValue([checkedFile])
|
||||
} catch (error) {
|
||||
@ -37,10 +38,6 @@ export default function FilesInput(props: InputProps): ReactElement {
|
||||
}
|
||||
|
||||
fileUrl && validateUrl()
|
||||
|
||||
return () => {
|
||||
source.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -40,6 +40,8 @@ import { getPreviousOrders, getPrice } from '../../../../utils/subgraph'
|
||||
import AssetActionHistoryTable from '../../AssetActionHistoryTable'
|
||||
import ComputeJobs from '../../../pages/Profile/History/ComputeJobs'
|
||||
import { BestPrice } from '../../../../models/BestPrice'
|
||||
import { useCancelToken } from '../../../../hooks/useCancelToken'
|
||||
import { useIsMounted } from '../../../../hooks/useIsMounted'
|
||||
|
||||
const SuccessAction = () => (
|
||||
<Button style="text" to="/profile?defaultTab=ComputeJobs" size="small">
|
||||
@ -72,8 +74,6 @@ export default function Compute({
|
||||
const [ddoAlgorithmList, setDdoAlgorithmList] = useState<DDO[]>()
|
||||
const [selectedAlgorithmAsset, setSelectedAlgorithmAsset] = useState<DDO>()
|
||||
const [hasAlgoAssetDatatoken, setHasAlgoAssetDatatoken] = useState<boolean>()
|
||||
const [datasetMaxDT, setDatasetMaxDT] = useState<number>(1)
|
||||
const [algoMaxDT, setAlgoMaxDT] = useState<number>(1)
|
||||
const [isPublished, setIsPublished] = useState(false)
|
||||
const [hasPreviousDatasetOrder, setHasPreviousDatasetOrder] = useState(false)
|
||||
const [previousDatasetOrderId, setPreviousDatasetOrderId] = useState<string>()
|
||||
@ -85,15 +85,19 @@ export default function Compute({
|
||||
useState<string>()
|
||||
const [datasetTimeout, setDatasetTimeout] = useState<string>()
|
||||
const [algorithmTimeout, setAlgorithmTimeout] = useState<string>()
|
||||
|
||||
const newCancelToken = useCancelToken()
|
||||
const hasDatatoken = Number(dtBalance) >= 1
|
||||
|
||||
const isMounted = useIsMounted()
|
||||
const [isConsumablePrice, setIsConsumablePrice] = useState(true)
|
||||
const [isAlgoConsumablePrice, setIsAlgoConsumablePrice] = useState(true)
|
||||
const isComputeButtonDisabled =
|
||||
isJobStarting === true ||
|
||||
file === null ||
|
||||
!ocean ||
|
||||
(!hasPreviousDatasetOrder && !hasDatatoken && !(datasetMaxDT >= 1)) ||
|
||||
(!hasPreviousAlgorithmOrder && !hasAlgoAssetDatatoken && !(algoMaxDT >= 1))
|
||||
(!hasPreviousDatasetOrder && !hasDatatoken && !isConsumablePrice) ||
|
||||
(!hasPreviousAlgorithmOrder &&
|
||||
!hasAlgoAssetDatatoken &&
|
||||
!isAlgoConsumablePrice)
|
||||
|
||||
async function checkPreviousOrders(ddo: DDO) {
|
||||
const { timeout } = (
|
||||
@ -105,6 +109,8 @@ export default function Compute({
|
||||
timeout.toString()
|
||||
)
|
||||
const assetType = ddo.findServiceByType('metadata').attributes.main.type
|
||||
|
||||
if (!isMounted()) return
|
||||
if (assetType === 'algorithm') {
|
||||
setPreviousAlgorithmOrderId(orderId)
|
||||
setHasPreviousAlgorithmOrder(!!orderId)
|
||||
@ -123,22 +129,6 @@ export default function Compute({
|
||||
setHasAlgoAssetDatatoken(Number(AssetDtBalance) >= 1)
|
||||
}
|
||||
|
||||
async function checkAssetDTMaxBuyQuantity(
|
||||
price: BestPrice,
|
||||
assetType: string
|
||||
) {
|
||||
if (!ocean || !price || !assetType) return
|
||||
const maxTokensInPool =
|
||||
price.type === 'pool'
|
||||
? await ocean.pool.getDTMaxBuyQuantity(price.address)
|
||||
: 1
|
||||
if (assetType === 'algorithm') {
|
||||
setAlgoMaxDT(Number(maxTokensInPool))
|
||||
} else {
|
||||
setDatasetMaxDT(Number(maxTokensInPool))
|
||||
}
|
||||
}
|
||||
|
||||
function getQuerryString(
|
||||
trustedAlgorithmList: publisherTrustedAlgorithm[],
|
||||
chainId?: number
|
||||
@ -188,12 +178,36 @@ export default function Compute({
|
||||
algorithmSelectionList = await transformDDOToAssetSelection(
|
||||
datasetComputeService?.serviceEndpoint,
|
||||
gueryResults.results,
|
||||
[]
|
||||
[],
|
||||
newCancelToken()
|
||||
)
|
||||
}
|
||||
return algorithmSelectionList
|
||||
}
|
||||
|
||||
const initMetadata = useCallback(async (ddo: DDO): Promise<void> => {
|
||||
if (!ddo) return
|
||||
const price = await getPrice(ddo)
|
||||
setAlgorithmPrice(price)
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (!algorithmPrice) return
|
||||
|
||||
setIsAlgoConsumablePrice(
|
||||
algorithmPrice.isConsumable !== undefined
|
||||
? algorithmPrice.isConsumable === 'true'
|
||||
: true
|
||||
)
|
||||
}, [algorithmPrice])
|
||||
useEffect(() => {
|
||||
if (!price) return
|
||||
|
||||
setIsConsumablePrice(
|
||||
price.isConsumable !== undefined ? price.isConsumable === 'true' : true
|
||||
)
|
||||
}, [price])
|
||||
|
||||
useEffect(() => {
|
||||
const { timeout } = (
|
||||
ddo.findServiceByType('access') || ddo.findServiceByType('compute')
|
||||
@ -201,17 +215,6 @@ export default function Compute({
|
||||
setDatasetTimeout(secondsToString(timeout))
|
||||
}, [ddo])
|
||||
|
||||
const initMetadata = useCallback(async (ddo: DDO): Promise<void> => {
|
||||
if (!ddo) return
|
||||
const price = await getPrice(ddo)
|
||||
setAlgorithmPrice(price)
|
||||
ocean &&
|
||||
checkAssetDTMaxBuyQuantity(
|
||||
price,
|
||||
ddo.findServiceByType('metadata').attributes.main.type
|
||||
)
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (!ddo) return
|
||||
getAlgorithmList().then((algorithms) => {
|
||||
@ -222,10 +225,6 @@ export default function Compute({
|
||||
useEffect(() => {
|
||||
if (!ocean || !accountId) return
|
||||
checkPreviousOrders(ddo)
|
||||
checkAssetDTMaxBuyQuantity(
|
||||
price,
|
||||
ddo.findServiceByType('metadata').attributes.main.type
|
||||
)
|
||||
}, [ocean, ddo, accountId])
|
||||
|
||||
useEffect(() => {
|
||||
@ -442,7 +441,7 @@ export default function Compute({
|
||||
hasPreviousOrder={hasPreviousDatasetOrder}
|
||||
hasDatatoken={hasDatatoken}
|
||||
dtBalance={dtBalance}
|
||||
datasetLowPoolLiquidity={!(datasetMaxDT >= 1)}
|
||||
datasetLowPoolLiquidity={!isConsumablePrice}
|
||||
assetType={type}
|
||||
assetTimeout={datasetTimeout}
|
||||
hasPreviousOrderSelectedComputeAsset={hasPreviousAlgorithmOrder}
|
||||
@ -451,7 +450,7 @@ export default function Compute({
|
||||
selectedAlgorithmAsset?.dataTokenInfo?.symbol
|
||||
}
|
||||
dtBalanceSelectedComputeAsset={algorithmDTBalance}
|
||||
selectedComputeAssetLowPoolLiquidity={!(algoMaxDT >= 1)}
|
||||
selectedComputeAssetLowPoolLiquidity={!isAlgoConsumablePrice}
|
||||
selectedComputeAssetType="algorithm"
|
||||
selectedComputeAssetTimeout={algorithmTimeout}
|
||||
stepText={pricingStepText || 'Starting Compute Job...'}
|
||||
|
@ -17,7 +17,7 @@ import ButtonBuy from '../../atoms/ButtonBuy'
|
||||
import { secondsToString } from '../../../utils/metadata'
|
||||
import AlgorithmDatasetsListForCompute from '../AssetContent/AlgorithmDatasetsListForCompute'
|
||||
import styles from './Consume.module.css'
|
||||
import { BestPrice } from '../../../models/BestPrice'
|
||||
import { useIsMounted } from '../../../hooks/useIsMounted'
|
||||
|
||||
const previousOrderQuery = gql`
|
||||
query PreviousOrder($id: String!, $account: String!) {
|
||||
@ -61,10 +61,10 @@ export default function Consume({
|
||||
const { consumeStepText, consume, consumeError, isLoading } = useConsume()
|
||||
const [isDisabled, setIsDisabled] = useState(true)
|
||||
const [hasDatatoken, setHasDatatoken] = useState(false)
|
||||
const [maxDt, setMaxDT] = useState<number>(1)
|
||||
const [isConsumablePrice, setIsConsumablePrice] = useState(true)
|
||||
const [assetTimeout, setAssetTimeout] = useState('')
|
||||
const [data, setData] = useState<OrdersData>()
|
||||
const isMounted = useIsMounted()
|
||||
|
||||
useEffect(() => {
|
||||
if (!ddo || !accountId) return
|
||||
@ -74,18 +74,9 @@ export default function Consume({
|
||||
account: accountId?.toLowerCase()
|
||||
}
|
||||
fetchData(previousOrderQuery, variables, context).then((result: any) => {
|
||||
setData(result.data)
|
||||
isMounted() && setData(result.data)
|
||||
})
|
||||
}, [ddo, accountId, hasPreviousOrder])
|
||||
|
||||
async function checkMaxAvaialableTokens(price: BestPrice) {
|
||||
if (!ocean || !price) return
|
||||
const maxTokensInPool =
|
||||
price.type === 'pool'
|
||||
? await ocean.pool.getDTMaxBuyQuantity(price.address)
|
||||
: 1
|
||||
setMaxDT(Number(maxTokensInPool))
|
||||
}
|
||||
}, [ddo, accountId, hasPreviousOrder, isMounted])
|
||||
|
||||
useEffect(() => {
|
||||
if (!data || !assetTimeout || data.tokenOrders.length === 0 || !accountId)
|
||||
@ -118,7 +109,6 @@ export default function Consume({
|
||||
setIsConsumablePrice(
|
||||
price.isConsumable !== undefined ? price.isConsumable === 'true' : true
|
||||
)
|
||||
checkMaxAvaialableTokens(price)
|
||||
}, [price])
|
||||
|
||||
useEffect(() => {
|
||||
@ -134,7 +124,7 @@ export default function Consume({
|
||||
!isAssetNetwork ||
|
||||
typeof consumeStepText !== 'undefined' ||
|
||||
pricingIsLoading ||
|
||||
(!hasPreviousOrder && !hasDatatoken && !(maxDt >= 1)) ||
|
||||
(!hasPreviousOrder && !hasDatatoken) ||
|
||||
!isConsumablePrice) &&
|
||||
!hasPreviousOrder &&
|
||||
!hasDatatoken)
|
||||
@ -184,7 +174,7 @@ export default function Consume({
|
||||
hasDatatoken={hasDatatoken}
|
||||
dtSymbol={ddo.dataTokenInfo?.symbol}
|
||||
dtBalance={dtBalance}
|
||||
datasetLowPoolLiquidity={!(maxDt >= 1)}
|
||||
datasetLowPoolLiquidity={!isConsumablePrice}
|
||||
onClick={handleConsume}
|
||||
assetTimeout={secondsToString(parseInt(assetTimeout))}
|
||||
assetType={type}
|
||||
|
@ -15,6 +15,7 @@ import { publisherTrustedAlgorithm as PublisherTrustedAlgorithm } from '@oceanpr
|
||||
import axios from 'axios'
|
||||
import { useSiteMetadata } from '../../../../hooks/useSiteMetadata'
|
||||
import FormActions from './FormActions'
|
||||
import { useCancelToken } from '../../../../hooks/useCancelToken'
|
||||
|
||||
export default function FormEditComputeDataset({
|
||||
data,
|
||||
@ -29,14 +30,13 @@ export default function FormEditComputeDataset({
|
||||
const { ddo } = useAsset()
|
||||
const { values }: FormikContextType<ComputePrivacyForm> = useFormikContext()
|
||||
const [allAlgorithms, setAllAlgorithms] = useState<AssetSelectionAsset[]>()
|
||||
|
||||
const newCancelToken = useCancelToken()
|
||||
const { publisherTrustedAlgorithms } =
|
||||
ddo?.findServiceByType('compute').attributes.main.privacy
|
||||
|
||||
async function getAlgorithmList(
|
||||
publisherTrustedAlgorithms: PublisherTrustedAlgorithm[]
|
||||
): Promise<AssetSelectionAsset[]> {
|
||||
const source = axios.CancelToken.source()
|
||||
const query = {
|
||||
query: {
|
||||
query_string: {
|
||||
@ -45,12 +45,13 @@ export default function FormEditComputeDataset({
|
||||
},
|
||||
sort: { created: 'desc' }
|
||||
}
|
||||
const querryResult = await queryMetadata(query, source.token)
|
||||
const querryResult = await queryMetadata(query, newCancelToken())
|
||||
const datasetComputeService = ddo.findServiceByType('compute')
|
||||
const algorithmSelectionList = await transformDDOToAssetSelection(
|
||||
datasetComputeService?.serviceEndpoint,
|
||||
querryResult.results,
|
||||
publisherTrustedAlgorithms
|
||||
publisherTrustedAlgorithms,
|
||||
newCancelToken()
|
||||
)
|
||||
return algorithmSelectionList
|
||||
}
|
||||
|
@ -86,7 +86,6 @@ export default function Pool(): ReactElement {
|
||||
const content = data.content.edges[0].node.childContentJson.pool
|
||||
|
||||
const { accountId } = useWeb3()
|
||||
const { ocean } = useOcean()
|
||||
const [dtSymbol, setDtSymbol] = useState<string>()
|
||||
const [oceanSymbol, setOceanSymbol] = useState<string>()
|
||||
const { isInPurgatory, ddo, owner, price, refreshInterval, isAssetNetwork } =
|
||||
@ -151,7 +150,7 @@ export default function Pool(): ReactElement {
|
||||
queryVariables,
|
||||
queryContext
|
||||
)
|
||||
return queryResult?.data.pool.shares[0].balance
|
||||
return queryResult?.data.pool.shares[0]?.balance
|
||||
}
|
||||
|
||||
function refetchLiquidity() {
|
||||
@ -483,11 +482,9 @@ export default function Pool(): ReactElement {
|
||||
<Token symbol="% swap fee" balance={swapFee} noIcon />
|
||||
</TokenList>
|
||||
|
||||
{ocean && (
|
||||
<div className={styles.update}>
|
||||
Fetching every {refreshInterval / 1000} sec.
|
||||
</div>
|
||||
)}
|
||||
<div className={styles.update}>
|
||||
Fetching every {refreshInterval / 1000} sec.
|
||||
</div>
|
||||
|
||||
<div className={stylesActions.actions}>
|
||||
{!isInPurgatory && (
|
||||
|
@ -12,9 +12,11 @@ import { useAsset } from '../../../providers/Asset'
|
||||
import { useOcean } from '../../../providers/Ocean'
|
||||
import { useWeb3 } from '../../../providers/Web3'
|
||||
import Web3Feedback from '../../molecules/Web3Feedback'
|
||||
import { getFileInfo } from '../../../utils/provider'
|
||||
import { fileinfo, getFileInfo } from '../../../utils/provider'
|
||||
import axios from 'axios'
|
||||
import { getOceanConfig } from '../../../utils/ocean'
|
||||
import { useCancelToken } from '../../../hooks/useCancelToken'
|
||||
import { useIsMounted } from '../../../hooks/useIsMounted'
|
||||
|
||||
export default function AssetActions(): ReactElement {
|
||||
const { accountId, balance } = useWeb3()
|
||||
@ -29,7 +31,8 @@ export default function AssetActions(): ReactElement {
|
||||
|
||||
const [isConsumable, setIsConsumable] = useState<boolean>(true)
|
||||
const [consumableFeedback, setConsumableFeedback] = useState<string>('')
|
||||
|
||||
const newCancelToken = useCancelToken()
|
||||
const isMounted = useIsMounted()
|
||||
useEffect(() => {
|
||||
if (!ddo || !accountId || !ocean || !isAssetNetwork) return
|
||||
|
||||
@ -50,36 +53,26 @@ export default function AssetActions(): ReactElement {
|
||||
const oceanConfig = getOceanConfig(ddo.chainId)
|
||||
if (!oceanConfig) return
|
||||
|
||||
const source = axios.CancelToken.source()
|
||||
|
||||
async function initFileInfo() {
|
||||
setFileIsLoading(true)
|
||||
try {
|
||||
const fileInfo = await getFileInfo(
|
||||
const fileInfoResponse = await getFileInfo(
|
||||
DID.parse(`${ddo.id}`),
|
||||
oceanConfig.providerUri,
|
||||
source.token
|
||||
newCancelToken()
|
||||
)
|
||||
|
||||
setFileMetadata(fileInfo.data[0])
|
||||
fileInfoResponse && setFileMetadata(fileInfoResponse[0])
|
||||
isMounted() && setFileIsLoading(false)
|
||||
} catch (error) {
|
||||
Logger.error(error.message)
|
||||
} finally {
|
||||
// this triggers a memory leak warning, no idea how to fix
|
||||
setFileIsLoading(false)
|
||||
}
|
||||
}
|
||||
initFileInfo()
|
||||
|
||||
return () => {
|
||||
source.cancel()
|
||||
}
|
||||
}, [ddo])
|
||||
}, [ddo, isMounted, newCancelToken])
|
||||
|
||||
// Get and set user DT balance
|
||||
useEffect(() => {
|
||||
if (!ocean || !accountId) return
|
||||
|
||||
if (!ocean || !accountId || !isAssetNetwork) return
|
||||
async function init() {
|
||||
try {
|
||||
const dtBalance = await ocean.datatokens.balance(
|
||||
|
@ -5,6 +5,7 @@ import { AssetSelectionAsset } from '../../molecules/FormFields/AssetSelection'
|
||||
import AssetComputeList from '../../molecules/AssetComputeList'
|
||||
import { useAsset } from '../../../providers/Asset'
|
||||
import { DDO } from '@oceanprotocol/lib'
|
||||
import { useCancelToken } from '../../../hooks/useCancelToken'
|
||||
|
||||
export default function AlgorithmDatasetsListForCompute({
|
||||
algorithmDid,
|
||||
@ -16,7 +17,7 @@ export default function AlgorithmDatasetsListForCompute({
|
||||
const { type } = useAsset()
|
||||
const [datasetsForCompute, setDatasetsForCompute] =
|
||||
useState<AssetSelectionAsset[]>()
|
||||
|
||||
const newCancelToken = useCancelToken()
|
||||
useEffect(() => {
|
||||
async function getDatasetsAllowedForCompute() {
|
||||
const isCompute = Boolean(dataset?.findServiceByType('compute'))
|
||||
@ -26,7 +27,8 @@ export default function AlgorithmDatasetsListForCompute({
|
||||
const datasets = await getAlgorithmDatasetsForCompute(
|
||||
algorithmDid,
|
||||
datasetComputeService?.serviceEndpoint,
|
||||
dataset?.chainId
|
||||
dataset?.chainId,
|
||||
newCancelToken()
|
||||
)
|
||||
setDatasetsForCompute(datasets)
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import classNames from 'classnames/bind'
|
||||
import { getAssetsBestPrices, AssetListPrices } from '../../utils/subgraph'
|
||||
import Loader from '../atoms/Loader'
|
||||
import { useUserPreferences } from '../../providers/UserPreferences'
|
||||
import { useIsMounted } from '../../hooks/useIsMounted'
|
||||
|
||||
const cx = classNames.bind(styles)
|
||||
|
||||
@ -42,14 +43,19 @@ const AssetList: React.FC<AssetListProps> = ({
|
||||
const { chainIds } = useUserPreferences()
|
||||
const [assetsWithPrices, setAssetWithPrices] = useState<AssetListPrices[]>()
|
||||
const [loading, setLoading] = useState<boolean>(true)
|
||||
|
||||
const isMounted = useIsMounted()
|
||||
useEffect(() => {
|
||||
if (!assets) return
|
||||
isLoading && setLoading(true)
|
||||
getAssetsBestPrices(assets).then((asset) => {
|
||||
|
||||
async function fetchPrices() {
|
||||
const asset = await getAssetsBestPrices(assets)
|
||||
if (!isMounted()) return
|
||||
setAssetWithPrices(asset)
|
||||
setLoading(false)
|
||||
})
|
||||
}
|
||||
|
||||
fetchPrices()
|
||||
}, [assets])
|
||||
|
||||
// // This changes the page field inside the query
|
||||
|
@ -4,6 +4,7 @@ import rbacRequest from '../../utils/rbac'
|
||||
import Alert from '../atoms/Alert'
|
||||
import Loader from '../atoms/Loader'
|
||||
import appConfig from '../../../app.config'
|
||||
import { useIsMounted } from '../../hooks/useIsMounted'
|
||||
|
||||
export default function Permission({
|
||||
eventType,
|
||||
@ -18,14 +19,17 @@ export default function Permission({
|
||||
const [messageState, updateMessageState] =
|
||||
useState<'error' | 'warning' | 'info' | 'success'>()
|
||||
const { accountId } = useWeb3()
|
||||
const isMounted = useIsMounted()
|
||||
useEffect(() => {
|
||||
if (url === undefined) return
|
||||
const controller = new AbortController()
|
||||
const getData = async () => {
|
||||
if (accountId === undefined) {
|
||||
updateError('Please make sure your wallet is connected to proceed.')
|
||||
updateMessageState('info')
|
||||
} else {
|
||||
const data = await rbacRequest(eventType, accountId)
|
||||
const data = await rbacRequest(eventType, accountId, controller.signal)
|
||||
if (!isMounted()) return
|
||||
updateData(data)
|
||||
if (data === 'ERROR') {
|
||||
updateError(
|
||||
@ -46,7 +50,10 @@ export default function Permission({
|
||||
}
|
||||
}
|
||||
getData()
|
||||
}, [eventType, accountId, url])
|
||||
return () => {
|
||||
controller.abort()
|
||||
}
|
||||
}, [eventType, accountId, url, isMounted])
|
||||
|
||||
if (url === undefined || data === true) {
|
||||
return <>{children}</>
|
||||
|
@ -3,7 +3,6 @@ import AssetList from '../organisms/AssetList'
|
||||
import { SearchQuery } from '@oceanprotocol/lib/dist/node/metadatacache/MetadataCache'
|
||||
import Button from '../atoms/Button'
|
||||
import Bookmarks from '../molecules/Bookmarks'
|
||||
import axios from 'axios'
|
||||
import {
|
||||
queryMetadata,
|
||||
transformChainIdsListToQuery
|
||||
@ -14,6 +13,8 @@ import { DDO, Logger } from '@oceanprotocol/lib'
|
||||
import { useSiteMetadata } from '../../hooks/useSiteMetadata'
|
||||
import { useUserPreferences } from '../../providers/UserPreferences'
|
||||
import styles from './Home.module.css'
|
||||
import { useIsMounted } from '../../hooks/useIsMounted'
|
||||
import { useCancelToken } from '../../hooks/useCancelToken'
|
||||
|
||||
async function getQueryHighest(
|
||||
chainIds: number[]
|
||||
@ -70,10 +71,10 @@ function SectionQueryResult({
|
||||
const { chainIds } = useUserPreferences()
|
||||
const [result, setResult] = useState<any>()
|
||||
const [loading, setLoading] = useState<boolean>()
|
||||
|
||||
const isMounted = useIsMounted()
|
||||
const newCancelToken = useCancelToken()
|
||||
useEffect(() => {
|
||||
if (!appConfig.metadataCacheUri) return
|
||||
const source = axios.CancelToken.source()
|
||||
|
||||
async function init() {
|
||||
if (chainIds.length === 0) {
|
||||
@ -88,9 +89,9 @@ function SectionQueryResult({
|
||||
} else {
|
||||
try {
|
||||
setLoading(true)
|
||||
const result = await queryMetadata(query, source.token)
|
||||
|
||||
if (queryData && result.totalResults > 0) {
|
||||
const result = await queryMetadata(query, newCancelToken())
|
||||
if (!isMounted()) return
|
||||
if (queryData && result?.totalResults > 0) {
|
||||
const searchDIDs = queryData.split(' ')
|
||||
const sortedAssets = sortElements(result.results, searchDIDs)
|
||||
const overflow = sortedAssets.length - 9
|
||||
@ -105,11 +106,14 @@ function SectionQueryResult({
|
||||
}
|
||||
}
|
||||
init()
|
||||
|
||||
return () => {
|
||||
source.cancel()
|
||||
}
|
||||
}, [appConfig.metadataCacheUri, query, queryData])
|
||||
}, [
|
||||
appConfig.metadataCacheUri,
|
||||
chainIds.length,
|
||||
isMounted,
|
||||
newCancelToken,
|
||||
query,
|
||||
queryData
|
||||
])
|
||||
|
||||
return (
|
||||
<section className={styles.section}>
|
||||
|
@ -9,6 +9,7 @@ import { ReactComponent as External } from '../../../../../images/external.svg'
|
||||
import { retrieveDDO } from '../../../../../utils/aquarius'
|
||||
import Results from './Results'
|
||||
import styles from './Details.module.css'
|
||||
import { useCancelToken } from '../../../../../hooks/useCancelToken'
|
||||
import { useSiteMetadata } from '../../../../../hooks/useSiteMetadata'
|
||||
|
||||
function Asset({
|
||||
@ -44,12 +45,10 @@ function DetailsAssets({ job }: { job: ComputeJobMetaData }) {
|
||||
const { appConfig } = useSiteMetadata()
|
||||
const [algoName, setAlgoName] = useState<string>()
|
||||
const [algoDtSymbol, setAlgoDtSymbol] = useState<string>()
|
||||
|
||||
const newCancelToken = useCancelToken()
|
||||
useEffect(() => {
|
||||
async function getAlgoMetadata() {
|
||||
const source = axios.CancelToken.source()
|
||||
|
||||
const ddo = await retrieveDDO(job.algoDID, source.token)
|
||||
const ddo = await retrieveDDO(job.algoDID, newCancelToken())
|
||||
setAlgoDtSymbol(ddo.dataTokenInfo.symbol)
|
||||
|
||||
const { attributes } = ddo.findServiceByType('metadata')
|
||||
|
@ -16,6 +16,7 @@ import NetworkName from '../../../../atoms/NetworkName'
|
||||
import { getComputeJobs } from '../../../../../utils/compute'
|
||||
import styles from './index.module.css'
|
||||
import { useAsset } from '../../../../../providers/Asset'
|
||||
import { useIsMounted } from '../../../../../hooks/useIsMounted'
|
||||
|
||||
export function Status({ children }: { children: string }): ReactElement {
|
||||
return <div className={styles.status}>{children}</div>
|
||||
@ -79,6 +80,7 @@ export default function ComputeJobs({
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
const { chainIds } = useUserPreferences()
|
||||
const [jobs, setJobs] = useState<ComputeJobMetaData[]>([])
|
||||
const isMounted = useIsMounted()
|
||||
|
||||
const columnsMinimal = [columns[4], columns[5], columns[3]]
|
||||
|
||||
@ -101,7 +103,7 @@ export default function ComputeJobs({
|
||||
try {
|
||||
setIsLoading(true)
|
||||
const jobs = await getComputeJobs(chainIds, config, ocean, account, ddo)
|
||||
setJobs(jobs)
|
||||
isMounted() && setJobs(jobs)
|
||||
} catch (error) {
|
||||
Logger.error(error.message)
|
||||
} finally {
|
||||
|
@ -11,12 +11,13 @@ import web3 from 'web3'
|
||||
import Token from '../../../organisms/AssetActions/Pool/Token'
|
||||
import { calculateUserLiquidity } from '../../../../utils/subgraph'
|
||||
import NetworkName from '../../../atoms/NetworkName'
|
||||
import axios, { CancelToken } from 'axios'
|
||||
import { CancelToken } from 'axios'
|
||||
import { retrieveDDO } from '../../../../utils/aquarius'
|
||||
import { isValidNumber } from '../../../../utils/numberValidations'
|
||||
import Decimal from 'decimal.js'
|
||||
import { useProfile } from '../../../../providers/Profile'
|
||||
import { DDO } from '@oceanprotocol/lib'
|
||||
import { useCancelToken } from '../../../../hooks/useCancelToken'
|
||||
|
||||
Decimal.set({ toExpNeg: -18, precision: 18, rounding: 1 })
|
||||
|
||||
@ -163,7 +164,7 @@ export default function PoolShares({
|
||||
const [assets, setAssets] = useState<Asset[]>()
|
||||
const [loading, setLoading] = useState<boolean>(false)
|
||||
const [dataFetchInterval, setDataFetchInterval] = useState<NodeJS.Timeout>()
|
||||
|
||||
const newCancelToken = useCancelToken()
|
||||
const fetchPoolSharesAssets = useCallback(
|
||||
async (cancelToken: CancelToken) => {
|
||||
if (!poolShares || isPoolSharesLoading) return
|
||||
@ -179,16 +180,15 @@ export default function PoolShares({
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
const cancelTokenSource = axios.CancelToken.source()
|
||||
|
||||
const cancelToken = newCancelToken()
|
||||
async function init() {
|
||||
setLoading(true)
|
||||
await fetchPoolSharesAssets(cancelTokenSource.token)
|
||||
await fetchPoolSharesAssets(cancelToken)
|
||||
setLoading(false)
|
||||
|
||||
if (dataFetchInterval) return
|
||||
const interval = setInterval(async () => {
|
||||
await fetchPoolSharesAssets(cancelTokenSource.token)
|
||||
await fetchPoolSharesAssets(cancelToken)
|
||||
}, REFETCH_INTERVAL)
|
||||
setDataFetchInterval(interval)
|
||||
}
|
||||
@ -196,9 +196,8 @@ export default function PoolShares({
|
||||
|
||||
return () => {
|
||||
clearInterval(dataFetchInterval)
|
||||
cancelTokenSource.cancel()
|
||||
}
|
||||
}, [dataFetchInterval, fetchPoolSharesAssets])
|
||||
}, [dataFetchInterval, fetchPoolSharesAssets, newCancelToken])
|
||||
|
||||
return accountId ? (
|
||||
<Table
|
||||
|
@ -6,7 +6,7 @@ import { getPublishedAssets } from '../../../../utils/aquarius'
|
||||
import { useSiteMetadata } from '../../../../hooks/useSiteMetadata'
|
||||
import { useUserPreferences } from '../../../../providers/UserPreferences'
|
||||
import styles from './PublishedList.module.css'
|
||||
import axios from 'axios'
|
||||
import { useCancelToken } from '../../../../hooks/useCancelToken'
|
||||
|
||||
export default function PublishedList({
|
||||
accountId
|
||||
@ -20,19 +20,18 @@ export default function PublishedList({
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [page, setPage] = useState<number>(1)
|
||||
const [service, setServiceType] = useState('dataset OR algorithm')
|
||||
const newCancelToken = useCancelToken()
|
||||
|
||||
useEffect(() => {
|
||||
if (!accountId) return
|
||||
|
||||
const cancelTokenSource = axios.CancelToken.source()
|
||||
|
||||
async function getPublished() {
|
||||
try {
|
||||
setIsLoading(true)
|
||||
const result = await getPublishedAssets(
|
||||
accountId,
|
||||
chainIds,
|
||||
cancelTokenSource.token,
|
||||
newCancelToken(),
|
||||
page - 1,
|
||||
service
|
||||
)
|
||||
@ -44,11 +43,14 @@ export default function PublishedList({
|
||||
}
|
||||
}
|
||||
getPublished()
|
||||
|
||||
return () => {
|
||||
cancelTokenSource.cancel()
|
||||
}
|
||||
}, [accountId, page, appConfig.metadataCacheUri, chainIds, service])
|
||||
}, [
|
||||
accountId,
|
||||
page,
|
||||
appConfig.metadataCacheUri,
|
||||
chainIds,
|
||||
service,
|
||||
newCancelToken
|
||||
])
|
||||
|
||||
return accountId ? (
|
||||
<>
|
||||
|
@ -122,12 +122,11 @@ export default function PublishPage({
|
||||
nextState?: Partial<FormikState<Partial<MetadataPublishFormDataset>>>
|
||||
) => void
|
||||
): Promise<void> {
|
||||
const metadata = transformPublishFormToMetadata(values)
|
||||
const timeout = mapTimeoutStringToSeconds(values.timeout)
|
||||
|
||||
const serviceType = values.access === 'Download' ? 'access' : 'compute'
|
||||
|
||||
try {
|
||||
const metadata = transformPublishFormToMetadata(values)
|
||||
const timeout = mapTimeoutStringToSeconds(values.timeout)
|
||||
|
||||
const serviceType = values.access === 'Download' ? 'access' : 'compute'
|
||||
Logger.log(
|
||||
'Publish with ',
|
||||
metadata,
|
||||
|
@ -7,9 +7,8 @@ import Sort from './sort'
|
||||
import { getResults } from './utils'
|
||||
import { navigate } from 'gatsby'
|
||||
import { updateQueryStringParameter } from '../../../utils'
|
||||
import { useSiteMetadata } from '../../../hooks/useSiteMetadata'
|
||||
import { useUserPreferences } from '../../../providers/UserPreferences'
|
||||
import axios from 'axios'
|
||||
import { useCancelToken } from '../../../hooks/useCancelToken'
|
||||
import styles from './index.module.css'
|
||||
|
||||
export default function SearchPage({
|
||||
@ -21,7 +20,6 @@ export default function SearchPage({
|
||||
setTotalResults: (totalResults: number) => void
|
||||
setTotalPagesNumber: (totalPagesNumber: number) => void
|
||||
}): ReactElement {
|
||||
const { appConfig } = useSiteMetadata()
|
||||
const parsed = queryString.parse(location.search)
|
||||
const { text, owner, tags, page, sort, sortOrder, serviceType, accessType } =
|
||||
parsed
|
||||
@ -34,23 +32,19 @@ export default function SearchPage({
|
||||
const [sortDirection, setSortDirection] = useState<string>(
|
||||
sortOrder as string
|
||||
)
|
||||
const newCancelToken = useCancelToken()
|
||||
|
||||
useEffect(() => {
|
||||
const source = axios.CancelToken.source()
|
||||
|
||||
async function initSearch() {
|
||||
setLoading(true)
|
||||
setTotalResults(undefined)
|
||||
const queryResult = await getResults(parsed, chainIds, source.token)
|
||||
const queryResult = await getResults(parsed, chainIds, newCancelToken())
|
||||
setQueryResult(queryResult)
|
||||
setTotalResults(queryResult.totalResults)
|
||||
setTotalPagesNumber(queryResult.totalPages)
|
||||
setLoading(false)
|
||||
}
|
||||
initSearch()
|
||||
return () => {
|
||||
source.cancel()
|
||||
}
|
||||
}, [
|
||||
text,
|
||||
owner,
|
||||
@ -60,7 +54,8 @@ export default function SearchPage({
|
||||
serviceType,
|
||||
accessType,
|
||||
sortOrder,
|
||||
chainIds
|
||||
chainIds,
|
||||
newCancelToken
|
||||
])
|
||||
|
||||
function setPage(page: number) {
|
||||
|
18
src/hooks/useCancelToken.ts
Normal file
18
src/hooks/useCancelToken.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { useRef, useEffect, useCallback } from 'react'
|
||||
import axios, { CancelToken } from 'axios'
|
||||
export const useCancelToken = (): (() => CancelToken) => {
|
||||
const axiosSource = useRef(null)
|
||||
const newCancelToken = useCallback(() => {
|
||||
axiosSource.current = axios.CancelToken.source()
|
||||
return axiosSource.current.token
|
||||
}, [])
|
||||
|
||||
useEffect(
|
||||
() => () => {
|
||||
if (axiosSource.current) axiosSource.current.cancel()
|
||||
},
|
||||
[]
|
||||
)
|
||||
|
||||
return newCancelToken
|
||||
}
|
14
src/hooks/useIsMounted.ts
Normal file
14
src/hooks/useIsMounted.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { useCallback, useEffect, useRef } from 'react'
|
||||
|
||||
export function useIsMounted(): () => boolean {
|
||||
const isMountedRef = useRef(true)
|
||||
const isMounted = useCallback(() => isMountedRef.current, [])
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
isMountedRef.current = false
|
||||
}
|
||||
}, [])
|
||||
|
||||
return isMounted
|
||||
}
|
@ -17,6 +17,7 @@ import { MetadataMarket } from '../@types/MetaData'
|
||||
import { useWeb3 } from './Web3'
|
||||
import { useSiteMetadata } from '../hooks/useSiteMetadata'
|
||||
import { BestPrice } from '../models/BestPrice'
|
||||
import { useCancelToken } from '../hooks/useCancelToken'
|
||||
|
||||
interface AssetProviderValue {
|
||||
isInPurgatory: boolean
|
||||
@ -61,7 +62,7 @@ function AssetProvider({
|
||||
const [type, setType] = useState<MetadataMain['type']>()
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [isAssetNetwork, setIsAssetNetwork] = useState<boolean>()
|
||||
|
||||
const newCancelToken = useCancelToken()
|
||||
const fetchDdo = async (token?: CancelToken) => {
|
||||
Logger.log('[asset] Init asset, get DDO')
|
||||
setLoading(true)
|
||||
@ -92,11 +93,10 @@ function AssetProvider({
|
||||
useEffect(() => {
|
||||
if (!asset || !appConfig.metadataCacheUri) return
|
||||
|
||||
const source = axios.CancelToken.source()
|
||||
let isMounted = true
|
||||
|
||||
async function init() {
|
||||
const ddo = await fetchDdo(source.token)
|
||||
const ddo = await fetchDdo(newCancelToken())
|
||||
if (!isMounted) return
|
||||
Logger.debug('[asset] Got DDO', ddo)
|
||||
setDDO(ddo)
|
||||
@ -105,7 +105,6 @@ function AssetProvider({
|
||||
init()
|
||||
return () => {
|
||||
isMounted = false
|
||||
source.cancel()
|
||||
}
|
||||
}, [asset, appConfig.metadataCacheUri])
|
||||
|
||||
|
@ -146,9 +146,9 @@ export async function getAssetsNames(
|
||||
export async function transformDDOToAssetSelection(
|
||||
datasetProviderEndpoint: string,
|
||||
ddoList: DDO[],
|
||||
selectedAlgorithms?: PublisherTrustedAlgorithm[]
|
||||
selectedAlgorithms?: PublisherTrustedAlgorithm[],
|
||||
cancelToken?: CancelToken
|
||||
): Promise<AssetSelectionAsset[]> {
|
||||
const source = axios.CancelToken.source()
|
||||
const didList: string[] = []
|
||||
const priceList: PriceList = await getAssetsPriceList(ddoList)
|
||||
const symbolList: any = {}
|
||||
@ -160,7 +160,7 @@ export async function transformDDOToAssetSelection(
|
||||
algoComputeService?.serviceEndpoint &&
|
||||
(didProviderEndpointMap[ddo.id] = algoComputeService?.serviceEndpoint)
|
||||
}
|
||||
const ddoNames = await getAssetsNames(didList, source.token)
|
||||
const ddoNames = await getAssetsNames(didList, cancelToken)
|
||||
const algorithmList: AssetSelectionAsset[] = []
|
||||
didList?.forEach((did: string) => {
|
||||
if (
|
||||
@ -197,12 +197,12 @@ export async function transformDDOToAssetSelection(
|
||||
export async function getAlgorithmDatasetsForCompute(
|
||||
algorithmId: string,
|
||||
datasetProviderUri: string,
|
||||
datasetChainId?: number
|
||||
datasetChainId?: number,
|
||||
cancelToken?: CancelToken
|
||||
): Promise<AssetSelectionAsset[]> {
|
||||
const source = axios.CancelToken.source()
|
||||
const computeDatasets = await queryMetadata(
|
||||
getQueryForAlgorithmDatasets(algorithmId, datasetChainId),
|
||||
source.token
|
||||
cancelToken
|
||||
)
|
||||
const computeDatasetsForCurrentAlgorithm: DDO[] = []
|
||||
computeDatasets.results.forEach((data: DDO) => {
|
||||
@ -219,7 +219,8 @@ export async function getAlgorithmDatasetsForCompute(
|
||||
const datasets = await transformDDOToAssetSelection(
|
||||
datasetProviderUri,
|
||||
computeDatasetsForCurrentAlgorithm,
|
||||
[]
|
||||
[],
|
||||
cancelToken
|
||||
)
|
||||
return datasets
|
||||
}
|
||||
|
@ -62,21 +62,30 @@ export async function getFileInfo(
|
||||
url: string | DID,
|
||||
providerUri: string,
|
||||
cancelToken: CancelToken
|
||||
): Promise<AxiosResponse> {
|
||||
): Promise<any> {
|
||||
let postBody
|
||||
try {
|
||||
if (url instanceof DID)
|
||||
postBody = {
|
||||
did: url.getDid(),
|
||||
cancelToken
|
||||
did: url.getDid()
|
||||
}
|
||||
else
|
||||
postBody = {
|
||||
url,
|
||||
cancelToken
|
||||
url
|
||||
}
|
||||
return await axios.post(`${providerUri}/api/v1/services/fileinfo`, postBody)
|
||||
const response = await axios.post(
|
||||
`${providerUri}/api/v1/services/fileinfo`,
|
||||
postBody,
|
||||
{ cancelToken }
|
||||
)
|
||||
|
||||
if (!response || response.status !== 200 || !response.data) return
|
||||
return response.data
|
||||
} catch (error) {
|
||||
Logger.error(error.message)
|
||||
if (axios.isCancel(error)) {
|
||||
Logger.log(error.message)
|
||||
} else {
|
||||
Logger.error(error.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,8 @@ import appConfig from '../../app.config'
|
||||
|
||||
export default async function rbacRequest(
|
||||
eventType: string,
|
||||
address: string
|
||||
address: string,
|
||||
signal?: AbortSignal
|
||||
): Promise<boolean | 'ERROR'> {
|
||||
const url = appConfig.rbacUrl
|
||||
if (url === undefined) {
|
||||
@ -23,7 +24,8 @@ export default async function rbacRequest(
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(data)
|
||||
body: JSON.stringify(data),
|
||||
signal: signal
|
||||
})
|
||||
return await response.json()
|
||||
} catch (error) {
|
||||
|
Loading…
Reference in New Issue
Block a user