From ed378e1a774e3045ea7915d9a64751057e9e1d12 Mon Sep 17 00:00:00 2001 From: Eric <5089238+emizzle@users.noreply.github.com> Date: Mon, 17 Jun 2024 17:25:05 +1000 Subject: [PATCH] Split out loading of request and request details On the requests page, only show details relating to the StorageRequested event On the request details page, load more detailed information, including slot info. If already fetched, do not re-fetch --- src/App.vue | 7 +- src/components/AppNav.vue | 8 -- src/components/ContractEventAlerts.vue | 4 - src/components/RelativeTime.vue | 11 +-- src/components/ShortenValue.vue | 5 +- src/components/Slots.vue | 4 +- src/components/StorageRequest.vue | 9 +- src/components/StorageRequests.vue | 23 ++--- src/components/Tooltip.vue | 12 +-- src/stores/requests.js | 116 ++++++++++++++----------- src/views/RequestView.vue | 53 ++++++----- src/views/RequestsView.vue | 6 +- 12 files changed, 124 insertions(+), 134 deletions(-) diff --git a/src/App.vue b/src/App.vue index 3608c3a..e74618c 100644 --- a/src/App.vue +++ b/src/App.vue @@ -6,7 +6,7 @@ import Balance from '@/components/Balance.vue' import BlockNumber from '@/components/BlockNumber.vue' import AppNav from '@/components/AppNav.vue' import ContractEventAlerts from '@/components/ContractEventAlerts.vue' -import { initDrawers } from 'flowbite' +import { initDrawers, initDismisses } from 'flowbite' const alerts = ref([]) const id = ref(0) @@ -38,10 +38,11 @@ function addSlotAlert(type, event, state) { onBeforeMount(async () => {}) onMounted(async () => { - await requestsStore.fetch() + await requestsStore.fetchPastRequests() initDrawers() + initDismisses() - function onStorageRequested(blockNumber, requestId, request, state) { + function onStorageRequested(blockNumber, requestId, state) { alerts.value.push({ type: 'info', event: 'StorageRequested', diff --git a/src/components/AppNav.vue b/src/components/AppNav.vue index a80a225..18dbaa4 100644 --- a/src/components/AppNav.vue +++ b/src/components/AppNav.vue @@ -1,16 +1,9 @@ - @@ -73,7 +66,6 @@ onMounted(() => { - diff --git a/src/components/ContractEventAlerts.vue b/src/components/ContractEventAlerts.vue index 89ac11e..20b1c47 100644 --- a/src/components/ContractEventAlerts.vue +++ b/src/components/ContractEventAlerts.vue @@ -1,12 +1,8 @@ diff --git a/src/components/RelativeTime.vue b/src/components/RelativeTime.vue index 69be5ae..c24355d 100644 --- a/src/components/RelativeTime.vue +++ b/src/components/RelativeTime.vue @@ -1,5 +1,5 @@ diff --git a/src/components/ShortenValue.vue b/src/components/ShortenValue.vue index f221762..5b84e44 100644 --- a/src/components/ShortenValue.vue +++ b/src/components/ShortenValue.vue @@ -17,8 +17,9 @@ defineProps({ }) - + {{shorten(value, ellipses, chars)}} + diff --git a/src/components/Slots.vue b/src/components/Slots.vue index 88ab14b..222a695 100644 --- a/src/components/Slots.vue +++ b/src/components/Slots.vue @@ -20,14 +20,13 @@ defineProps({ SlotID Index - Proofs Missed Provider State @@ -38,7 +37,6 @@ defineProps({ {{ shorten(slotId) }} {{ slotIdx }} - {{ proofsMissed }} {{ shorten(provider) }} diff --git a/src/components/StorageRequest.vue b/src/components/StorageRequest.vue index 2f160ec..316a0ce 100644 --- a/src/components/StorageRequest.vue +++ b/src/components/StorageRequest.vue @@ -1,5 +1,6 @@ @@ -132,14 +133,13 @@ const requestsOrdered = computed(() => { > RequestID - CID State Action { scope="row" class="flex items-center px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white" > - @@ -162,16 +157,12 @@ const requestsOrdered = computed(() => { - - - - -import { onMounted, ref } from 'vue' -import { initTooltips } from 'flowbite' -// defineProps({ -// id: { -// type: String, -// required: true -// } -// }) +import { onMounted } from 'vue' onMounted(() => { - initTooltips() + }) - diff --git a/src/stores/requests.js b/src/stores/requests.js index 5b83f1c..f604bb1 100644 --- a/src/stores/requests.js +++ b/src/stores/requests.js @@ -63,14 +63,20 @@ export const useRequestsStore = defineStore('request', () => { } const getSlots = async (requestId, numSlots) => { + console.log(`fetching ${numSlots} slots`) + let start = Date.now() let slots = [] for (let slotIdx = 0; slotIdx < numSlots; slotIdx++) { let id = slotId(requestId, slotIdx) + const startSlotState = Date.now() let state = await getSlotState(id) - let proofsMissed = await marketplace.missingProofs(id) + console.log(`fetched slot state in ${(Date.now() - startSlotState) / 1000}s`) + const startGetHost = Date.now() let provider = await marketplace.getHost(id) - slots.push({ slotId: id, slotIdx, state, proofsMissed, provider }) + console.log(`fetched slot provider in ${(Date.now() - startGetHost) / 1000}s`) + slots.push({ slotId: id, slotIdx, state, provider }) } + console.log(`fetched ${numSlots} slots in ${(Date.now() - start) / 1000}s`) return slots // blockNumbers.value.add(blockNumber) } @@ -85,40 +91,34 @@ export const useRequestsStore = defineStore('request', () => { } } - async function fetch() { + async function addRequest(requestId, blockHash) { + let state = await getRequestState(requestId) + let block = await getBlock(blockHash) + let reqExisting = requests.value.get(requestId) // just in case it already exists + let request = { + ...reqExisting, + state, + requestedAt: block.timestamp, + requestFinishedId: null, + detailsFetched: false + } + requests.value.set(requestId, request) + return request + } + + async function fetchPastRequests() { // query past events + console.log('fetching past requests') loading.value = true try { let events = await marketplace.queryFilter(StorageRequested) console.log('got ', events.length, ' StorageRequested events') - let reqs = new Map() events.forEach(async (event, i) => { console.log('getting details for StorageRequested event ', i) let start = Date.now() - // let event = events[i] - // await events.forEach(async (event) => { let { requestId, ask, expiry } = event.args let { blockHash, blockNumber } = event - let arrRequest = await marketplace.getRequest(requestId) - let request = arrayToObject(arrRequest) - let state = await getRequestState(requestId) - let slots = await getSlots(requestId, request.ask.slots) - let block = await getBlock(blockHash) - // populate temp map to constrain state update volume - // reqs.set(requestId, { - // ...request, - // state, - // slots: [], - // requestedAt: block.timestamp, - // requestFinishedId: null - // }) - requests.value.set(requestId, { - ...request, - state, - slots, - requestedAt: block.timestamp, - requestFinishedId: null - }) + await addRequest(requestId, blockHash) console.log(`got details for ${i} in ${(Date.now() - start) / 1000} seconds`) if (i === events.length - 1) { loading.value = false @@ -127,32 +127,59 @@ export const useRequestsStore = defineStore('request', () => { if (events.length === 0) { loading.value = false } - // reqs.forEach((request, requestId) => requests.value.set(requestId, request)) } catch (error) { console.error(`failed to load past contract events: ${error.message}`) } } + async function fetchRequest(requestId) { + let start = Date.now() + console.log('fetching request ', requestId) + const preFetched = requests.value.get(requestId) + if (preFetched?.detailsFetched) { + return + } + loading.value = true + try { + let arrRequest = await marketplace.getRequest(requestId) + let request = arrayToObject(arrRequest) + let slots = await getSlots(requestId, request.ask.slots) + const reqExisting = requests.value.get(requestId) + requests.value.set(requestId, { + ...reqExisting, // state, requestedAt, requestFinishedId (null) + ...request, + slots, + detailsFetched: true + }) + } catch (error) { + console.error(`failed to load slots for request ${requestId}: ${error}`) + throw error + } finally { + console.log(`fetched request in ${(Date.now() - start) / 1000}s`) + loading.value = false + } + } + function updateRequestState(requestId, newState) { - let { request, state, slots, requestFinishedId } = requests.value.get(requestId) + let { state, ...rest } = requests.value.get(requestId) state = newState - requests.value.set(requestId, { request, state, slots, requestFinishedId }) + requests.value.set(requestId, { state, ...rest }) } function updateRequestFinishedId(requestId, newRequestFinishedId) { - let { request, state, slots, requestFinishedId } = requests.value.get(requestId) + let { requestFinishedId, ...rest } = requests.value.get(requestId) requestFinishedId = newRequestFinishedId - requests.value.set(requestId, { request, state, slots, requestFinishedId }) + requests.value.set(requestId, { requestFinishedId, ...rest }) } function updateRequestSlotState(requestId, slotIdx, newState) { - let { request, state, slots, requestFinishedId } = requests.value.get(requestId) + let { slots, ...rest } = requests.value.get(requestId) slots = slots.map((slot) => { if (slot.slotIdx == slotIdx) { slot.state = newState } }) - requests.value.set(requestId, { request, state, slots, requestFinishedId }) + requests.value.set(requestId, { slots, ...rest }) } function waitForRequestFinished(requestId, duration, onRequestFinished) { @@ -184,22 +211,11 @@ export const useRequestsStore = defineStore('request', () => { ) { marketplace.on(StorageRequested, async (requestId, ask, expiry, event) => { let { blockNumber, blockHash } = event.log - let arrRequest = await marketplace.getRequest(requestId) - let request = arrayToObject(arrRequest) - let state = await getRequestState(requestId) - let slots = await getSlots(requestId, request.ask.slots) - let block = await getBlock(blockHash) - requests.value.set(requestId, { - ...request, - state, - slots, - requestedAt: block.timestamp, - requestFinishedId: null - }) + const request = addRequest(requestId, blockHash) // callback if (onStorageRequested) { - onStorageRequested(blockNumber, requestId, request, state) + onStorageRequested(blockNumber, requestId, request.state) } }) @@ -254,11 +270,6 @@ export const useRequestsStore = defineStore('request', () => { }) } - // const eventsByBlock = computed(() =>) - // const doubleCount = computed(() => count.value * 2) - // function increment() { - // count.value++ - // } return { requests, // slots, @@ -270,7 +281,8 @@ export const useRequestsStore = defineStore('request', () => { // requestCancelledEvents, // requestFailedEvents, // requestFinishedEvents, - fetch, + fetchPastRequests, + fetchRequest, listenForNewEvents, loading } diff --git a/src/views/RequestView.vue b/src/views/RequestView.vue index b0de89a..e77a0f3 100644 --- a/src/views/RequestView.vue +++ b/src/views/RequestView.vue @@ -10,32 +10,43 @@ const requestsStore = useRequestsStore() const { requests, loading } = storeToRefs(requestsStore) const route = useRoute() const router = useRouter() -const isLoading = computed(() => loading.value) -const requestId = ref(route.params.requestId) -const request = ref(requests?.value?.get(requestId.value)) -const requestNotFound = computed( - () => - !isLoading.value && requests.value !== undefined && !requests.value.get(route.params.requestId) -) -function getRequestFromStore(_) { - let req = requests?.value?.get(route.params.requestId) - if (requestNotFound.value) { - router.push({ name: 'NotFound' }) - } else { - request.value = req +const request = ref(undefined) + +async function fetch(requestId) { + try { + await requestsStore.fetchRequest(requestId) + } catch (error) { + if (error.message.includes('Unknown request')) { + router.push({ name: 'NotFound' }) + } } + request.value = requests.value.get(requestId) +} + +const hasRequest = computed(() => { + return request.value !== undefined +}) + +watch(() => route.params.requestId, fetch) + +if (loading.value) { + watch( + () => loading.value, + (isLoading) => { + if (!isLoading) { + fetch(route.params.requestId) + } + }, + { once: true } + ) +} else { + fetch(route.params.requestId) } -watch(() => route.params.requestId, getRequestFromStore) -watch(() => isLoading.value, getRequestFromStore) - - + + diff --git a/src/views/RequestsView.vue b/src/views/RequestsView.vue index 8bc54df..046cc66 100644 --- a/src/views/RequestsView.vue +++ b/src/views/RequestsView.vue @@ -3,16 +3,14 @@ import { storeToRefs } from 'pinia' import { useRequestsStore } from '@/stores/requests' import StorageRequests from '@/components/StorageRequests.vue' import SkeletonLoading from '@/components/SkeletonLoading.vue' -import { computed } from 'vue' const requestsStore = useRequestsStore() -const { loading, requests } = storeToRefs(requestsStore) -const isLoading = computed(() => loading.value || !requests.value) +const { loading } = storeToRefs(requestsStore) - +