1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-15 13:47:24 +08:00

Merge pull request #30151 from bdach/migration-is-completely-fucked

Fix several breakages with migration operation
This commit is contained in:
Dean Herbert 2024-10-09 14:24:34 +09:00 committed by GitHub
commit 270c4c4f12
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 30 additions and 16 deletions

View File

@ -44,7 +44,7 @@ namespace osu.Game.Database
{ {
if (changes == null) if (changes == null)
{ {
if (detachedBeatmapSets.Count > 0 && sender.Count == 0) if (sender is RealmResetEmptySet<BeatmapSetInfo>)
{ {
// Usually we'd reset stuff here, but doing so triggers a silly flow which ends up deadlocking realm. // Usually we'd reset stuff here, but doing so triggers a silly flow which ends up deadlocking realm.
// Additionally, user should not be at song select when realm is blocking all operations in the first place. // Additionally, user should not be at song select when realm is blocking all operations in the first place.

View File

@ -568,7 +568,7 @@ namespace osu.Game.Database
lock (notificationsResetMap) lock (notificationsResetMap)
{ {
// Store an action which is used when blocking to ensure consumers don't use results of a stale changeset firing. // Store an action which is used when blocking to ensure consumers don't use results of a stale changeset firing.
notificationsResetMap.Add(action, () => callback(new EmptyRealmSet<T>(), null)); notificationsResetMap.Add(action, () => callback(new RealmResetEmptySet<T>(), null));
} }
return RegisterCustomSubscription(action); return RegisterCustomSubscription(action);

View File

@ -12,7 +12,13 @@ using Realms.Schema;
namespace osu.Game.Database namespace osu.Game.Database
{ {
public class EmptyRealmSet<T> : IRealmCollection<T> /// <summary>
/// This can arrive in <see cref="RealmAccess.RegisterForNotifications{T}"/> callbacks to imply that realm access has been reset.
/// </summary>
/// <remarks>
/// Usually implies that the original database may return soon and the callback can usually be silently ignored.
///</remarks>
public class RealmResetEmptySet<T> : IRealmCollection<T>
{ {
private IList<T> emptySet => Array.Empty<T>(); private IList<T> emptySet => Array.Empty<T>();

View File

@ -1137,7 +1137,6 @@ namespace osu.Game
loadComponentSingleFile(new MedalOverlay(), topMostOverlayContent.Add); loadComponentSingleFile(new MedalOverlay(), topMostOverlayContent.Add);
loadComponentSingleFile(new BackgroundDataStoreProcessor(), Add); loadComponentSingleFile(new BackgroundDataStoreProcessor(), Add);
loadComponentSingleFile(new DetachedBeatmapStore(), Add, true);
Add(difficultyRecommender); Add(difficultyRecommender);
Add(externalLinkOpener = new ExternalLinkOpener()); Add(externalLinkOpener = new ExternalLinkOpener());

View File

@ -377,6 +377,10 @@ namespace osu.Game
dependencies.Cache(previewTrackManager = new PreviewTrackManager(BeatmapManager.BeatmapTrackStore)); dependencies.Cache(previewTrackManager = new PreviewTrackManager(BeatmapManager.BeatmapTrackStore));
base.Content.Add(previewTrackManager); base.Content.Add(previewTrackManager);
var detachedBeatmapStore = new DetachedBeatmapStore();
base.Content.Add(detachedBeatmapStore);
dependencies.CacheAs(detachedBeatmapStore);
base.Content.Add(MusicController = new MusicController()); base.Content.Add(MusicController = new MusicController());
dependencies.CacheAs(MusicController); dependencies.CacheAs(MusicController);
@ -541,7 +545,10 @@ namespace osu.Game
realmBlocker = realm.BlockAllOperations("migration"); realmBlocker = realm.BlockAllOperations("migration");
success = true; success = true;
} }
catch { } catch (Exception ex)
{
Logger.Log($"Attempting to block all operations failed: {ex}", LoggingTarget.Database);
}
readyToRun.Set(); readyToRun.Set();
}, false); }, false);

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Audio.Track; using osu.Framework.Audio.Track;
@ -62,8 +63,7 @@ namespace osu.Game.Overlays
public DrawableTrack CurrentTrack { get; private set; } = new DrawableTrack(new TrackVirtual(1000)); public DrawableTrack CurrentTrack { get; private set; } = new DrawableTrack(new TrackVirtual(1000));
[Resolved] private IBindableList<BeatmapSetInfo> detachedBeatmaps = null!;
private RealmAccess realm { get; set; } = null!;
private BindableNumber<double> sampleVolume = null!; private BindableNumber<double> sampleVolume = null!;
@ -76,13 +76,15 @@ namespace osu.Game.Overlays
private int randomHistoryDirection; private int randomHistoryDirection;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(AudioManager audio, OsuConfigManager configManager) private void load(AudioManager audio, OsuConfigManager configManager, DetachedBeatmapStore detachedBeatmapStore, CancellationToken? cancellationToken)
{ {
AddInternal(audioDuckFilter = new AudioFilter(audio.TrackMixer)); AddInternal(audioDuckFilter = new AudioFilter(audio.TrackMixer));
audio.Tracks.AddAdjustment(AdjustableProperty.Volume, audioDuckVolume); audio.Tracks.AddAdjustment(AdjustableProperty.Volume, audioDuckVolume);
sampleVolume = audio.VolumeSample.GetBoundCopy(); sampleVolume = audio.VolumeSample.GetBoundCopy();
configManager.BindWith(OsuSetting.RandomSelectAlgorithm, randomSelectAlgorithm); configManager.BindWith(OsuSetting.RandomSelectAlgorithm, randomSelectAlgorithm);
detachedBeatmaps = detachedBeatmapStore.GetDetachedBeatmaps(cancellationToken);
} }
protected override void LoadComplete() protected override void LoadComplete()
@ -255,8 +257,8 @@ namespace osu.Game.Overlays
playableSet = getNextRandom(-1, allowProtectedTracks); playableSet = getNextRandom(-1, allowProtectedTracks);
else else
{ {
playableSet = getBeatmapSets().AsEnumerable().TakeWhile(i => !i.Equals(current?.BeatmapSetInfo)).LastOrDefault(s => !s.Protected || allowProtectedTracks) playableSet = getBeatmapSets().TakeWhile(i => !i.Equals(current?.BeatmapSetInfo)).LastOrDefault(s => !s.Protected || allowProtectedTracks)
?? getBeatmapSets().AsEnumerable().LastOrDefault(s => !s.Protected || allowProtectedTracks); ?? getBeatmapSets().LastOrDefault(s => !s.Protected || allowProtectedTracks);
} }
if (playableSet != null) if (playableSet != null)
@ -351,10 +353,10 @@ namespace osu.Game.Overlays
playableSet = getNextRandom(1, allowProtectedTracks); playableSet = getNextRandom(1, allowProtectedTracks);
else else
{ {
playableSet = getBeatmapSets().AsEnumerable().SkipWhile(i => !i.Equals(current?.BeatmapSetInfo)) playableSet = getBeatmapSets().SkipWhile(i => !i.Equals(current?.BeatmapSetInfo))
.Where(i => !i.Protected || allowProtectedTracks) .Where(i => !i.Protected || allowProtectedTracks)
.ElementAtOrDefault(1) .ElementAtOrDefault(1)
?? getBeatmapSets().AsEnumerable().FirstOrDefault(i => !i.Protected || allowProtectedTracks); ?? getBeatmapSets().FirstOrDefault(i => !i.Protected || allowProtectedTracks);
} }
var playableBeatmap = playableSet?.Beatmaps.FirstOrDefault(); var playableBeatmap = playableSet?.Beatmaps.FirstOrDefault();
@ -373,7 +375,7 @@ namespace osu.Game.Overlays
{ {
BeatmapSetInfo result; BeatmapSetInfo result;
var possibleSets = getBeatmapSets().AsEnumerable().Where(s => !s.Protected || allowProtectedTracks).ToArray(); var possibleSets = getBeatmapSets().Where(s => !s.Protected || allowProtectedTracks).ToArray();
if (possibleSets.Length == 0) if (possibleSets.Length == 0)
return null; return null;
@ -432,7 +434,7 @@ namespace osu.Game.Overlays
private TrackChangeDirection? queuedDirection; private TrackChangeDirection? queuedDirection;
private IQueryable<BeatmapSetInfo> getBeatmapSets() => realm.Realm.All<BeatmapSetInfo>().Where(s => !s.DeletePending); private IEnumerable<BeatmapSetInfo> getBeatmapSets() => detachedBeatmaps.Where(s => !s.DeletePending);
private void changeBeatmap(WorkingBeatmap newWorking) private void changeBeatmap(WorkingBeatmap newWorking)
{ {
@ -459,8 +461,8 @@ namespace osu.Game.Overlays
else else
{ {
// figure out the best direction based on order in playlist. // figure out the best direction based on order in playlist.
int last = getBeatmapSets().AsEnumerable().TakeWhile(b => !b.Equals(current.BeatmapSetInfo)).Count(); int last = getBeatmapSets().TakeWhile(b => !b.Equals(current.BeatmapSetInfo)).Count();
int next = getBeatmapSets().AsEnumerable().TakeWhile(b => !b.Equals(newWorking.BeatmapSetInfo)).Count(); int next = getBeatmapSets().TakeWhile(b => !b.Equals(newWorking.BeatmapSetInfo)).Count();
direction = last > next ? TrackChangeDirection.Prev : TrackChangeDirection.Next; direction = last > next ? TrackChangeDirection.Prev : TrackChangeDirection.Next;
} }