From bc032aa0a6472a3ae0c77bfd4a5085ab96638ff9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Feb 2017 12:58:56 +0900 Subject: [PATCH 1/4] Catch http errors in full update process (could happen during downloads too). --- osu.Desktop/Overlays/VersionManager.cs | 50 +++++++++++++------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs index f33cd6eac2..388020dd27 100644 --- a/osu.Desktop/Overlays/VersionManager.cs +++ b/osu.Desktop/Overlays/VersionManager.cs @@ -119,33 +119,35 @@ namespace osu.Desktop.Overlays try { updateManager = await UpdateManager.GitHubUpdateManager(@"https://github.com/ppy/osu", @"osulazer", null, null, true); - } - catch(HttpRequestException) - { - //check again every 30 minutes. - Scheduler.AddDelayed(updateChecker, 60000 * 30); - return; - } - - if (!updateManager.IsInstalledApp) - return; - - var info = await updateManager.CheckForUpdate(); - if (info.ReleasesToApply.Count > 0) - { - ProgressNotification n = new UpdateProgressNotification + var info = await updateManager.CheckForUpdate(); + if (info.ReleasesToApply.Count > 0) { - Text = @"Downloading update..." - }; - Schedule(() => notification.Post(n)); - Schedule(() => n.State = ProgressNotificationState.Active); - await updateManager.DownloadReleases(info.ReleasesToApply, (int p) => Schedule(() => n.Progress = p / 100f)); - Schedule(() => n.Text = @"Installing update..."); - await updateManager.ApplyReleases(info, (int p) => Schedule(() => n.Progress = p / 100f)); - Schedule(() => n.State = ProgressNotificationState.Completed); + ProgressNotification n = new UpdateProgressNotification + { + Text = @"Downloading update..." + }; + Schedule(() => + { + notification.Post(n); + n.State = ProgressNotificationState.Active; + }); + await updateManager.DownloadReleases(info.ReleasesToApply, p => Schedule(() => n.Progress = p / 100f)); + Schedule(() => + { + n.Progress = 0; + n.Text = @"Installing update..."; + }); + await updateManager.ApplyReleases(info, p => Schedule(() => n.Progress = p / 100f)); + Schedule(() => n.State = ProgressNotificationState.Completed); + } + else + { + //check again every 30 minutes. + Scheduler.AddDelayed(updateChecker, 60000 * 30); + } } - else + catch (HttpRequestException) { //check again every 30 minutes. Scheduler.AddDelayed(updateChecker, 60000 * 30); From cbd061d5731c089e7b3042697607c25349d16328 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Feb 2017 13:52:30 +0900 Subject: [PATCH 2/4] Improve appearance of notifications. --- osu.Desktop/Overlays/VersionManager.cs | 20 +++++++++++++++++++ .../Overlays/Notifications/Notification.cs | 1 - .../ProgressCompletionNotification.cs | 10 ++++++++++ .../Notifications/SimpleNotification.cs | 8 +++++--- 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs index 388020dd27..c06b4cce10 100644 --- a/osu.Desktop/Overlays/VersionManager.cs +++ b/osu.Desktop/Overlays/VersionManager.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Overlays; @@ -174,6 +175,25 @@ namespace osu.Desktop.Overlays return true; } }; + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + IconContent.Add(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + ColourInfo = ColourInfo.GradientVertical(colours.YellowDark, colours.Yellow) + }, + new TextAwesome + { + Anchor = Anchor.Centre, + Icon = FontAwesome.fa_upload, + Colour = Color4.White, + } + }); + } } } } diff --git a/osu.Game/Overlays/Notifications/Notification.cs b/osu.Game/Overlays/Notifications/Notification.cs index 6faa79433e..6ad0fde419 100644 --- a/osu.Game/Overlays/Notifications/Notification.cs +++ b/osu.Game/Overlays/Notifications/Notification.cs @@ -89,7 +89,6 @@ namespace osu.Game.Overlays.Notifications IconContent = new Container { Size = new Vector2(40), - Colour = Color4.DarkGray, Masking = true, CornerRadius = 5, }, diff --git a/osu.Game/Overlays/Notifications/ProgressCompletionNotification.cs b/osu.Game/Overlays/Notifications/ProgressCompletionNotification.cs index a5ec9a3545..61525ed019 100644 --- a/osu.Game/Overlays/Notifications/ProgressCompletionNotification.cs +++ b/osu.Game/Overlays/Notifications/ProgressCompletionNotification.cs @@ -1,7 +1,11 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Allocation; using osu.Game.Graphics; +using osu.Framework.Graphics.Colour; +using OpenTK.Graphics; + namespace osu.Game.Overlays.Notifications { @@ -14,5 +18,11 @@ namespace osu.Game.Overlays.Notifications this.progressNotification = progressNotification; Icon = FontAwesome.fa_check; } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + IconBackgound.ColourInfo = ColourInfo.GradientVertical(colours.GreenDark, colours.GreenLight); + } } } \ No newline at end of file diff --git a/osu.Game/Overlays/Notifications/SimpleNotification.cs b/osu.Game/Overlays/Notifications/SimpleNotification.cs index 24f347eee3..c9c56e8d4a 100644 --- a/osu.Game/Overlays/Notifications/SimpleNotification.cs +++ b/osu.Game/Overlays/Notifications/SimpleNotification.cs @@ -37,19 +37,21 @@ namespace osu.Game.Overlays.Notifications private SpriteText textDrawable; private TextAwesome iconDrawable; + protected Box IconBackgound; + public SimpleNotification() { IconContent.Add(new Drawable[] { - new Box + IconBackgound = new Box { RelativeSizeAxes = Axes.Both, - ColourInfo = ColourInfo.GradientVertical(OsuColour.Gray(0.2f), OsuColour.Gray(0.5f)) + ColourInfo = ColourInfo.GradientVertical(OsuColour.Gray(0.2f), OsuColour.Gray(0.6f)) }, iconDrawable = new TextAwesome { Anchor = Anchor.Centre, - Icon = icon , + Icon = icon, } }); From 461a22bccb43263cfbf5674fe635f768735fdf86 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Feb 2017 13:52:52 +0900 Subject: [PATCH 3/4] Add resiliency to update process when delta patching fails. --- osu.Desktop/Overlays/VersionManager.cs | 57 +++++++++++++++++--------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs index c06b4cce10..a853c375ca 100644 --- a/osu.Desktop/Overlays/VersionManager.cs +++ b/osu.Desktop/Overlays/VersionManager.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.ComponentModel; using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -23,7 +24,7 @@ namespace osu.Desktop.Overlays public class VersionManager : OverlayContainer { private UpdateManager updateManager; - private NotificationManager notification; + private NotificationManager notificationManager; AssemblyName assembly = Assembly.GetEntryAssembly().GetName(); @@ -36,7 +37,7 @@ namespace osu.Desktop.Overlays [BackgroundDependencyLoader] private void load(NotificationManager notification, OsuColour colours, TextureStore textures) { - this.notification = notification; + this.notificationManager = notification; AutoSizeAxes = Axes.Both; Anchor = Anchor.BottomCentre; @@ -115,43 +116,59 @@ namespace osu.Desktop.Overlays updateManager?.Dispose(); } - private async void updateChecker() + private async void updateChecker(bool useDeltaPatching = true, UpdateProgressNotification notification = null) { try { - updateManager = await UpdateManager.GitHubUpdateManager(@"https://github.com/ppy/osu", @"osulazer", null, null, true); - var info = await updateManager.CheckForUpdate(); + if (updateManager == null) updateManager = await UpdateManager.GitHubUpdateManager(@"https://github.com/ppy/osu", @"osulazer", null, null, true); + + var info = await updateManager.CheckForUpdate(!useDeltaPatching); if (info.ReleasesToApply.Count > 0) { - ProgressNotification n = new UpdateProgressNotification + if (notification == null) { - Text = @"Downloading update..." - }; + notification = new UpdateProgressNotification { State = ProgressNotificationState.Active }; + Schedule(() => notificationManager.Post(notification)); + } + Schedule(() => { - notification.Post(n); - n.State = ProgressNotificationState.Active; - }); - await updateManager.DownloadReleases(info.ReleasesToApply, p => Schedule(() => n.Progress = p / 100f)); - Schedule(() => - { - n.Progress = 0; - n.Text = @"Installing update..."; + notification.Progress = 0; + notification.Text = @"Downloading update..."; }); - await updateManager.ApplyReleases(info, p => Schedule(() => n.Progress = p / 100f)); - Schedule(() => n.State = ProgressNotificationState.Completed); + await updateManager.DownloadReleases(info.ReleasesToApply, p => Schedule(() => notification.Progress = p / 100f)); + + Schedule(() => + { + notification.Progress = 0; + notification.Text = @"Installing update..."; + }); + + try + { + await updateManager.ApplyReleases(info, p => Schedule(() => notification.Progress = p / 100f)); + } + catch (Win32Exception) + { + //could fail if deltas are unavailable for full update path (https://github.com/Squirrel/Squirrel.Windows/issues/959) + //try again without deltas. + updateChecker(false, notification); + return; + } + + Schedule(() => notification.State = ProgressNotificationState.Completed); } else { //check again every 30 minutes. - Scheduler.AddDelayed(updateChecker, 60000 * 30); + Scheduler.AddDelayed(() => updateChecker(), 60000 * 30); } } catch (HttpRequestException) { //check again every 30 minutes. - Scheduler.AddDelayed(updateChecker, 60000 * 30); + Scheduler.AddDelayed(() => updateChecker(), 60000 * 30); } } From b744f3a3a79ab4543b9b8e2128e03bdf8d76fc94 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Feb 2017 14:15:46 +0900 Subject: [PATCH 4/4] Re-nest code and handle even more potential exceptions. --- osu.Desktop/Overlays/VersionManager.cs | 66 ++++++++++++++++---------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs index a853c375ca..a2dc0cb5c3 100644 --- a/osu.Desktop/Overlays/VersionManager.cs +++ b/osu.Desktop/Overlays/VersionManager.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.ComponentModel; using System.Diagnostics; using osu.Framework.Allocation; @@ -18,6 +19,7 @@ using osu.Game.Graphics; using OpenTK; using OpenTK.Graphics; using System.Net.Http; +using osu.Framework.Logging; namespace osu.Desktop.Overlays { @@ -118,25 +120,32 @@ namespace osu.Desktop.Overlays private async void updateChecker(bool useDeltaPatching = true, UpdateProgressNotification notification = null) { + //should we schedule a retry on completion of this check? + bool scheduleRetry = true; + try { if (updateManager == null) updateManager = await UpdateManager.GitHubUpdateManager(@"https://github.com/ppy/osu", @"osulazer", null, null, true); var info = await updateManager.CheckForUpdate(!useDeltaPatching); - if (info.ReleasesToApply.Count > 0) + if (info.ReleasesToApply.Count == 0) + //no updates available. bail and retry later. + return; + + if (notification == null) { - if (notification == null) - { - notification = new UpdateProgressNotification { State = ProgressNotificationState.Active }; - Schedule(() => notificationManager.Post(notification)); - } + notification = new UpdateProgressNotification { State = ProgressNotificationState.Active }; + Schedule(() => notificationManager.Post(notification)); + } - Schedule(() => - { - notification.Progress = 0; - notification.Text = @"Downloading update..."; - }); + Schedule(() => + { + notification.Progress = 0; + notification.Text = @"Downloading update..."; + }); + try + { await updateManager.DownloadReleases(info.ReleasesToApply, p => Schedule(() => notification.Progress = p / 100f)); Schedule(() => @@ -145,30 +154,35 @@ namespace osu.Desktop.Overlays notification.Text = @"Installing update..."; }); - try - { - await updateManager.ApplyReleases(info, p => Schedule(() => notification.Progress = p / 100f)); - } - catch (Win32Exception) + await updateManager.ApplyReleases(info, p => Schedule(() => notification.Progress = p / 100f)); + + Schedule(() => notification.State = ProgressNotificationState.Completed); + } + catch (Exception) + { + if (useDeltaPatching) { //could fail if deltas are unavailable for full update path (https://github.com/Squirrel/Squirrel.Windows/issues/959) //try again without deltas. updateChecker(false, notification); - return; + scheduleRetry = false; } - - Schedule(() => notification.State = ProgressNotificationState.Completed); - } - else - { - //check again every 30 minutes. - Scheduler.AddDelayed(() => updateChecker(), 60000 * 30); } } catch (HttpRequestException) { - //check again every 30 minutes. - Scheduler.AddDelayed(() => updateChecker(), 60000 * 30); + //likely have no internet connection. + //we'll ignore this and retry later. + } + finally + { + if (scheduleRetry) + { + //check again in 30 minutes. + Scheduler.AddDelayed(() => updateChecker(), 60000 * 30); + if (notification != null) + notification.State = ProgressNotificationState.Cancelled; + } } }