1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-14 03:22:54 +08:00

Fix rollback logic not necessrily cleaning up file store

This commit is contained in:
Dean Herbert 2019-06-10 16:14:42 +09:00
parent fae32b3901
commit 02b376d962

View File

@ -154,26 +154,23 @@ namespace osu.Game.Database
await Task.WhenAll(paths.Select(path => Import(path, notification.CancellationToken).ContinueWith(t => await Task.WhenAll(paths.Select(path => Import(path, notification.CancellationToken).ContinueWith(t =>
{ {
if (notification.CancellationToken.IsCancellationRequested) notification.CancellationToken.ThrowIfCancellationRequested();
return;
lock (notification) lock (imported)
{ {
current++; Interlocked.Increment(ref current);
notification.Text = $"Imported {current} of {paths.Length} {term}s";
notification.Progress = (float)current / paths.Length;
}
if (t.Exception == null) if (t.Exception == null)
{ {
lock (imported)
imported.Add(t.Result); imported.Add(t.Result);
notification.Text = $"Imported {current} of {paths.Length} {term}s";
notification.Progress = (float)current / paths.Length;
} }
else else
{ {
Logger.Error(t.Exception, $@"Could not import ({Path.GetFileName(path)})"); Logger.Error(t.Exception, $@"Could not import ({Path.GetFileName(path)})");
} }
}
}, TaskContinuationOptions.NotOnCanceled))); }, TaskContinuationOptions.NotOnCanceled)));
if (imported.Count == 0) if (imported.Count == 0)
@ -300,23 +297,23 @@ namespace osu.Game.Database
delayEvents(); delayEvents();
void rollback()
{
if (!Delete(item))
{
// We may have not yet added the model to the underlying table, but should still clean up files.
Logger.Log($"Dereferencing files for incomplete import of {item}.", LoggingTarget.Database);
Files.Dereference(item.Files.Select(f => f.FileInfo).ToArray());
}
}
try try
{ {
Logger.Log($"Importing {item}...", LoggingTarget.Database); Logger.Log($"Importing {item}...", LoggingTarget.Database);
item.Files = archive != null ? createFileInfos(archive, Files) : new List<TFileModel>(); item.Files = archive != null ? createFileInfos(archive, Files) : new List<TFileModel>();
var localItem = item;
try
{
await Populate(item, archive, cancellationToken); await Populate(item, archive, cancellationToken);
}
catch (Exception)
{
if (!Delete(localItem))
Files.Dereference(localItem.Files.Select(f => f.FileInfo).ToArray());
}
using (var write = ContextFactory.GetForWrite()) // used to share a context for full import. keep in mind this will block all writes. using (var write = ContextFactory.GetForWrite()) // used to share a context for full import. keep in mind this will block all writes.
{ {
@ -333,6 +330,8 @@ namespace osu.Game.Database
Undelete(existing); Undelete(existing);
Logger.Log($"Found existing {nameof(TModel)} for {item} (ID {existing.ID}). Skipping import.", LoggingTarget.Database); Logger.Log($"Found existing {nameof(TModel)} for {item} (ID {existing.ID}). Skipping import.", LoggingTarget.Database);
handleEvent(() => ItemAdded?.Invoke(existing, true)); handleEvent(() => ItemAdded?.Invoke(existing, true));
rollback();
return existing; return existing;
} }
else else
@ -349,9 +348,6 @@ namespace osu.Game.Database
} }
catch (Exception e) catch (Exception e)
{ {
if (!Delete(item))
Files.Dereference(item.Files.Select(f => f.FileInfo).ToArray());
write.Errors.Add(e); write.Errors.Add(e);
throw; throw;
} }
@ -359,13 +355,12 @@ namespace osu.Game.Database
Logger.Log($"Import of {item} successfully completed!", LoggingTarget.Database); Logger.Log($"Import of {item} successfully completed!", LoggingTarget.Database);
} }
catch (TaskCanceledException)
{
throw;
}
catch (Exception e) catch (Exception e)
{ {
if (!(e is TaskCanceledException))
Logger.Error(e, $"Import of {item} failed and has been rolled back.", LoggingTarget.Database); Logger.Error(e, $"Import of {item} failed and has been rolled back.", LoggingTarget.Database);
rollback();
item = null; item = null;
} }
finally finally