Skip to content

Commit 73e99c4

Browse files
committed
feat(indexd): add stuck host alert rendering
1 parent 7dadad8 commit 73e99c4

File tree

5 files changed

+99
-20
lines changed

5 files changed

+99
-20
lines changed

.changeset/brown-rooms-do.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'indexd': minor
3+
---
4+
5+
Added support for stuck host alerts.

apps/indexd/components/Data/Alerts/SidePanelAlert.tsx

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
useAdminAlert,
1818
useAdminAlertsDismiss,
1919
} from '@siafoundation/indexd-react'
20+
import { humanDate } from '@siafoundation/units'
2021
import { getAlertTypeLabel } from './utils'
2122
import { SidePanelHeadingCopyable } from '../SidePanelHeadingCopyable'
2223
import { transformAlert } from './transform'
@@ -104,13 +105,15 @@ export function SidePanelAccount() {
104105
<InfoRow label="Data" value={JSON.stringify(alert.data)} />
105106
</div>
106107
)}
107-
{alert.data && alert.data.type === 'lostSectors' && (
108-
<InfoRow
109-
variant="column"
110-
label="Hint"
111-
value={alert.data.hint}
112-
/>
113-
)}
108+
{alert.data &&
109+
'hint' in alert.data &&
110+
alert.data.type !== 'unknown' && (
111+
<InfoRow
112+
variant="column"
113+
label="Hint"
114+
value={alert.data.hint}
115+
/>
116+
)}
114117
</div>
115118
</SidePanelSection>
116119
{alert.data && alert.data.type === 'lostSectors' && (
@@ -126,6 +129,35 @@ export function SidePanelAccount() {
126129
</div>
127130
</SidePanelSection>
128131
)}
132+
{alert.data && alert.data.type === 'stuckHosts' && (
133+
<SidePanelSection heading="Stuck hosts">
134+
<div className="flex flex-col gap-4">
135+
{alert.data.hosts.map((host) => (
136+
<div key={host.publicKey} className="flex flex-col gap-2">
137+
<InfoRow
138+
label="Host Key"
139+
value={
140+
<ValueCopyable
141+
value={host.publicKey}
142+
type="hostPublicKey"
143+
/>
144+
}
145+
/>
146+
<InfoRow
147+
label="Stuck Since"
148+
value={humanDate(host.stuckSince, {
149+
timeStyle: 'short',
150+
})}
151+
/>
152+
<InfoRow
153+
label="Unpinned Sectors"
154+
value={host.unpinnedSectors.toLocaleString()}
155+
/>
156+
</div>
157+
))}
158+
</div>
159+
</SidePanelSection>
160+
)}
129161
</SidePanel>
130162
)}
131163
/>

apps/indexd/components/Data/Alerts/transform.ts

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,44 @@
11
import { Alert } from '@siafoundation/indexd-types'
2-
import { AlertData, AlertDataLostSectors, AlertDataUnknown } from './types'
2+
import {
3+
AlertData,
4+
AlertDataLostSectors,
5+
AlertDataStuckHosts,
6+
AlertDataUnknown,
7+
AlertType,
8+
StuckHost,
9+
} from './types'
10+
11+
function getAlertType(alert: Alert): AlertType {
12+
if (alert.data && 'hostKeys' in alert.data) return 'lostSectors'
13+
if (alert.data && 'hosts' in alert.data) return 'stuckHosts'
14+
return 'unknown'
15+
}
16+
17+
function getAlertData(
18+
type: AlertType,
19+
data: Alert['data']
20+
): AlertDataLostSectors | AlertDataStuckHosts | AlertDataUnknown | undefined {
21+
if (!data) return undefined
22+
if (type === 'lostSectors') {
23+
return {
24+
type: 'lostSectors',
25+
hostKeys: data.hostKeys as string[],
26+
hint: data.hint as string,
27+
}
28+
}
29+
if (type === 'stuckHosts') {
30+
return {
31+
type: 'stuckHosts',
32+
hosts: data.hosts as StuckHost[],
33+
hint: data.hint as string,
34+
}
35+
}
36+
return { type: 'unknown', ...data }
37+
}
338

439
export function transformAlert(alert: Alert): AlertData {
5-
const type =
6-
alert.data && 'hostKeys' in alert.data ? 'lostSectors' : 'unknown'
7-
const data =
8-
type === 'lostSectors'
9-
? ({
10-
type: 'lostSectors',
11-
hostKeys: alert.data?.hostKeys as string[],
12-
hint: alert.data?.hint as string,
13-
} as AlertDataLostSectors)
14-
: ({ type: 'unknown', ...alert.data } as AlertDataUnknown)
40+
const type = getAlertType(alert)
41+
const data = getAlertData(type, alert.data)
1542

1643
const datum: AlertData = {
1744
id: alert.id,

apps/indexd/components/Data/Alerts/types.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
11
import { AlertSeverity } from '@siafoundation/indexd-types'
22

3-
export type AlertType = 'lostSectors' | 'unknown'
3+
export type AlertType = 'lostSectors' | 'stuckHosts' | 'unknown'
44

55
export type AlertDataLostSectors = {
66
type: 'lostSectors'
77
hostKeys: string[]
88
hint: string
99
}
1010

11+
export type StuckHost = {
12+
publicKey: string
13+
stuckSince: string
14+
unpinnedSectors: number
15+
}
16+
17+
export type AlertDataStuckHosts = {
18+
type: 'stuckHosts'
19+
hosts: StuckHost[]
20+
hint: string
21+
}
22+
1123
export type AlertDataUnknown = {
1224
type: 'unknown'
1325
[key: string]: unknown
@@ -18,7 +30,7 @@ export type AlertData = {
1830
severity: AlertSeverity
1931
message: string
2032
type: AlertType
21-
data?: AlertDataLostSectors | AlertDataUnknown
33+
data?: AlertDataLostSectors | AlertDataStuckHosts | AlertDataUnknown
2234
timestamp: string
2335
displayFields: {
2436
timestamp: string

apps/indexd/components/Data/Alerts/utils.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,8 @@ export function getAlertTypeLabel(alert: AlertData) {
44
if (alert.data?.type === 'lostSectors') {
55
return 'Lost sectors'
66
}
7+
if (alert.data?.type === 'stuckHosts') {
8+
return 'Stuck hosts'
9+
}
710
return 'Unknown'
811
}

0 commit comments

Comments
 (0)