Skip to content

Commit

Permalink
refactor: renterd hosts apis
Browse files Browse the repository at this point in the history
  • Loading branch information
alexfreska committed Sep 10, 2024
1 parent 1c94a60 commit 937367b
Show file tree
Hide file tree
Showing 17 changed files with 238 additions and 259 deletions.
6 changes: 6 additions & 0 deletions .changeset/early-bobcats-fry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'renterd': patch
'@siafoundation/renterd-react': patch
---

Fixed a bug optimistically updating last scan information when initiating a host scan.
5 changes: 5 additions & 0 deletions .changeset/eighty-eagles-taste.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'renterd': minor
---

The hosts explorer now uses the new combined hosts API.
7 changes: 7 additions & 0 deletions .changeset/fair-carrots-reflect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@siafoundation/renterd-js': minor
'@siafoundation/renterd-react': minor
'@siafoundation/renterd-types': minor
---

Added the bus list autopilots API.
7 changes: 7 additions & 0 deletions .changeset/tiny-mails-guess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@siafoundation/renterd-js': minor
'@siafoundation/renterd-react': minor
'@siafoundation/renterd-types': minor
---

Removed the search hosts and autopilot hosts APIs and added the new combined hosts API.
12 changes: 11 additions & 1 deletion apps/renterd/contexts/app/useAutopilot.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import { secondsInMilliseconds } from '@siafoundation/units'
import { useAutopilotState } from '@siafoundation/renterd-react'
import { useAutopilotState, useAutopilots } from '@siafoundation/renterd-react'
import { useEffect, useState } from 'react'

