-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add initial realm database implementation with KeyBindingStore migration #11461
Conversation
Also improve the Query method for action types by using generic field
@gagahpangeran care to share your operating system? I've tested with fresh installs on windows and macOS and it works as expected, for what it's worth. |
openSUSE Tumbleweed, linux kernel 5.12.4, X86_64. |
@peppy I have been running under Linux but I haven't admittedly ran the version as it is right now. May be something new-ish. |
I've tried again on my linux box and I cannot seem to reproduce deadlocks, the game launches fine. Tried both with an existing sqlite DB but the realm items removed, and with a fresh install.
Maybe the kernel version matters somehow? I haven't (manually) updated this box for a while now. |
Mine: |
Here's a native stack:
I've also tested 10.2.0-beta.2 and 10.1.4 (previous stable version) and this still occurs. |
Is this still related to realm/realm-dotnet#2245 ? |
While it might be related to some similar scenario in the linux implementation, the report in the linked issue (happening on windows) is already fixed in the beta releases, as already mentioned in this thread. |
As a heads up, I test this PR again with the latest release of Realm version 10.2.0 and now it works. |
Can reproduce; will investigate. |
Should be resolved, along with a weird thread concurrency issue. |
if (keyBinding.IsManaged) | ||
throw new ArgumentException("Key binding should not be attached as we make temporary changes", nameof(keyBinding)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it was done this way to keep it simple and not have many abstractions over database model doing magic behind the scenes.
I would agree with immutability, though.
List<RealmKeyBinding> bindings; | ||
|
||
using (var usage = realmFactory.GetForRead()) | ||
bindings = usage.Realm.All<RealmKeyBinding>().Where(b => b.RulesetID == rulesetId && b.Variant == variant).Detach(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the difference between calling Detach()
and Freeze()
in this scenario? Is Freeze()
more expensive because it creates a frozen realm?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Freezing objects requires the source realm (the one which the freeze was run on) to be kept open, and disposed of once it's finished. Keeping frozen objects/realms open will keep that version of the realm on disk, which can lead to filesize bloat depending on how many follow-up changes are made while it's kept frozen.
Looks good to me. I personally think the build time is acceptable, but surely we could improve it by moving models to a separate project. Maybe best done as a follow-up? For me, I don't know anything about Fody, and I can tell that the issue is already going to be super deep and not easy to resolve - at least several days of work and figuring out how to even debug such a compile-time process. |
Now that realm have fixed the bug causing windows crashes on multi-threaded usage (realm/realm-dotnet#1933), I've begun to look at how we can make use of Realm. See #7057 for previous experimentation and discussion.
This is a first step towards an attempt to migrate to realm as our database backend. Unlike previous attempts at this (where I tried to update all stores to use realm at once), this takes the lowest hanging fruit and adds complete migration and implementation, while keeping the majority of the game still using the original EF backing.
There are multiple reasons for taking on this simplified direction:
KeyBindingStore
avoids much of the consideration required for cross-thread access, as all usages are detached (ie. copied away from realm)I'd recommend reading this article as a primer to realm and how it should/shouldn't be used.
Dependencies
IKeyBinding
interfaceConsiderations
Live<> (aka RealmWrapper<>) inclusion
Even though I have not used this class in the
KeyBindingStore
implementation, I have included it in an initial state. It doesn't have test coverage yet, but I wanted to have it present to give an idea on my current approach to non-detached usages. I will likely add some more test coverage over the next couple of days.Would appreciate any feedback on the general structure of this class, even if it doesn't have explicit usage yet.
Context refreshing
Generally it is recommended that the main realm context is refreshed as part of the program update loop. This is likely something we will want in the future, but unnecessary given the scope of usage right now. A refresh will occur on realm context retrieval for the time being.
This will need to change if/when we start using
Live<>
data objects, else stale data will start to become a thing.One consideration here is that we currently open a context per thread accessing realm. These are kept open indefinitely, and in the case of a background thread, may not be refreshed for some time. This is known to cause realm filesize growth (as without having them close or refresh, they will be referencing an old snapshot of the full realm database). I'm still investigating a solution to this. It may require some kind of background process as part of the
CompositeDrawable
'sThreadedTaskScheduler
to run after x seconds of not using a thread (to close the context), or on a regular schedule (to run refresh on the context).Again, this is not too important this early in implementation and given the limited size of key binding data, but requires further thought.
Remaining questions
There's some remaining questions which I plan to reach out to the realm team to get answers from (after doing my own investigation, in some cases):
threadLocal
management and opened/closed the realm each time?