Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add POC disk cleanup #117

Closed
wants to merge 1 commit into from
Closed

Conversation

isZumpo
Copy link
Contributor

@isZumpo isZumpo commented Apr 9, 2024

No description provided.

Copy link
Contributor

coderabbitai bot commented Apr 9, 2024

Walkthrough

The recent update introduces a disk cleanup mechanism within the analysis processor. This addition is designed to monitor disk usage and automatically clear out files once certain thresholds are reached. It's a smart move towards ensuring the system remains efficient and avoids running out of storage space unexpectedly. The update encompasses both the implementation of the cleanup functionality and its testing.

Changes

File Path Change Summary
.../processor/actions.go Added disk cleanup functionality including usage calculation and file removal.
.../processor/actions_test.go Introduced tests for the new disk cleanup mechanism.

🐇✨
In the land of code and byte,
Where disks do fill up in the night,
A clever rabbit hopped in sight,
With cleanup code, made storage light.
🌟📁✨
"Fear not," it said, "for I'll ensure,
Your space is free, forevermore."


Recent Review Status

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 5f26da1 and a22d719.
Files ignored due to path filters (2)
  • go.mod is excluded by !**/*.mod
  • go.sum is excluded by !**/*.sum
Files selected for processing (2)
  • internal/analysis/processor/actions.go (3 hunks)
  • internal/analysis/processor/actions_test.go (1 hunks)
Additional Context Used
GitHub Check Runs (1)
lint failure (3)

internal/analysis/processor/actions.go: [failure] 213-213:
Error return value of a.DiskCleanUp is not checked (errcheck)


internal/analysis/processor/actions_test.go: [failure] 5-5:
SA1019: "io/ioutil" has been deprecated since Go 1.19: As of Go 1.16, the same functionality is now provided by package [io] or package [os], and those implementations should be preferred in new code. See the specific function documentation for details. (staticcheck)

Additional comments not posted (6)
internal/analysis/processor/actions_test.go (3)

27-53: Consider adding error handling for file creation and data writing in initData.

While the current implementation uses t.Fatalf to halt the test on errors, ensuring clean file closure and deletion in case of failures can prevent resource leaks during test execution.


69-106: Validate disk cleanup logic when disk is full.

The test TestDiskCleanUpFullDisk correctly sets up a scenario where the disk is full and validates the cleanup process. It properly calculates the expected number of files after cleanup based on the mock disk usage and asserts the outcome.


108-139: Ensure cleanup does not occur below threshold.

The test TestDiskCleanUpLessThanTreshold effectively verifies that no files are removed when the disk usage is below the specified threshold. This test ensures that the cleanup logic is correctly applied only when necessary.

internal/analysis/processor/actions.go (3)

91-95: Implement sorting interface for file modification times.

The ByModTime type and its methods correctly implement the sort.Interface, enabling sorting of files by modification time. This is essential for the disk cleanup logic to remove older files first.


97-100: Define disk usage calculation interface.

The DiskUsageCalculator interface is well-defined, encapsulating the necessary methods for calculating disk usage. This abstraction allows for easy testing and future extensions.


102-111: Utilize actual disk usage for cleanup calculations.

The RealDiskUsage type correctly implements the DiskUsageCalculator interface using the go-disk-usage library. This provides accurate disk usage metrics for the cleanup process.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share

Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@isZumpo isZumpo closed this Apr 9, 2024
@isZumpo isZumpo deleted the disk_cleanup_poc branch April 9, 2024 19:35
@isZumpo
Copy link
Contributor Author

isZumpo commented Apr 9, 2024

Sorry.... Was going to push a pr to my own fork such that I did not forget about the branch...

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4


import (
"fmt"
"io/ioutil"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace deprecated ioutil package with os or io package.

- import "io/ioutil"
+ import "os"

And update ioutil.ReadDir(filePath) to os.ReadDir(filePath) in the countFiles function.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
"io/ioutil"
import "os"

}
}

