Skip to content

Commit

Permalink
fix: renterd memory leak, abort uploads, inline progress
Browse files Browse the repository at this point in the history
  • Loading branch information
alexfreska committed Mar 2, 2024
1 parent dc2f51d commit 5477362
Show file tree
Hide file tree
Showing 13 changed files with 252 additions and 130 deletions.
5 changes: 5 additions & 0 deletions .changeset/few-chefs-love.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'renterd': minor
---

Directory and global file explorers now show upload progress inline.
5 changes: 5 additions & 0 deletions .changeset/large-crews-play.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'renterd': patch
---

Fixed a slow memory leak that became especially apparent during long running large uploads, memory usage is now minimal and stable over time.
5 changes: 5 additions & 0 deletions .changeset/rich-lemons-speak.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'renterd': minor
---

Uploads now support aborting the entire visible page of active uploads.
6 changes: 4 additions & 2 deletions apps/renterd/components/Uploads/UploadsStatsMenu/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { PaginatorMarker } from '@siafoundation/design-system'
import { Button, PaginatorMarker } from '@siafoundation/design-system'
import { useUploads } from '../../../contexts/uploads'

export function UploadsStatsMenu() {
const { limit, pageCount, dataState, nextMarker, hasMore } = useUploads()
const { abortAll, limit, pageCount, dataState, nextMarker, hasMore } =
useUploads()
return (
<div className="flex gap-3 w-full">
<div className="flex-1" />
{pageCount > 0 && <Button onClick={abortAll}>Abort ({pageCount})</Button>}
<PaginatorMarker
marker={nextMarker}
isMore={hasMore}
Expand Down
34 changes: 22 additions & 12 deletions apps/renterd/contexts/filesDirectory/columns.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
import {
Button,
LoadingDots,
Text,
Tooltip,
ValueNum,
} from '@siafoundation/design-system'
import { Button, Text, Tooltip, ValueNum } from '@siafoundation/design-system'
import {
Document16,
Earth16,
FolderIcon,
Locked16,
Upload16,
} from '@siafoundation/react-icons'
import { humanBytes } from '@siafoundation/units'
import { FileContextMenu } from '../../components/Files/FileContextMenu'
Expand Down Expand Up @@ -158,13 +153,10 @@ export const columns: FilesTableColumn[] = [
id: 'size',
label: 'size',
contentClassName: 'justify-end',
render: function SizeColumn({ data: { type, name, size, isUploading } }) {
render: function SizeColumn({ data: { type, name, size } }) {
if (type === 'bucket') {
return null
}
if (isUploading) {
return <LoadingDots />
}

if (name === '..') {
return null
Expand All @@ -187,9 +179,27 @@ export const columns: FilesTableColumn[] = [
label: 'health',
contentClassName: 'justify-center',
render: function HealthColumn({ data }) {
if (data.type === 'bucket') {
const { type, isUploading, loaded, size } = data
if (type === 'bucket') {
return null
}
if (isUploading) {
const displayPercent = ((loaded / size) * 100).toFixed(0) + '%'
return (
<Tooltip
content={`Uploaded ${humanBytes(loaded)}/${humanBytes(size)}`}
>
<div className="flex items-center gap-1 cursor-pointer">
<Text color="subtle">
<Upload16 className="scale-75" />
</Text>
<Text color="subtle" size="12">
{displayPercent}
</Text>
</div>
</Tooltip>
)
}
return <FilesHealthColumn {...data} />
},
},
Expand Down
12 changes: 9 additions & 3 deletions apps/renterd/contexts/filesDirectory/dataset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,17 @@ export function useDataset() {
},
})

const d = useDatasetGeneric({
objects: {
const objects = useMemo(
() => ({
isValidating: response.isValidating,
data: response.data?.entries,
},
}),
[response.isValidating, response.data?.entries]
)

const d = useDatasetGeneric({
id: 'filesDirectory',
objects,
})

return {
Expand Down
38 changes: 26 additions & 12 deletions apps/renterd/contexts/filesFlat/columns.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { Button, Text, Tooltip, ValueNum } from '@siafoundation/design-system'
import {
Button,
LoadingDots,
Text,
Tooltip,
ValueNum,
} from '@siafoundation/design-system'
import { Document16, Earth16, Locked16 } from '@siafoundation/react-icons'
Document16,
Earth16,
Locked16,
Upload16,
} from '@siafoundation/react-icons'
import { humanBytes } from '@siafoundation/units'
import { FileContextMenu } from '../../components/Files/FileContextMenu'
import { DirectoryContextMenu } from '../../components/Files/DirectoryContextMenu'
Expand Down Expand Up @@ -126,13 +125,10 @@ export const columns: FilesTableColumn[] = [
id: 'size',
label: 'size',
contentClassName: 'justify-end',
render: function SizeColumn({ data: { type, name, size, isUploading } }) {
render: function SizeColumn({ data: { type, name, size } }) {
if (type === 'bucket') {
return null
}
if (isUploading) {
return <LoadingDots />
}

if (name === '..') {
return null
Expand All @@ -155,9 +151,27 @@ export const columns: FilesTableColumn[] = [
label: 'health',
contentClassName: 'justify-center',
render: function HealthColumn({ data }) {
if (data.type === 'bucket') {
const { type, isUploading, loaded, size } = data
if (type === 'bucket') {
return null
}
if (isUploading) {
const displayPercent = ((loaded / size) * 100).toFixed(0) + '%'
return (
<Tooltip
content={`Uploaded ${humanBytes(loaded)}/${humanBytes(size)}`}
>
<div className="flex items-center gap-1 cursor-pointer">
<Text color="subtle">
<Upload16 className="scale-75" />
</Text>
<Text color="subtle" size="12">
{displayPercent}
</Text>
</div>
</Tooltip>
)
}
return <FilesHealthColumn {...data} />
},
},
Expand Down
12 changes: 9 additions & 3 deletions apps/renterd/contexts/filesFlat/dataset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,17 @@ export function useDataset({ sortDirection, sortField }: Props) {
},
})

const d = useDatasetGeneric({
objects: {
const objects = useMemo(
() => ({
isValidating: response.isValidating,
data: response.data?.objects,
},
}),
[response.isValidating, response.data]
)

const d = useDatasetGeneric({
id: 'filesFlat',
objects,
})

return {
Expand Down
23 changes: 12 additions & 11 deletions apps/renterd/contexts/filesManager/dataset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,17 @@ import {
isDirectory,
} from '../../lib/paths'
import { useFilesManager } from '.'
import { useEffect } from 'react'

type Props = {
id: string
objects: {
isValidating: boolean
data?: ObjEntry[]
}
}

export function useDataset({ objects }: Props) {
export function useDataset({ id, objects }: Props) {
const {
activeBucket,
activeBucketName,
Expand All @@ -31,17 +33,10 @@ export function useDataset({ objects }: Props) {
setActiveDirectory,
} = useFilesManager()
const { dataset: allContracts } = useContracts()
return useSWR<ObjectData[] | null>(
const response = useSWR<ObjectData[] | null>(
objects.isValidating || buckets.isValidating
? null
: [
objects.data,
uploadsList,
allContracts,
buckets.data,
activeBucketName,
activeDirectoryPath,
],
: [id, activeBucketName, activeDirectoryPath],
() => {
const dataMap: Record<string, ObjectData> = {}
if (!activeBucket) {
Expand All @@ -61,7 +56,7 @@ export function useDataset({ objects }: Props) {
type: 'bucket',
}
})
} else if (objects.data) {
} else if (objects.data || uploadsList.length) {
objects.data?.forEach(({ name: key, size, health }) => {
const path = join(activeBucketName, key)
const name = getFilename(key)
Expand Down Expand Up @@ -102,4 +97,10 @@ export function useDataset({ objects }: Props) {
keepPreviousData: true,
}
)
// refetch when the dependent data changes
useEffect(() => {
response.mutate()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [objects.data, uploadsList, allContracts, buckets.data])
return response
}
Loading

0 comments on commit 5477362

Please sign in to comment.