ppy / osu

rhythm is just a *click* away!
https://osu.ppy.sh
MIT License
15.5k stars 2.3k forks source link

Consider hard disk drive space availability and early-warn user on low disk space #5997

Open l3lackShark opened 5 years ago

l3lackShark commented 5 years ago

The game just did nothing after completing a map, holding Esc resulted in a transition to SongSelect osu!lazer version: 2019.903.0

Logs: runtime.log

3037?

peppy commented 5 years ago

Looks to be database related. Can you reproduce?

l3lackShark commented 5 years ago

I don't think I can.. I will record everything from now on and try to catch some luck.

l3lackShark commented 5 years ago

Alright, I think I figured out the cause. Or actually this might be a separate issue that leads to the same outcome. It looks like full hard drive triggers this database.log This time runtime log was empty... Needs a further investigation. https://www.youtube.com/watch?v=78eYWTogfRg

l3lackShark commented 5 years ago

Ah yes, If there is no disk space then the logs just can't write themselves... So full hard drive is the cause of the issue.

smallketchup82 commented 3 months ago

This has been on my todo list for a while, and I might begin some work on it. I've backread the thread, but don't see any reasoning in particular that would make this an osu!framework specific issue, so I'm going to place my sights on implementing this osu! side.

I believe the best solution to this issue is to query DriveInfo.AvailableFreeSpace and check if the amount of free space is less than 5% of the total drive capacity. This check can be done in both BeatmapImporter, when importing a new map. And during startup, to warn the user that things like this (where realm can't write) could occur.

I don't see much that could be done here in regards to fault tolerance (since a full drive is a full drive), the only thing we really can do is give the user warnings to reduce the chance of getting into this predicament in the first place.

peppy commented 3 months ago

Relevant stable implementation

        private static bool ensureFreeSpace()
        {
            const ulong requiredBytes = 1024 * 1024 * 128;
            ulong systemBytesAvailable, totalBytes, bytesAvailable;

            Native.GetDiskFreeSpaceEx(Environment.CurrentDirectory, out bytesAvailable, out totalBytes, out systemBytesAvailable);
            if (bytesAvailable < requiredBytes)
            {
                //make sure we have at least 128mb free.
                NotificationManager.ShowMessage(LocalisationManager.GetString(OsuString.DatabaseHelper_LowDiskSpace), Color.Red, 60000);
                return false;
            }

            return true;
        }

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetDiskFreeSpaceEx(string lpDirectoryName, out ulong lpFreeBytesAvailable, out ulong lpTotalNumberOfBytes, out ulong lpTotalNumberOfFreeBytes);

This was called before operations which would require disk space.

But of course if you can make a native solution work it will be preferred.