// TODO add a test that expects an error if too many files have to be removed at once.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add missing test case for error handling.

It's important to cover scenarios where errors are expected, such as when too many files need to be removed. Would you like assistance in implementing this test case?

Comment on lines +118 to +189
func (a DatabaseAction) DiskCleanUp(calculator DiskUsageCalculator) error {
basePath := conf.GetBasePath(a.Settings.Realtime.AudioExport.Path)

const cleanupThreshold = 0.9 // Example threshold for disk cleanup (90% usage)

// Calculate bytesToRemove based on available disk space and cleanup threshold
diskUsed, err := calculator.Used(basePath)
if err != nil {
return err
}

diskSize, err := calculator.Size(basePath)
if err != nil {
return err
}
bytesToRemove := int64(diskUsed) - int64(float64(diskSize)*cleanupThreshold)

// Only cleanup if required (positive bytes to remove)
if bytesToRemove < 0 {
return nil
}

log.Printf("Reached disk usage treshold of %f percent. Will try to remove: %d bytes of files.\n", cleanupThreshold*100, bytesToRemove)

var files []os.FileInfo
var totalSize int64

errr := filepath.Walk(basePath,
func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
// Check if the file is a regular file
if info.Mode().IsRegular() {
files = append(files, info)
totalSize += info.Size() // Accumulate file sizes
}
return nil
})
if errr != nil {
log.Println(errr)
return err
}

// Sort files by modification time
sort.Sort(ByModTime(files))

// Check if it's possible to remove X bytes
if totalSize < bytesToRemove {
return fmt.Errorf("failed to remove %d bytes: insufficient files to meet the target size", bytesToRemove)
}

// Remove files until total size exceeds or equals bytesToRemove
var removedSize int64
for i := 0; i < len(files) && removedSize < bytesToRemove; i++ {
err := os.Remove(filepath.Join(basePath, files[i].Name()))
if err != nil {
log.Printf("Error removing file %s: %v\n", files[i].Name(), err)
} else {
removedSize += files[i].Size() // Update removedSize after removal
log.Printf("File %s (%d bytes) removed successfully. %d bytes remaning to remove.\n", files[i].Name(), files[i].Size(), max(bytesToRemove-removedSize, 0))
}
}

// Perform a check afterward again. It could be the case that because of removal errors,
// it is still not possible to remove enough files to reach the threshold
if removedSize < bytesToRemove {
return fmt.Errorf("only managed to remove %d bytes: insufficient files to meet the target size %d", removedSize, bytesToRemove)
}

return nil
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refine disk cleanup logic for better error handling and efficiency.

The disk cleanup logic in DiskCleanUp method is comprehensive but can be refined for better error handling and efficiency. Consider the following improvements:

  • Use filepath.WalkDir instead of filepath.Walk for better performance in Go 1.16 and later.
  • Directly return the error from filepath.WalkDir instead of logging and returning a different error.
  • Accumulate errors during file removal to attempt removing as many files as possible before returning an error.

@@ -105,6 +209,9 @@
if a.Settings.Realtime.AudioExport.Enabled {
time.Sleep(1 * time.Second) // Sleep for 1 second to allow the audio buffer to fill
pcmData, _ := a.AudioBuffer.ReadSegment(a.Note.BeginTime, time.Now())

a.DiskCleanUp(RealDiskUsage{})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check error return value of DiskCleanUp.

- a.DiskCleanUp(RealDiskUsage{})
+ if err := a.DiskCleanUp(RealDiskUsage{}); err != nil {
+     log.Printf("Disk cleanup failed: %v", err)
+ }

It's important to handle the error returned by DiskCleanUp to ensure that any issues during the cleanup process are properly logged or addressed.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
a.DiskCleanUp(RealDiskUsage{})
if err := a.DiskCleanUp(RealDiskUsage{}); err != nil {
log.Printf("Disk cleanup failed: %v", err)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant