-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Add Disk Space Checker #35964
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
base: master
Are you sure you want to change the base?
Add Disk Space Checker #35964
Conversation
This is due to a `FileInfo` class existing in both `System.IO` and `osu.Game.IO`. I decided to go with this, but I can remove this and reference the namespace during the only `FileInfo` usage in the file, or remove the `osu.Game.IO` import and specify `osu.Game.IO` when calling `DiskUsage` Could also just move the `DiskUsage` class outside of `osu.Game.IO` to wherever it fits better. Let me know if an alternative solution to this commit is preferred.
osu.Game/IO/DiskUsage.cs
Outdated
| public static async Task EnsureSufficientSpaceAsync(string checkDirectory, long requiredSpace = required_space_default) | ||
| { | ||
| await Task.Run(() => EnsureSufficientSpace(checkDirectory, requiredSpace)).ConfigureAwait(false); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be worried about usages of this in something like an import operation firing far too many checks.
Also I think you can make this return the task directly rather than adding an extra async layer:
| public static async Task EnsureSufficientSpaceAsync(string checkDirectory, long requiredSpace = required_space_default) | |
| { | |
| await Task.Run(() => EnsureSufficientSpace(checkDirectory, requiredSpace)).ConfigureAwait(false); | |
| } | |
| public static Task EnsureSufficientSpaceAsync(string checkDirectory, long requiredSpace = required_space_default) | |
| { | |
| return Task.Run(() => EnsureSufficientSpace(checkDirectory, requiredSpace)); | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've applied your suggestion in c641f0a
I did originally consider adding debouncing logic here. My original idea was to add a DateTime as a property of DiskUsage, storing DateTime.Now in it whenever EnsureSufficientSpace is called, and silently return in said method if it hasn't yet been 5 minutes since the last call.
I decided to leave that out of this PR as the async wrapper is mostly just future-proofing, and this logic could be added in the future if the async wrapper does ever end up being used in real-time contexts. But I can see the confusion in supplying this method, but not going the full mile and specializing it for its intended purpose 😅
I can probably just remove the async wrapper altogether if we decide to stick with the "only on startup" approach. The actual overhead of checking disk space isn't really high, but it can get bad if done in a loop.
Co-authored-by: Dean Herbert <[email protected]>
osu.Game/IO/DiskUsage.cs
Outdated
| if (!Directory.Exists(checkPath)) | ||
| throw new DirectoryNotFoundException($"The directory '{checkPath}' does not exist or could not be found."); | ||
|
|
||
| string? validPathRoot = Path.GetPathRoot(checkPath); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm reading the documentation correctly, this will basically always return "/" on non-Windows, making this code invalid if osu! is on an external disk. Have you checked that this correctly reports the free size when querying directories on external disks on macOS?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have not, thanks for catching that. Should be fixed in fb73dec
Using GetPathRoot() does always return "/". Fortunately, my main use for that method was simply to check if the provided path is valid, so changing it to GetFullPath() properly provides the correct disk space while still checking path validity.
Here's a test on my Linux PC, having switched to GetFullPath(), testing for "/" and my HDD:
Which is roughly consistent with what my OS reports for my hard drive:
Note: The reason for the large difference here is that the logger reports the available space in MiB, while duf reports in GB. Convert the 385,103 MiB to GB and you get 403GB, which is exactly what my OS reports.
The reason for that second discrepancy (376GB vs 403GB), is due to the fact that duf reports btrfs's actual free space including metadata usage, while DiskInfo just checks whatever my OS returns. The available space for my HDD is reported as 403GB in nautilus, so everything here is accurate and working as intended, just confusing due to linux shenanigans.
dunno why the previous commit wasnt properly capitalized
Closes #5997
Introduction
This PR adds a static
DiskUsageclass toosu.Game/IOwith a method to natively determine available disk space given a path to a file or directory, providing a safeguard against running out of space during gameplay.Implementation & Notes
DriveInfofor system-level disk usage checking.EnsureSufficientSpaceAsync, has been implemented to allow for disk space checks in future IO-bound scenarios without blocking the calling thread.RealmAccess, I had to addusing FileInfo = System.IO.FileInfo;due to aFileInfoclass existing in bothSystem.IOandosu.Game.IO. Read the commit for details on that.osu-frameworkif preferredOverall, this is a simple solution to the linked issue, adding roughly 62 LOC excluding tests. I plan to submit smaller PRs (excl. haptics) going forwards to reduce burden on the core team with my contributions.