|
@@ -1,13 +1,21 @@
|
|
|
-import React, { SetStateAction, useCallback, useContext, useState } from 'react'
|
|
|
-
|
|
|
-import { useStorageWorkers as useStorageProvidersData } from '@/api/hooks'
|
|
|
-import { BasicWorkerFieldsFragment } from '@/api/queries/__generated__/workers.generated'
|
|
|
+import { ApolloQueryResult, useApolloClient } from '@apollo/client'
|
|
|
+import React, { SetStateAction, useCallback, useContext, useEffect, useState } from 'react'
|
|
|
+import { useRef } from 'react'
|
|
|
+
|
|
|
+import { storageWorkersVariables } from '@/api/hooks'
|
|
|
+import {
|
|
|
+ BasicWorkerFieldsFragment,
|
|
|
+ GetWorkersDocument,
|
|
|
+ GetWorkersQuery,
|
|
|
+ GetWorkersQueryVariables,
|
|
|
+} from '@/api/queries/__generated__/workers.generated'
|
|
|
import { Logger } from '@/utils/logger'
|
|
|
import { getRandomIntInclusive } from '@/utils/number'
|
|
|
|
|
|
+type StorageProvidersPromise = Promise<ApolloQueryResult<GetWorkersQuery>>
|
|
|
+
|
|
|
type StorageProvidersContextValue = {
|
|
|
- storageProviders: BasicWorkerFieldsFragment[]
|
|
|
- storageProvidersLoading: boolean
|
|
|
+ storageProvidersPromiseRef: React.MutableRefObject<StorageProvidersPromise | undefined>
|
|
|
notWorkingStorageProvidersIds: string[]
|
|
|
setNotWorkingStorageProvidersIds: React.Dispatch<SetStateAction<string[]>>
|
|
|
}
|
|
@@ -29,20 +37,27 @@ class NoStorageProviderError extends Error {
|
|
|
// ¯\_(ツ)_/¯ for the name
|
|
|
export const StorageProvidersProvider: React.FC = ({ children }) => {
|
|
|
const [notWorkingStorageProvidersIds, setNotWorkingStorageProvidersIds] = useState<string[]>([])
|
|
|
+ const storageProvidersPromiseRef = useRef<StorageProvidersPromise>()
|
|
|
|
|
|
- const { storageProviders, loading } = useStorageProvidersData(
|
|
|
- { limit: 100 },
|
|
|
- {
|
|
|
+ const client = useApolloClient()
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ const promise = client.query<GetWorkersQuery, GetWorkersQueryVariables>({
|
|
|
+ query: GetWorkersDocument,
|
|
|
fetchPolicy: 'network-only',
|
|
|
- onError: (error) => Logger.error('Failed to fetch storage providers list', error),
|
|
|
- }
|
|
|
- )
|
|
|
+ variables: {
|
|
|
+ ...storageWorkersVariables,
|
|
|
+ limit: 100,
|
|
|
+ },
|
|
|
+ })
|
|
|
+ storageProvidersPromiseRef.current = promise
|
|
|
+ promise.catch((error) => Logger.error('Failed to fetch storage providers list', error))
|
|
|
+ }, [client])
|
|
|
|
|
|
return (
|
|
|
<StorageProvidersContext.Provider
|
|
|
value={{
|
|
|
- storageProvidersLoading: loading,
|
|
|
- storageProviders: storageProviders || [],
|
|
|
+ storageProvidersPromiseRef: storageProvidersPromiseRef,
|
|
|
notWorkingStorageProvidersIds,
|
|
|
setNotWorkingStorageProvidersIds,
|
|
|
}}
|
|
@@ -59,19 +74,16 @@ export const useStorageProviders = () => {
|
|
|
throw new Error('useStorageProviders must be used within StorageProvidersProvider')
|
|
|
}
|
|
|
|
|
|
- const {
|
|
|
- storageProvidersLoading,
|
|
|
- storageProviders,
|
|
|
- notWorkingStorageProvidersIds,
|
|
|
- setNotWorkingStorageProvidersIds,
|
|
|
- } = ctx
|
|
|
-
|
|
|
- const getStorageProviders = useCallback(() => {
|
|
|
- // make sure we finished fetching providers list
|
|
|
- if (storageProvidersLoading) {
|
|
|
- // TODO: we need to handle that somehow, possibly make it async and block until ready
|
|
|
- Logger.error('Trying to use storage providers while still loading')
|
|
|
- return null
|
|
|
+ const { storageProvidersPromiseRef, notWorkingStorageProvidersIds, setNotWorkingStorageProvidersIds } = ctx
|
|
|
+
|
|
|
+ const getStorageProviders = useCallback(async () => {
|
|
|
+ let storageProviders: BasicWorkerFieldsFragment[] = []
|
|
|
+ try {
|
|
|
+ const storageProvidersData = await storageProvidersPromiseRef.current
|
|
|
+ storageProviders = storageProvidersData?.data.workers || []
|
|
|
+ } catch {
|
|
|
+ // error is handled by the context
|
|
|
+ return []
|
|
|
}
|
|
|
|
|
|
const workingStorageProviders = storageProviders.filter(
|
|
@@ -87,10 +99,10 @@ export const useStorageProviders = () => {
|
|
|
}
|
|
|
|
|
|
return workingStorageProviders
|
|
|
- }, [notWorkingStorageProvidersIds, storageProviders, storageProvidersLoading])
|
|
|
+ }, [notWorkingStorageProvidersIds, storageProvidersPromiseRef])
|
|
|
|
|
|
- const getRandomStorageProvider = useCallback(() => {
|
|
|
- const workingStorageProviders = getStorageProviders()
|
|
|
+ const getRandomStorageProvider = useCallback(async () => {
|
|
|
+ const workingStorageProviders = await getStorageProviders()
|
|
|
if (!workingStorageProviders) {
|
|
|
return null
|
|
|
}
|