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:
parent
fae32b3901
commit
02b376d962
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user