Ensure realm subscriptions always fire initial callback with null ChangeSet

We expect this to be the case, but it turns out that it [may be
coalesced](https://www.mongodb.com/docs/realm-sdks/dotnet/latest/reference/Realms.IRealmCollection-1.html#Realms_IRealmCollection_1_SubscribeForNotifications_Realms_NotificationCallbackDelegate__0__Realms_KeyPathsCollection_):

> Notifications are delivered via the standard event loop, and so can't
> be delivered while the event loop is blocked by other activity. When
> notifications can't be delivered instantly, multiple notifications may
> be coalesced into a single notification. This can include the
> notification with the initial collection.

Rather than struggle with handling this locally every time, let's fix
the callback at our end to ensure we receive the initial null case.

I've raised concern for the API being a bit silly with realm
(https://github.com/realm/realm-dotnet/issues/3641).
This commit is contained in:
Dean Herbert 2024-07-09 15:28:35 +09:00
parent c8b9c117cd
commit 2423bbb776
No known key found for this signature in database

View File

@ -65,7 +65,8 @@ namespace osu.Game.Database
if (!d.Beatmaps.Contains(existingBeatmap))
{
Debug.Fail("Beatmaps should never become detached under normal circumstances. If this ever triggers, it should be investigated further.");
Logger.Log("WARNING: One of the difficulties in a beatmap was detached from its set. Please save a copy of logs and report this to devs.", LoggingTarget.Database, LogLevel.Important);
Logger.Log("WARNING: One of the difficulties in a beatmap was detached from its set. Please save a copy of logs and report this to devs.", LoggingTarget.Database,
LogLevel.Important);
d.Beatmaps.Add(existingBeatmap);
}
@ -291,7 +292,21 @@ namespace osu.Game.Database
if (!RealmAccess.CurrentThreadSubscriptionsAllowed)
throw new InvalidOperationException($"Make sure to call {nameof(RealmAccess)}.{nameof(RealmAccess.RegisterForNotifications)}");
return collection.SubscribeForNotifications(callback);
bool initial = true;
return collection.SubscribeForNotifications(((sender, changes) =>
{
if (initial)
{
initial = false;
// Realm might coalesce the initial callback, meaning we never receive a `ChangeSet` of `null` marking the first callback.
// Let's decouple it for simplicity in handling.
if (changes != null)
callback(sender, null);
}
callback(sender, changes);
}));
}
/// <summary>