From a98aac3bf2bbd0e03c46f4fb5eea7182e7b53d47 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 28 Mar 2022 17:33:15 +0900 Subject: [PATCH 1/4] Better inform users of migration failure reason when running Apply Silicon build As mentioned in https://github.com/ppy/osu/discussions/17409#discussioncomment-2445464? --- osu.Game/Database/EFToRealmMigrator.cs | 34 ++++++++++++++++++++------ 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/osu.Game/Database/EFToRealmMigrator.cs b/osu.Game/Database/EFToRealmMigrator.cs index cbf5c5ffe9..d3f7c561d5 100644 --- a/osu.Game/Database/EFToRealmMigrator.cs +++ b/osu.Game/Database/EFToRealmMigrator.cs @@ -1,6 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +#nullable enable + +using System; using System.IO; using System.Linq; using System.Threading.Tasks; @@ -14,6 +17,7 @@ using osu.Framework.Platform; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Models; @@ -29,8 +33,6 @@ using SharpCompress.Archives.Zip; using SharpCompress.Common; using SharpCompress.Writers.Zip; -#nullable enable - namespace osu.Game.Database { internal class EFToRealmMigrator : CompositeDrawable @@ -57,7 +59,7 @@ namespace osu.Game.Database [Resolved] private Storage storage { get; set; } = null!; - private readonly OsuSpriteText currentOperationText; + private readonly OsuTextFlowContainer currentOperationText; public EFToRealmMigrator() { @@ -99,11 +101,13 @@ namespace osu.Game.Database { State = { Value = Visibility.Visible } }, - currentOperationText = new OsuSpriteText + currentOperationText = new OsuTextFlowContainer(cp => cp.Font = OsuFont.Default.With(size: 30)) { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Font = OsuFont.Default.With(size: 30) + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + TextAnchor = Anchor.TopCentre, }, } }, @@ -147,19 +151,33 @@ namespace osu.Game.Database log("Migration successful!"); if (DebugUtils.IsDebugBuild) - Logger.Log("Your development database has been fully migrated to realm. If you switch back to a pre-realm branch and need your previous database, rename the backup file back to \"client.db\".\n\nNote that doing this can potentially leave your file store in a bad state.", level: LogLevel.Important); + { + Logger.Log( + "Your development database has been fully migrated to realm. If you switch back to a pre-realm branch and need your previous database, rename the backup file back to \"client.db\".\n\nNote that doing this can potentially leave your file store in a bad state.", + level: LogLevel.Important); + } } else { log("Migration failed!"); Logger.Log(t.Exception.ToString(), LoggingTarget.Database); + if (t.Exception.Flatten().InnerException is TypeInitializationException) + { + // Not guaranteed to be the only cause of exception, but let's roll with it for now. + log("Please download and run the intel version of osu! once\nto allow data migration to complete!"); + return; + } + notificationOverlay.Post(new SimpleErrorNotification { - Text = "IMPORTANT: During data migration, some of your data could not be successfully migrated. The previous version has been backed up.\n\nFor further assistance, please open a discussion on github and attach your backup files (click to get started).", + Text = + "IMPORTANT: During data migration, some of your data could not be successfully migrated. The previous version has been backed up.\n\nFor further assistance, please open a discussion on github and attach your backup files (click to get started).", Activated = () => { - game.OpenUrlExternally($@"https://github.com/ppy/osu/discussions/new?title=Realm%20migration%20issue ({t.Exception.Message})&body=Please%20drag%20the%20""attach_me.zip""%20file%20here!&category=q-a", true); + game.OpenUrlExternally( + $@"https://github.com/ppy/osu/discussions/new?title=Realm%20migration%20issue ({t.Exception.Message})&body=Please%20drag%20the%20""attach_me.zip""%20file%20here!&category=q-a", + true); const string attachment_filename = "attach_me.zip"; const string backup_folder = "backups"; From b6ae0ebb6f9ec7b561659d67327971e1a484ff87 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 28 Mar 2022 23:46:04 +0900 Subject: [PATCH 2/4] Limit macOS specific log output to macOS platforms specifically --- osu.Game/Database/EFToRealmMigrator.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Database/EFToRealmMigrator.cs b/osu.Game/Database/EFToRealmMigrator.cs index d3f7c561d5..d6460bc9d3 100644 --- a/osu.Game/Database/EFToRealmMigrator.cs +++ b/osu.Game/Database/EFToRealmMigrator.cs @@ -8,6 +8,7 @@ using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; +using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Development; using osu.Framework.Graphics; @@ -162,7 +163,7 @@ namespace osu.Game.Database log("Migration failed!"); Logger.Log(t.Exception.ToString(), LoggingTarget.Database); - if (t.Exception.Flatten().InnerException is TypeInitializationException) + if (RuntimeInfo.OS == RuntimeInfo.Platform.macOS && t.Exception.Flatten().InnerException is TypeInitializationException) { // Not guaranteed to be the only cause of exception, but let's roll with it for now. log("Please download and run the intel version of osu! once\nto allow data migration to complete!"); From ea46e024c1f883fb73d655010fe69853e9bfa22e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 28 Mar 2022 23:59:11 +0900 Subject: [PATCH 3/4] Avoid deadlock during migration failed exit process --- osu.Game/Database/EFToRealmMigrator.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Database/EFToRealmMigrator.cs b/osu.Game/Database/EFToRealmMigrator.cs index d6460bc9d3..ae73e13b77 100644 --- a/osu.Game/Database/EFToRealmMigrator.cs +++ b/osu.Game/Database/EFToRealmMigrator.cs @@ -167,6 +167,7 @@ namespace osu.Game.Database { // Not guaranteed to be the only cause of exception, but let's roll with it for now. log("Please download and run the intel version of osu! once\nto allow data migration to complete!"); + efContextFactory.SetMigrationCompletion(); return; } From 0433d2fe6a120f3b28140d24ae0026c34d7a4e91 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 29 Mar 2022 11:40:58 +0900 Subject: [PATCH 4/4] Add safety to realm instance retrieval in `RealmAccess` --- osu.Game/Database/RealmAccess.cs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/osu.Game/Database/RealmAccess.cs b/osu.Game/Database/RealmAccess.cs index 8574002436..8dbb338980 100644 --- a/osu.Game/Database/RealmAccess.cs +++ b/osu.Game/Database/RealmAccess.cs @@ -13,6 +13,7 @@ using System.Linq.Expressions; using System.Reflection; using System.Threading; using System.Threading.Tasks; +using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Development; using osu.Framework.Input.Bindings; @@ -293,7 +294,18 @@ namespace osu.Game.Database /// Compact this realm. /// /// - public bool Compact() => Realm.Compact(getConfiguration()); + public bool Compact() + { + try + { + return Realm.Compact(getConfiguration()); + } + // Catch can be removed along with entity framework. Is specifically to allow a failure message to arrive to the user (see similar catches in EFToRealmMigrator). + catch (AggregateException ae) when (RuntimeInfo.OS == RuntimeInfo.Platform.macOS && ae.Flatten().InnerException is TypeInitializationException) + { + return true; + } + } /// /// Run work on realm with a return value. @@ -542,6 +554,11 @@ namespace osu.Game.Database return Realm.GetInstance(getConfiguration()); } + // Catch can be removed along with entity framework. Is specifically to allow a failure message to arrive to the user (see similar catches in EFToRealmMigrator). + catch (AggregateException ae) when (RuntimeInfo.OS == RuntimeInfo.Platform.macOS && ae.Flatten().InnerException is TypeInitializationException) + { + return Realm.GetInstance(); + } finally { if (tookSemaphoreLock)