Fix baetmap downloads using too much memory

This commit is contained in:
Dean Herbert 2019-01-29 18:34:10 +09:00
parent 432bc60db6
commit baea9691cc
3 changed files with 37 additions and 26 deletions

View File

@ -163,18 +163,14 @@ public bool Download(BeatmapSetInfo beatmapSetInfo, bool noVideo = false)
downloadNotification.Progress = progress; downloadNotification.Progress = progress;
}; };
request.Success += data => request.Success += filename =>
{ {
downloadNotification.Text = $"Importing {beatmapSetInfo.Metadata.Artist} - {beatmapSetInfo.Metadata.Title}"; downloadNotification.Text = $"Importing {beatmapSetInfo.Metadata.Artist} - {beatmapSetInfo.Metadata.Title}";
Task.Factory.StartNew(() => Task.Factory.StartNew(() =>
{ {
BeatmapSetInfo importedBeatmap;
// This gets scheduled back to the update thread, but we want the import to run in the background. // This gets scheduled back to the update thread, but we want the import to run in the background.
using (var stream = new MemoryStream(data)) var importedBeatmap = Import(filename);
using (var archive = new ZipArchiveReader(stream, beatmapSetInfo.ToString()))
importedBeatmap = Import(archive);
downloadNotification.CompletionClickAction = () => downloadNotification.CompletionClickAction = () =>
{ {

View File

@ -150,25 +150,9 @@ public void Import(params string[] paths)
{ {
notification.Text = $"Importing ({++current} of {paths.Length})\n{Path.GetFileName(path)}"; notification.Text = $"Importing ({++current} of {paths.Length})\n{Path.GetFileName(path)}";
TModel import; imported.Add(Import(path));
using (ArchiveReader reader = getReaderFrom(path))
imported.Add(import = Import(reader));
notification.Progress = (float)current / paths.Length; notification.Progress = (float)current / paths.Length;
// We may or may not want to delete the file depending on where it is stored.
// e.g. reconstructing/repairing database with items from default storage.
// Also, not always a single file, i.e. for LegacyFilesystemReader
// TODO: Add a check to prevent files from storage to be deleted.
try
{
if (import != null && File.Exists(path))
File.Delete(path);
}
catch (Exception e)
{
Logger.Error(e, $@"Could not delete original file after import ({Path.GetFileName(path)})");
}
} }
catch (Exception e) catch (Exception e)
{ {
@ -195,6 +179,34 @@ public void Import(params string[] paths)
} }
} }
/// <summary>
/// Import one <see cref="TModel"/> from the filesystem and delete the file on success.
/// </summary>
/// <param name="paths">The archive location on disk.</param>
/// <returns>The imported model, if successful.</returns>
public TModel Import(string path)
{
TModel import;
using (ArchiveReader reader = getReaderFrom(path))
import = Import(reader);
// We may or may not want to delete the file depending on where it is stored.
// e.g. reconstructing/repairing database with items from default storage.
// Also, not always a single file, i.e. for LegacyFilesystemReader
// TODO: Add a check to prevent files from storage to be deleted.
try
{
if (import != null && File.Exists(path))
File.Delete(path);
}
catch (Exception e)
{
Logger.Error(e, $@"Could not delete original file after import ({Path.GetFileName(path)})");
}
return import;
}
protected virtual void PresentCompletedImport(IEnumerable<TModel> imported) protected virtual void PresentCompletedImport(IEnumerable<TModel> imported)
{ {
} }

View File

@ -1,15 +1,18 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System.IO;
using osu.Framework.IO.Network; using osu.Framework.IO.Network;
namespace osu.Game.Online.API namespace osu.Game.Online.API
{ {
public abstract class APIDownloadRequest : APIRequest public abstract class APIDownloadRequest : APIRequest
{ {
private string filename;
protected override WebRequest CreateWebRequest() protected override WebRequest CreateWebRequest()
{ {
var request = new WebRequest(Uri); var request = new FileWebRequest(filename = Path.GetTempFileName(), Uri);
request.DownloadProgress += request_Progress; request.DownloadProgress += request_Progress;
return request; return request;
} }
@ -23,11 +26,11 @@ protected APIDownloadRequest()
private void onSuccess() private void onSuccess()
{ {
Success?.Invoke(WebRequest.ResponseData); Success?.Invoke(filename);
} }
public event APIProgressHandler Progress; public event APIProgressHandler Progress;
public new event APISuccessHandler<byte[]> Success; public new event APISuccessHandler<string> Success;
} }
} }