mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 18:27:26 +08:00
Merge branch 'realm-stable-subscriptions' into music-controller-less-population
This commit is contained in:
commit
287d70d728
@ -29,8 +29,10 @@ namespace osu.Game.Benchmarks
|
||||
|
||||
realmFactory = new RealmContextFactory(storage, "client");
|
||||
|
||||
using (var context = realmFactory.CreateContext())
|
||||
context.Write(c => c.Add(TestResources.CreateTestBeatmapSetInfo(rulesets: new[] { new OsuRuleset().RulesetInfo })));
|
||||
realmFactory.Run(realm =>
|
||||
{
|
||||
realm.Write(c => c.Add(TestResources.CreateTestBeatmapSetInfo(rulesets: new[] { new OsuRuleset().RulesetInfo })));
|
||||
});
|
||||
|
||||
updateThread = new UpdateThread(() => { }, null);
|
||||
updateThread.Start();
|
||||
@ -39,15 +41,15 @@ namespace osu.Game.Benchmarks
|
||||
[Benchmark]
|
||||
public void BenchmarkDirectPropertyRead()
|
||||
{
|
||||
using (var context = realmFactory.CreateContext())
|
||||
realmFactory.Run(realm =>
|
||||
{
|
||||
var beatmapSet = context.All<BeatmapSetInfo>().First();
|
||||
var beatmapSet = realm.All<BeatmapSetInfo>().First();
|
||||
|
||||
for (int i = 0; i < ReadsPerFetch; i++)
|
||||
{
|
||||
string _ = beatmapSet.Beatmaps.First().Hash;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
@ -78,15 +80,15 @@ namespace osu.Game.Benchmarks
|
||||
[Benchmark]
|
||||
public void BenchmarkRealmLivePropertyRead()
|
||||
{
|
||||
using (var context = realmFactory.CreateContext())
|
||||
realmFactory.Run(realm =>
|
||||
{
|
||||
var beatmapSet = context.All<BeatmapSetInfo>().First().ToLive(realmFactory);
|
||||
var beatmapSet = realm.All<BeatmapSetInfo>().First().ToLive(realmFactory);
|
||||
|
||||
for (int i = 0; i < ReadsPerFetch; i++)
|
||||
{
|
||||
string _ = beatmapSet.PerformRead(b => b.Beatmaps.First().Hash);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
@ -117,15 +119,15 @@ namespace osu.Game.Benchmarks
|
||||
[Benchmark]
|
||||
public void BenchmarkDetachedPropertyRead()
|
||||
{
|
||||
using (var context = realmFactory.CreateContext())
|
||||
realmFactory.Run(realm =>
|
||||
{
|
||||
var beatmapSet = context.All<BeatmapSetInfo>().First().Detach();
|
||||
var beatmapSet = realm.All<BeatmapSetInfo>().First().Detach();
|
||||
|
||||
for (int i = 0; i < ReadsPerFetch; i++)
|
||||
{
|
||||
string _ = beatmapSet.Beatmaps.First().Hash;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[GlobalCleanup]
|
||||
|
@ -47,6 +47,11 @@ namespace osu.Game.Tests.Database
|
||||
liveBeatmap = beatmap.ToLive(realmFactory);
|
||||
});
|
||||
|
||||
using (realmFactory.BlockAllOperations())
|
||||
{
|
||||
// recycle realm before migrating
|
||||
}
|
||||
|
||||
using (var migratedStorage = new TemporaryNativeStorage("realm-test-migration-target"))
|
||||
{
|
||||
migratedStorage.DeleteDirectory(string.Empty);
|
||||
|
@ -69,28 +69,29 @@ namespace osu.Game.Database
|
||||
|
||||
private Realm? context;
|
||||
|
||||
public Realm Context
|
||||
public Realm Context => ensureUpdateContext();
|
||||
|
||||
private Realm ensureUpdateContext()
|
||||
{
|
||||
get
|
||||
if (!ThreadSafety.IsUpdateThread)
|
||||
throw new InvalidOperationException(@$"Use {nameof(createContext)} when performing realm operations from a non-update thread");
|
||||
|
||||
lock (contextLock)
|
||||
{
|
||||
if (!ThreadSafety.IsUpdateThread)
|
||||
throw new InvalidOperationException(@$"Use {nameof(createContext)} when performing realm operations from a non-update thread");
|
||||
|
||||
lock (contextLock)
|
||||
if (context == null)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
context = createContext();
|
||||
Logger.Log(@$"Opened realm ""{context.Config.DatabasePath}"" at version {context.Config.SchemaVersion}");
|
||||
context = createContext();
|
||||
Logger.Log(@$"Opened realm ""{context.Config.DatabasePath}"" at version {context.Config.SchemaVersion}");
|
||||
|
||||
// Resubscribe any subscriptions
|
||||
foreach (var action in subscriptionActions.Keys)
|
||||
registerSubscription(action);
|
||||
}
|
||||
|
||||
// creating a context will ensure our schema is up-to-date and migrated.
|
||||
return context;
|
||||
// Resubscribe any subscriptions
|
||||
foreach (var action in subscriptionActions.Keys)
|
||||
registerSubscription(action);
|
||||
}
|
||||
|
||||
Debug.Assert(context != null);
|
||||
|
||||
// creating a context will ensure our schema is up-to-date and migrated.
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,10 +262,13 @@ namespace osu.Game.Database
|
||||
{
|
||||
Debug.Assert(ThreadSafety.IsUpdateThread);
|
||||
|
||||
// Get context outside of flag update to ensure beyond doubt this can't be cyclic.
|
||||
var realm = Context;
|
||||
|
||||
lock (contextLock)
|
||||
{
|
||||
current_thread_subscriptions_allowed.Value = true;
|
||||
subscriptionActions[action] = action(Context);
|
||||
subscriptionActions[action] = action(realm);
|
||||
current_thread_subscriptions_allowed.Value = false;
|
||||
}
|
||||
}
|
||||
@ -501,6 +505,8 @@ namespace osu.Game.Database
|
||||
if (isDisposed)
|
||||
throw new ObjectDisposedException(nameof(RealmContextFactory));
|
||||
|
||||
SynchronizationContext syncContext;
|
||||
|
||||
try
|
||||
{
|
||||
contextCreationLock.Wait();
|
||||
@ -510,6 +516,8 @@ namespace osu.Game.Database
|
||||
if (!ThreadSafety.IsUpdateThread && context != null)
|
||||
throw new InvalidOperationException(@$"{nameof(BlockAllOperations)} must be called from the update thread.");
|
||||
|
||||
syncContext = SynchronizationContext.Current;
|
||||
|
||||
Logger.Log(@"Blocking realm operations.", LoggingTarget.Database);
|
||||
|
||||
context?.Dispose();
|
||||
@ -548,6 +556,9 @@ namespace osu.Game.Database
|
||||
{
|
||||
factory.contextCreationLock.Release();
|
||||
Logger.Log(@"Restoring realm operations.", LoggingTarget.Database);
|
||||
|
||||
// Post back to the update thread to revive any subscriptions.
|
||||
syncContext?.Post(_ => ensureUpdateContext(), null);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -33,10 +33,6 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings
|
||||
using (realmFactory.BlockAllOperations())
|
||||
{
|
||||
}
|
||||
|
||||
// retrieve context to revive realm subscriptions.
|
||||
// TODO: should we do this from OsuGame or RealmContextFactory or something? Answer: yes.
|
||||
var _ = realmFactory.Context;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -34,9 +34,9 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
||||
{
|
||||
string rulesetName = Ruleset?.ShortName;
|
||||
|
||||
List<RealmKeyBinding> bindings = null;
|
||||
|
||||
realmFactory.Run(realm => bindings = realm.All<RealmKeyBinding>().Where(b => b.RulesetName == rulesetName && b.Variant == variant).Detach());
|
||||
var bindings = realmFactory.Run(realm => realm.All<RealmKeyBinding>()
|
||||
.Where(b => b.RulesetName == rulesetName && b.Variant == variant)
|
||||
.Detach());
|
||||
|
||||
foreach (var defaultGroup in Defaults.GroupBy(d => d.Action))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user