mirror of
https://github.com/ppy/osu
synced 2025-01-11 16:49:39 +00:00
Reduce the scope of realm transactions during import operations
This commit is contained in:
parent
2ae41521eb
commit
390ff8b9da
@ -294,15 +294,38 @@ namespace osu.Game.Database
|
|||||||
// Log output here will be missing a valid hash in non-batch imports.
|
// Log output here will be missing a valid hash in non-batch imports.
|
||||||
LogForModel(item, $@"Beginning import from {archive?.Name ?? "unknown"}...");
|
LogForModel(item, $@"Beginning import from {archive?.Name ?? "unknown"}...");
|
||||||
|
|
||||||
|
List<RealmNamedFileUsage> files = new List<RealmNamedFileUsage>();
|
||||||
|
|
||||||
|
if (archive != null)
|
||||||
|
{
|
||||||
|
// Import files to the disk store.
|
||||||
|
// We intentionally delay adding to realm to avoid blocking on a write during disk operations.
|
||||||
|
foreach (var filenames in getShortenedFilenames(archive))
|
||||||
|
{
|
||||||
|
using (Stream s = archive.GetStream(filenames.original))
|
||||||
|
files.Add(new RealmNamedFileUsage(Files.Add(s, realm, false), filenames.shortened));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var transaction = realm.BeginWrite())
|
||||||
|
{
|
||||||
|
// Add all files to realm in one go.
|
||||||
|
// This is done ahead of the main transaction to ensure we can correctly cleanup the files, even if the import fails.
|
||||||
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
if (!file.File.IsManaged)
|
||||||
|
realm.Add(file.File, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction.Commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
item.Files.AddRange(files);
|
||||||
|
item.Hash = ComputeHash(item);
|
||||||
|
|
||||||
// TODO: do we want to make the transaction this local? not 100% sure, will need further investigation.
|
// TODO: do we want to make the transaction this local? not 100% sure, will need further investigation.
|
||||||
using (var transaction = realm.BeginWrite())
|
using (var transaction = realm.BeginWrite())
|
||||||
{
|
{
|
||||||
if (archive != null)
|
|
||||||
// TODO: look into rollback of file additions (or delayed commit).
|
|
||||||
item.Files.AddRange(createFileInfos(archive, Files, realm));
|
|
||||||
|
|
||||||
item.Hash = ComputeHash(item);
|
|
||||||
|
|
||||||
// TODO: we may want to run this outside of the transaction.
|
// TODO: we may want to run this outside of the transaction.
|
||||||
Populate(item, archive, realm, cancellationToken);
|
Populate(item, archive, realm, cancellationToken);
|
||||||
|
|
||||||
@ -425,16 +448,6 @@ namespace osu.Game.Database
|
|||||||
{
|
{
|
||||||
var fileInfos = new List<RealmNamedFileUsage>();
|
var fileInfos = new List<RealmNamedFileUsage>();
|
||||||
|
|
||||||
// import files to manager
|
|
||||||
foreach (var filenames in getShortenedFilenames(reader))
|
|
||||||
{
|
|
||||||
using (Stream s = reader.GetStream(filenames.original))
|
|
||||||
{
|
|
||||||
var item = new RealmNamedFileUsage(files.Add(s, realm), filenames.shortened);
|
|
||||||
fileInfos.Add(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return fileInfos;
|
return fileInfos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,8 +40,8 @@ namespace osu.Game.Database
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="data">The file data stream.</param>
|
/// <param name="data">The file data stream.</param>
|
||||||
/// <param name="realm">The realm instance to add to. Should already be in a transaction.</param>
|
/// <param name="realm">The realm instance to add to. Should already be in a transaction.</param>
|
||||||
/// <returns></returns>
|
/// <param name="addToRealm">Whether the <see cref="RealmFile"/> should immediately be added to the underlying realm. If <c>false</c> is provided here, the instance must be manually added.</param>
|
||||||
public RealmFile Add(Stream data, Realm realm)
|
public RealmFile Add(Stream data, Realm realm, bool addToRealm = true)
|
||||||
{
|
{
|
||||||
string hash = data.ComputeSHA2Hash();
|
string hash = data.ComputeSHA2Hash();
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ namespace osu.Game.Database
|
|||||||
if (!checkFileExistsAndMatchesHash(file))
|
if (!checkFileExistsAndMatchesHash(file))
|
||||||
copyToStore(file, data);
|
copyToStore(file, data);
|
||||||
|
|
||||||
if (!file.IsManaged)
|
if (addToRealm && !file.IsManaged)
|
||||||
realm.Add(file);
|
realm.Add(file);
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
|
Loading…
Reference in New Issue
Block a user