export function useAutopilot() {
// Assume there is only one autopilot.
const autopilots = useAutopilots({
config: {
swr: {
revalidateOnFocus: false,
},
},
})
const id = autopilots.data?.[0]?.id
const state = useAutopilotState({
config: {
swr: {
Expand Down Expand Up @@ -31,6 +40,7 @@ export function useAutopilot() {
}, [state])

return {
id: id || 'autopilot',
status,
state,
}
Expand Down
6 changes: 3 additions & 3 deletions apps/renterd/contexts/hosts/columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { format, formatDistance, formatRelative } from 'date-fns'
import { HostContextMenu } from '../../components/Hosts/HostContextMenu'
import { useWorkflows } from '@siafoundation/react-core'
import {
AutopilotHost,
HostItem,
RhpScanPayload,
workerRhpScanRoute,
} from '@siafoundation/renterd-types'
Expand Down Expand Up @@ -1079,8 +1079,8 @@ function getFullLabelAndTip(col: HostsTableColumn): {
}

type Key =
| keyof AutopilotHost['host']['priceTable']
| keyof AutopilotHost['host']['settings']
| keyof HostItem['host']['priceTable']
| keyof HostItem['host']['settings']

function makeRenderSc(section: 'priceTable' | 'settings', name: Key) {
return memo(function RenderPriceTableNumber({ data }: { data: HostData }) {
Expand Down
141 changes: 62 additions & 79 deletions apps/renterd/contexts/hosts/dataset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,25 @@ import BigNumber from 'bignumber.js'
import { HostData } from './types'
import { Host } from '@siafoundation/renterd-types'
import {
useAutopilotHostsSearch,
useHostsAllowlist,
useHostsBlocklist,
useHostsSearch,
useHosts,
} from '@siafoundation/renterd-react'
import { ContractData } from '../contracts/types'
import { useApp } from '../app'
import { SiaCentralHost } from '@siafoundation/sia-central-types'

export function useDataset({
autopilotStatus,
regularResponse,
autopilotResponse,
response,
allContracts,
autopilotID,
allowlist,
blocklist,
isAllowlistActive,
geoHosts,
onHostSelect,
}: {
autopilotStatus: ReturnType<typeof useApp>['autopilot']['status']
regularResponse: ReturnType<typeof useHostsSearch>
autopilotResponse: ReturnType<typeof useAutopilotHostsSearch>
response: ReturnType<typeof useHosts>
autopilotID: string
allContracts: ContractData[]
allowlist: ReturnType<typeof useHostsAllowlist>
blocklist: ReturnType<typeof useHostsBlocklist>
Expand All @@ -34,51 +30,28 @@ export function useDataset({
onHostSelect: (publicKey: string, location?: [number, number]) => void
}) {
return useMemo<HostData[] | null>(() => {
if (autopilotStatus === 'off') {
return (
regularResponse.data?.map((host) => {
const sch = geoHosts.find((gh) => gh.public_key === host.publicKey)
return {
onClick: () => onHostSelect(host.publicKey, sch?.location),
...getHostFields(host, allContracts),
...getAllowedFields({
host,
allowlist: allowlist.data,
blocklist: blocklist.data,
isAllowlistActive,
}),
...getAutopilotFields(),
location: sch?.location,
countryCode: sch?.country_code,
}
}) || null
)
} else if (autopilotStatus === 'on') {
return (
autopilotResponse.data?.map((ah) => {
const sch = geoHosts.find((gh) => gh.public_key === ah.host.publicKey)
return {
onClick: () => onHostSelect(ah.host.publicKey, sch?.location),
...getHostFields(ah.host, allContracts),
...getAllowedFields({
host: ah.host,
allowlist: allowlist.data,
blocklist: blocklist.data,
isAllowlistActive,
}),
...getAutopilotFields(ah.checks),
location: sch?.location,
countryCode: sch?.country_code,
}
}) || null
)
}
return null
return (
response.data?.map((host) => {
const sch = geoHosts.find((gh) => gh.public_key === host.publicKey)
return {
onClick: () => onHostSelect(host.publicKey, sch?.location),
...getHostFields(host, allContracts),
...getAllowedFields({
host,
allowlist: allowlist.data,
blocklist: blocklist.data,
isAllowlistActive,
}),
...getAutopilotFields(host.checks?.[autopilotID]),
location: sch?.location,
countryCode: sch?.country_code,
}
}) || null
)
}, [
onHostSelect,
autopilotStatus,
regularResponse.data,
autopilotResponse.data,
autopilotID,
response.data,
allContracts,
allowlist.data,
blocklist.data,
Expand Down Expand Up @@ -159,42 +132,52 @@ function getAllowedFields({
}

function getAutopilotFields(ahc?: {
score: number
gougingBreakdown: {
contractErr?: string
downloadErr?: string
gougingErr?: string
uploadErr?: string
}
gouging: boolean
scoreBreakdown: {
score: {
age: number
collateral: number
interactions: number
prices: number
storageRemaining: number
prices: number
uptime: number
version: number
}
unusableReasons: string[]
usable: boolean
gouging: {
contractErr?: string
downloadErr?: string
gougingErr?: string
uploadErr?: string
pruneErr?: string
}
usability: {
blocked: boolean
gouging: boolean
lowScore: boolean
notAcceptingContracts: boolean
notAnnounced: boolean
notCompletingScan: boolean
offline: boolean
redundantIP: boolean
}
}) {
return {
score: new BigNumber(ahc?.score || 0),
scoreBreakdown: {
age: new BigNumber(ahc?.scoreBreakdown.age || 0),
collateral: new BigNumber(ahc?.scoreBreakdown.collateral || 0),
interactions: new BigNumber(ahc?.scoreBreakdown.interactions || 0),
prices: new BigNumber(ahc?.scoreBreakdown.prices || 0),
storageRemaining: new BigNumber(
ahc?.scoreBreakdown.storageRemaining || 0
),
uptime: new BigNumber(ahc?.scoreBreakdown.uptime || 0),
version: new BigNumber(ahc?.scoreBreakdown.version || 0),
},
gougingBreakdown: ahc?.gougingBreakdown || {},
score: ahc
? {
age: new BigNumber(ahc?.score.age || 0),
collateral: new BigNumber(ahc?.score.collateral || 0),
interactions: new BigNumber(ahc?.score.interactions || 0),
prices: new BigNumber(ahc?.score.prices || 0),
storageRemaining: new BigNumber(ahc?.score.storageRemaining || 0),
uptime: new BigNumber(ahc?.score.uptime || 0),
version: new BigNumber(ahc?.score.version || 0),
}
: undefined,
isGouging: ahc
? Object.values(ahc.gouging || {}).some((v) => v)
: undefined,
isUsable: ahc
? Object.values(ahc.usability || {}).every((v) => !v)
: undefined,
gouging: ahc?.gouging,
unusableReasons: ahc?.unusableReasons || [],
usable: ahc?.usable,
usability: ahc?.usability,
}
}
49 changes: 9 additions & 40 deletions apps/renterd/contexts/hosts/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ import {
truncate,
} from '@siafoundation/design-system'
import {
HostsSearchFilterMode,
HostsFilterMode,
HostsUsabilityMode,
} from '@siafoundation/renterd-types'
import {
useAutopilotHostsSearch,
useHostsAllowlist,
useHostsBlocklist,
useHostsSearch,
useHosts as useHostsSearch,
} from '@siafoundation/renterd-react'
import {
createContext,
Expand Down Expand Up @@ -66,43 +65,18 @@ function useHostsMain() {
return keyIn.length ? keyIn : undefined
}, [filters, allContracts])

const autopilotResponse = useAutopilotHostsSearch({
disabled:
// prevents an extra fetch when allContracts is null
(filters.find((f) => f.id === 'hasActiveContracts') && !allContracts) ||
autopilot.status !== 'on',
const response = useHostsSearch({
payload: {
autopilotID: autopilot.id,
limit,
offset,
usabilityMode: (filters.find((f) => f.id === 'usabilityMode')?.value ||
'all') as HostsUsabilityMode,
filterMode: (filters.find((f) => f.id === 'filterMode')?.value ||
'all') as HostsSearchFilterMode,
'all') as HostsFilterMode,
addressContains: filters.find((f) => f.id === 'addressContains')?.value,
keyIn,
},
config: {
swr: {
// before autopilot is configured this will repeatedly 500
errorRetryInterval: 20_000,
refreshInterval: defaultDatasetRefreshInterval,
},
},
})

const regularResponse = useHostsSearch({
disabled: autopilot.status !== 'off',
payload: {
limit,
offset,
filterMode: (filters.find((f) => f.id === 'filterMode')?.value ||
'all') as HostsSearchFilterMode,
addressContains: filters.find((f) => f.id === 'addressContains')?.value,
keyIn:
filters.find((f) => f.id === 'hasActiveContracts') && allContracts
? allContracts.map((c) => c.hostKey)
: undefined,
},
config: {
swr: {
refreshInterval: defaultDatasetRefreshInterval,
Expand Down Expand Up @@ -197,10 +171,9 @@ function useHostsMain() {
)

const dataset = useDataset({
autopilotStatus: autopilot.status,
autopilotResponse,
regularResponse,
response,
allContracts,
autopilotID: autopilot.id,
allowlist,
blocklist,
isAllowlistActive,
Expand Down Expand Up @@ -236,12 +209,8 @@ function useHostsMain() {
[enabledColumns]
)

const isValidating =
autopilot.status === 'on'
? autopilotResponse.isValidating
: regularResponse.isValidating
const error =
autopilot.status === 'on' ? autopilotResponse.error : regularResponse.error
const isValidating = response.isValidating
const error = response.error
const dataState = useDatasetEmptyState(dataset, isValidating, error, filters)

const siascanUrl = useSiascanUrl()
Expand Down
Loading

0 comments on commit 937367b

Please sign in to comment.