1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-12-02 05:57:29 +01:00

Merge pull request #1217 from oceanprotocol/fix/compute-jobs

Fix compute jobs
This commit is contained in:
Bogdan Fazakas 2022-04-15 11:22:22 +03:00 committed by GitHub
commit c86a9f8429
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 895 additions and 1269 deletions

1773
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -21,7 +21,7 @@
"@coingecko/cryptoformat": "^0.4.4",
"@loadable/component": "^5.15.2",
"@oceanprotocol/art": "^3.2.0",
"@oceanprotocol/lib": "^1.0.0-next.33",
"@oceanprotocol/lib": "^1.0.0-next.36",
"@oceanprotocol/typographies": "^0.1.0",
"@portis/web3": "^4.0.7",
"@tippyjs/react": "^4.2.6",

View File

@ -74,15 +74,14 @@ async function getAssetMetadata(
const baseQueryparams = {
chainIds,
filters: [
getFilterTerm('datatokens', queryDtList),
getFilterTerm('service.type', 'compute'),
getFilterTerm('services.datatokenAddress', queryDtList),
getFilterTerm('services.type', 'compute'),
getFilterTerm('metadata.type', 'dataset')
],
ignorePurgatory: true
} as BaseQueryParams
const query = generateBaseQuery(baseQueryparams)
const result = await queryMetadata(query, cancelToken)
return result?.results
}
@ -215,42 +214,43 @@ async function getJobs(
assets: Asset[]
): Promise<ComputeJobMetaData[]> {
const computeJobs: ComputeJobMetaData[] = []
providerUrls.forEach(async (providerUrl) => {
try {
const providerComputeJobs = (await ProviderInstance.computeStatus(
providerUrl,
accountId
)) as ComputeJob[]
// commented loop since we decide how to filter jobs
// for await (const providerUrl of providerUrls) {
try {
const providerComputeJobs = (await ProviderInstance.computeStatus(
providerUrls[0],
accountId
)) as ComputeJob[]
if (!providerComputeJobs) {
providerComputeJobs.sort((a, b) => {
if (a.dateCreated > b.dateCreated) {
return -1
}
if (a.dateCreated < b.dateCreated) {
return 1
}
return 0
})
providerComputeJobs.forEach((job) => {
const did = job.inputDID[0]
const asset = assets.filter((x) => x.id === did)[0]
if (providerComputeJobs) {
providerComputeJobs.sort((a, b) => {
if (a.dateCreated > b.dateCreated) {
return -1
}
if (a.dateCreated < b.dateCreated) {
return 1
}
return 0
})
if (!asset) {
const compJob: ComputeJobMetaData = {
...job,
assetName: asset.metadata.name,
assetDtSymbol: asset.datatokens[0].symbol,
networkId: asset.chainId
}
computeJobs.push(compJob)
providerComputeJobs.forEach((job) => {
const did = job.inputDID[0]
const asset = assets.filter((x) => x.id === did)[0]
if (asset) {
const compJob: ComputeJobMetaData = {
...job,
assetName: asset.metadata.name,
assetDtSymbol: asset.datatokens[0].symbol,
networkId: asset.chainId
}
})
}
} catch (err) {
LoggerInstance.error(err.message)
computeJobs.push(compJob)
}
})
}
})
} catch (err) {
LoggerInstance.error(err.message)
}
// }
return computeJobs
}
export async function getComputeJobs(
@ -274,21 +274,18 @@ export async function getComputeJobs(
user: accountId.toLowerCase()
}
console.log(' getComputeJobs variables ', variables)
const results = await fetchDataForMultipleChains(
assetDTAddress ? getComputeOrdersByDatatokenAddress : getComputeOrders,
variables,
assetDTAddress ? [asset?.chainId] : chainIds
)
console.log(' getComputeJobs results getComputeOrders', results)
let tokenOrders: TokenOrder[] = []
results.map((result) => {
result.orders.forEach((tokenOrder: TokenOrder) =>
tokenOrders.push(tokenOrder)
)
})
console.log(' getComputeJobs tokenOrders ', tokenOrders)
if (tokenOrders.length === 0) {
return computeResult
}
@ -296,6 +293,7 @@ export async function getComputeJobs(
tokenOrders = tokenOrders.sort(
(a, b) => b.createdTimestamp - a.createdTimestamp
)
const datatokenAddressList = tokenOrders.map(
(tokenOrder: TokenOrder) => tokenOrder.datatoken.address
)
@ -311,6 +309,7 @@ export async function getComputeJobs(
assets.forEach((asset: Asset) =>
providerUrls.push(asset.services[0].serviceEndpoint)
)
computeResult.computeJobs = await getJobs(providerUrls, accountId, assets)
computeResult.isLoaded = true

View File

@ -243,13 +243,10 @@ export async function fetchDataForMultipleChains(
let datas: any[] = []
try {
for (const chainId of chainIds) {
// console.log('fetch chainID', chainId)
const context: OperationContext = getQueryContext(chainId)
const response = await fetchData(query, variables, context)
// console.log('fetch response', response)
if (!response || response.error) continue
datas = datas.concat(response?.data)
// console.log('fetch datas', datas)
}
return datas
} catch (error) {
@ -358,10 +355,8 @@ export async function getAccountTVLInOwnAssets(
chainIds
)
let tvl = new Decimal(0)
// console.log('resss', results)
for (const result of results) {
// console.log('result.poolShares', result.poolShares)
for (const poolShare of result.poolShares) {
const poolUserTvl = calculateUserTVL(
poolShare.shares,
@ -369,7 +364,6 @@ export async function getAccountTVLInOwnAssets(
poolShare.pool.baseTokenLiquidity
)
tvl = tvl.add(new Decimal(poolUserTvl))
// console.log('result.poolShares', tvl.toString())
}
}
return tvl.toDecimalPlaces(MAX_DECIMALS).toString()

View File

@ -9,7 +9,8 @@ import {
Datatoken,
ProviderInstance,
ComputeAsset,
ZERO_ADDRESS
ZERO_ADDRESS,
ComputeEnvironment
} from '@oceanprotocol/lib'
import { toast } from 'react-toastify'
import Price from '@shared/Price'
@ -83,6 +84,8 @@ export default function Compute({
const [isConsumablePrice, setIsConsumablePrice] = useState(true)
const [isAlgoConsumablePrice, setIsAlgoConsumablePrice] = useState(true)
const [computeStatusText, setComputeStatusText] = useState('')
const [computeEnv, setComputeEnv] = useState<ComputeEnvironment>()
const [computeValidUntil, setComputeValidUntil] = useState<number>()
const [datasetOrderPriceAndFees, setDatasetOrderPriceAndFees] =
useState<OrderPriceAndFees>()
const [isRequestingDataseOrderPrice, setIsRequestingDataseOrderPrice] =
@ -110,28 +113,76 @@ export default function Compute({
return hasAlgoDt
}
async function initPriceAndFees() {
const computeEnv = await getComputeEnviroment(asset)
setComputeEnv(computeEnv)
const validUntil = getValidUntilTime(
computeEnv?.maxJobDuration,
asset.services[0].timeout,
selectedAlgorithmAsset.services[0].timeout
)
setComputeValidUntil(validUntil)
if (
asset?.accessDetails?.addressOrId !== ZERO_ADDRESS ||
asset?.accessDetails?.type !== 'free'
) {
setIsRequestingDataseOrderPrice(true)
setComputeStatusText(
getComputeFeedback(
asset.accessDetails.baseToken?.symbol,
asset.accessDetails.datatoken?.symbol,
asset.metadata.type
)[0]
)
const datasetPriceAndFees = await getOrderPriceAndFees(
asset,
accountId,
computeEnv?.id,
validUntil
)
if (!datasetPriceAndFees) {
setError('Error setting dataset price and fees!')
toast.error('Error setting dataset price and fees!')
return
}
setDatasetOrderPriceAndFees(datasetPriceAndFees)
setIsRequestingDataseOrderPrice(false)
}
if (
selectedAlgorithmAsset?.accessDetails?.addressOrId !== ZERO_ADDRESS ||
selectedAlgorithmAsset?.accessDetails?.type !== 'free'
) {
setIsRequestingAlgoOrderPrice(true)
setComputeStatusText(
getComputeFeedback(
selectedAlgorithmAsset?.accessDetails?.baseToken?.symbol,
selectedAlgorithmAsset?.accessDetails?.datatoken?.symbol,
selectedAlgorithmAsset?.metadata?.type
)[0]
)
const algorithmOrderPriceAndFees = await getOrderPriceAndFees(
selectedAlgorithmAsset,
ZERO_ADDRESS,
computeEnv?.id,
validUntil
)
if (!algorithmOrderPriceAndFees) {
setError('Error setting algorithm price and fees!')
toast.error('Error setting algorithm price and fees!')
return
}
setAlgoOrderPriceAndFees(algorithmOrderPriceAndFees)
setIsRequestingAlgoOrderPrice(false)
}
}
useEffect(() => {
if (!asset?.accessDetails || !accountId) return
setIsConsumablePrice(asset?.accessDetails?.isPurchasable)
setIsOwned(asset?.accessDetails?.isOwned)
setValidOrderTx(asset?.accessDetails?.validOrderTx)
async function initDatasetPriceAndFees() {
if (
asset?.accessDetails?.addressOrId === ZERO_ADDRESS ||
asset?.accessDetails?.type === 'free'
)
return
setIsRequestingDataseOrderPrice(true)
setComputeStatusText('Calculating price including fees.')
const orderPriceAndFees = await getOrderPriceAndFees(asset, accountId)
setDatasetOrderPriceAndFees(orderPriceAndFees)
setIsRequestingDataseOrderPrice(false)
}
initDatasetPriceAndFees()
}, [asset?.accessDetails])
useEffect(() => {
@ -143,26 +194,9 @@ export default function Compute({
selectedAlgorithmAsset?.accessDetails?.validOrderTx
)
async function initAlgoPriceAndFees() {
if (
selectedAlgorithmAsset?.accessDetails?.addressOrId === ZERO_ADDRESS ||
selectedAlgorithmAsset?.accessDetails?.type === 'free'
)
return
setIsRequestingAlgoOrderPrice(true)
setComputeStatusText('Calculating price including fees.')
const orderPriceAndFees = await getOrderPriceAndFees(
selectedAlgorithmAsset,
accountId
)
setAlgoOrderPriceAndFees(orderPriceAndFees)
setIsRequestingAlgoOrderPrice(false)
}
async function initSelectedAlgo() {
const hasAlgoDt = await checkAssetDTBalance(selectedAlgorithmAsset)
!hasAlgoDt && (await initAlgoPriceAndFees())
await checkAssetDTBalance(selectedAlgorithmAsset)
await initPriceAndFees()
}
initSelectedAlgo()
@ -215,32 +249,6 @@ export default function Compute({
return
}
const computeEnv = await getComputeEnviroment(asset)
const validUntil = getValidUntilTime(
computeEnv?.maxJobDuration,
asset.services[0].timeout,
selectedAlgorithmAsset.services[0].timeout
)
setComputeStatusText(
getComputeFeedback(
asset.accessDetails.baseToken?.symbol,
asset.accessDetails.datatoken?.symbol,
asset.metadata.type
)[0]
)
const datasetPriceAndFees = await getOrderPriceAndFees(
asset,
accountId,
computeEnv?.id,
validUntil
)
if (!datasetPriceAndFees) {
setError('Error setting dataset price and fees!')
toast.error('Error setting dataset price and fees!')
return
}
let datasetOrderTx
if (isOwned) {
datasetOrderTx = validOrderTx
@ -266,7 +274,10 @@ export default function Compute({
return
}
}
LoggerInstance.log('dataset orderPriceAndFees: ', datasetPriceAndFees)
LoggerInstance.log(
'dataset orderPriceAndFees: ',
datasetOrderPriceAndFees
)
setComputeStatusText(
getComputeFeedback(
asset.accessDetails.baseToken?.symbol,
@ -277,10 +288,10 @@ export default function Compute({
const orderTx = await order(
web3,
asset,
datasetPriceAndFees,
datasetOrderPriceAndFees,
accountId,
computeEnv?.id,
validUntil,
computeValidUntil,
computeEnv?.consumerAddress
)
if (!orderTx) {
@ -301,26 +312,6 @@ export default function Compute({
}
}
setComputeStatusText(
getComputeFeedback(
selectedAlgorithmAsset.accessDetails.baseToken?.symbol,
selectedAlgorithmAsset.accessDetails.datatoken?.symbol,
selectedAlgorithmAsset.metadata.type
)[0]
)
const algorithmOrderPriceAndFees = await getOrderPriceAndFees(
selectedAlgorithmAsset,
ZERO_ADDRESS,
computeEnv?.id,
validUntil
)
if (!algorithmOrderPriceAndFees) {
setError('Error setting algorithm price and fees!')
toast.error('Error setting algorithm price and fees!')
return
}
let algorithmOrderTx
if (isAlgorithmOwned) {
algorithmOrderTx = validAlgorithmOrderTx
@ -362,10 +353,10 @@ export default function Compute({
const orderTx = await order(
web3,
selectedAlgorithmAsset,
algorithmOrderPriceAndFees,
algoOrderPriceAndFees,
accountId,
computeEnv?.id,
validUntil,
computeValidUntil,
computeEnv?.consumerAddress
)
if (!orderTx) {

View File

@ -62,6 +62,20 @@
.assetMeta code {
color: var(--color-secondary);
font-size: var(--font-size-small);
overflow: hidden;
width: 100%;
flex: 6;
text-overflow: ellipsis;
white-space: nowrap;
}
.assetMeta span {
flex: 1;
}
.assetMeta {
display: flex;
flex-wrap: wrap;
}
.meta {

View File

@ -33,7 +33,8 @@ function Asset({
</a>
</h3>
<p className={styles.assetMeta}>
{symbol} | <code>{did}</code>
<span className={styles.assetMeta}> {`${symbol} | `}</span>
<code className={styles.assetMeta}>{did}</code>
</p>
</div>
)
@ -97,7 +98,7 @@ export default function Details({
/>
)}
<MetaItem title="Job ID" content={<code>{job.jobId}</code>} />
{/* {job.resultsDid && (
{/* {job.results[0]. && (
<MetaItem
title="Published Results DID"
content={<code>{job.resultsDid}</code>}

View File

@ -3,6 +3,10 @@
border-bottom-left-radius: var(--border-radius) !important;
}
.results li {
list-style-type: none;
}
.help {
margin-top: calc(var(--spacer) / 3);
}

View File

@ -1,90 +1,106 @@
import { LoggerInstance } from '@oceanprotocol/lib'
import React, { ReactElement, useState } from 'react'
import Loader from '@shared/atoms/Loader'
import {
ComputeResultType,
downloadFileBrowser,
LoggerInstance,
Provider
} from '@oceanprotocol/lib'
import React, { ReactElement, useEffect, useState } from 'react'
import { ListItem } from '@shared/atoms/Lists'
import Button from '@shared/atoms/Button'
import styles from './Results.module.css'
import FormHelp from '@shared/FormInput/Help'
import content from '../../../../../content/pages/history.json'
import { useWeb3 } from '@context/Web3'
import { useCancelToken } from '@hooks/useCancelToken'
import { retrieveAsset } from '@utils/aquarius'
export default function Results({
job
}: {
job: ComputeJobMetaData
}): ReactElement {
const { accountId } = useWeb3()
const providerInstance = new Provider()
const { accountId, web3 } = useWeb3()
const [isLoading, setIsLoading] = useState(false)
const [hasFetched, setHasFetched] = useState(false)
const isFinished = job.dateFinished !== null
async function getResults() {
const [datasetProvider, setDatasetProvider] = useState<string>()
const newCancelToken = useCancelToken()
useEffect(() => {
async function getAssetMetadata() {
const ddo = await retrieveAsset(job.inputDID[0], newCancelToken())
setDatasetProvider(ddo.services[0].serviceEndpoint)
}
getAssetMetadata()
}, [job.inputDID[0]])
function getDownloadButtonValue(type: ComputeResultType): string {
let buttonName
switch (type) {
case 'output':
buttonName = 'Download results'
break
case 'algorithmLog':
buttonName = 'Download algorithm logs'
break
case 'configrationLog':
buttonName = 'Download configuration logs'
break
case 'publishLog':
buttonName = 'Download publish logs'
break
default:
buttonName = 'Download results'
break
}
return buttonName
}
async function downloadResults(resultIndex: number) {
if (!accountId || !job) return
try {
setIsLoading(true)
// const jobStatus = await ocean.compute.status(
// account,
// job.did,
// undefined,
// undefined,
// job.jobId
// )
// if (jobStatus?.length > 0) {
// job.algorithmLogUrl = jobStatus[0].algorithmLogUrl
// job.resultsUrl = jobStatus[0].resultsUrl
// }
const jobResult = await providerInstance.getComputeResultUrl(
datasetProvider,
web3,
accountId,
job.jobId,
resultIndex
)
await downloadFileBrowser(jobResult)
} catch (error) {
LoggerInstance.error(error.message)
} finally {
setIsLoading(false)
setHasFetched(true)
}
}
return (
<div className={styles.results}>
{hasFetched ? (
{isFinished ? (
<ul>
<ListItem>
{/* {job.algorithmLogUrl ? (
<a href={job.algorithmLogUrl} target="_blank" rel="noreferrer">
View Log
</a>
) : (
'No logs found.'
)} */}
</ListItem>
{/* {job.resultsUrl &&
Array.isArray(job.resultsUrl) &&
job.resultsUrl.map((url, i) =>
url ? (
<ListItem key={job.jobId}>
<a href={url} target="_blank" rel="noreferrer">
View Result {i + 1}
</a>
{job.results &&
Array.isArray(job.results) &&
job.results.map((jobResult, i) =>
jobResult.filename ? (
<ListItem key={i}>
<Button
style="primary"
size="small"
onClick={() => downloadResults(i)}
disabled={isLoading || !isFinished}
>
{getDownloadButtonValue(jobResult.type)}
</Button>
</ListItem>
) : (
<ListItem>No results found.</ListItem>
)
)} */}
)}
</ul>
) : (
<Button
style="primary"
size="small"
onClick={() => getResults()}
disabled={isLoading || !isFinished}
>
{isLoading ? (
<Loader />
) : !isFinished ? (
'Waiting for results...'
) : (
'Get Results'
)}
</Button>
<p> Waiting for results...</p>
)}
<FormHelp className={styles.help}>{content.compute.storage}</FormHelp>
</div>