diff --git a/osu.Game/Database/EFToRealmMigrator.cs b/osu.Game/Database/EFToRealmMigrator.cs index 4e98b7d3d2..d2f52fa635 100644 --- a/osu.Game/Database/EFToRealmMigrator.cs +++ b/osu.Game/Database/EFToRealmMigrator.cs @@ -123,8 +123,18 @@ namespace osu.Game.Database private void beginMigration() { + const string backup_folder = "backups"; + + string backupSuffix = $"before_final_migration_{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}"; + + // required for initial backup. + var realmBlockOperations = realm.BlockAllOperations(); + Task.Factory.StartNew(() => { + realm.CreateBackup(Path.Combine(backup_folder, $"client.{backupSuffix}.realm"), realmBlockOperations); + efContextFactory.CreateBackup(Path.Combine(backup_folder, $"client.{backupSuffix}.db")); + using (var ef = efContextFactory.Get()) { realm.Write(r => @@ -182,7 +192,6 @@ namespace osu.Game.Database true); const string attachment_filename = "attach_me.zip"; - const string backup_folder = "backups"; var backupStorage = storage.GetStorageForDirectory(backup_folder); @@ -209,6 +218,8 @@ namespace osu.Game.Database // If we were to not do this, the migration would run another time the next time the user starts the game. deletePreRealmData(); + realmBlockOperations.Dispose(); + migrationCompleted.SetResult(true); efContextFactory.SetMigrationCompletion(); }); diff --git a/osu.Game/Database/RealmAccess.cs b/osu.Game/Database/RealmAccess.cs index bd47920f82..b144b70574 100644 --- a/osu.Game/Database/RealmAccess.cs +++ b/osu.Game/Database/RealmAccess.cs @@ -750,9 +750,9 @@ namespace osu.Game.Database private string? getRulesetShortNameFromLegacyID(long rulesetId) => efContextFactory?.Get().RulesetInfo.FirstOrDefault(r => r.ID == rulesetId)?.ShortName; - public void CreateBackup(string backupFilename) + public void CreateBackup(string backupFilename, IDisposable? blockAllOperations = null) { - using (BlockAllOperations()) + using (blockAllOperations ?? BlockAllOperations()) { Logger.Log($"Creating full realm database backup at {backupFilename}", LoggingTarget.Database); diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 3f896ff52e..a4e6486c46 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -233,19 +233,6 @@ namespace osu.Game Decoder.RegisterDependencies(RulesetStore); - // Backup is taken here rather than in EFToRealmMigrator to avoid recycling realm contexts - // after initial usages below. It can be moved once a direction is established for handling re-subscription. - // See https://github.com/ppy/osu/pull/16547 for more discussion. - if (EFContextFactory != null) - { - const string backup_folder = "backups"; - - string migration = $"before_final_migration_{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}"; - - EFContextFactory.CreateBackup(Path.Combine(backup_folder, $"client.{migration}.db")); - realm.CreateBackup(Path.Combine(backup_folder, $"client.{migration}.realm")); - } - dependencies.CacheAs(Storage); var largeStore = new LargeTextureStore(Host.CreateTextureLoaderStore(new NamespacedResourceStore(Resources, @"Textures")));