-
Notifications
You must be signed in to change notification settings - Fork 4
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
Create MailboxLocalValues
class to stop forgetting to pass values in initLocalValues()
#2058
base: master
Are you sure you want to change the base?
Conversation
8e192fd
to
2d9e505
Compare
fun setFeatureFlags(featureFlags: List<String>) { | ||
mailboxLocalValues = local.copyFromRealm().also { | ||
it.featureFlags.setFeatureFlags(featureFlags) | ||
} |
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.
Can we change isBimiEnabledLiveData
's query so it directly queries the feature flags? This way we might be able to avoid the copyFromRealm
in this setFeatureFlags
method if it's only used to trigger the live data that observes the realm query
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.
We can't, it's an EmbeddedObject, we need to use its parent (ie. the Mailbox).
it.local.externalMailFlagEnabled = externalMailInfo.externalMailFlagEnabled | ||
it.local.trustedDomains = externalMailInfo.trustedDomains.toRealmList() |
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.
Is it worth bothering to only update the local values' object rather than updating all of the mailbox object in realm? Because here the only values we updates are inside the local values, not inside the whole mailbox.
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.
In this part of the code we have multiple spot where we modify the realm object the same way we do it for the local.featureFlags
where we needed a copyFromRealm()
. If we cannot remove the copyFromRealm()
will we also need it in these places here?
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.
Updating like it's done here will correctly update data in Realm, but won't trigger any Flow if it's listening to the Mailbox, because the Mailbox itself won't be updated, only it's embeddedObject.
If we want to immediately broadcast this change to any Flow listening to this Mailbox, we need to update the data like we did in the other places, with the copyFromRealm()
method.
Maybe it's better to always update it with copyFromRealm()
, to be sure we don't miss it.
But I don't really like this idea. It will complicate the code everywhere (remember that we need to do this change for every Realm object that has a initLocalValues()
function).
I'm starting to think it's better to drop this PR instead of complicating the code and risking to forget to update correctly.
The issue was that we could forget some parameters in initLocalValues()
, and now the issue is that we can forget to correctly broadcast values updates.
The issue is the same, but somewhere else and with more code complexity.
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.
If this doesn't work, it indeed introduces a new equivalent problem. It'd be even worse at that.
But I'd be very surprised if Realm didn't create a way to listen to items in a DB and get notified when they change even in this situation. We should talk about it in person and maybe even talk about it with @sirambd
@@ -31,7 +31,7 @@ class SignatureController @Inject constructor( | |||
|
|||
//region Get data | |||
fun getSignaturesAsync(mailboxObjectId: String): Flow<RealmList<Signature>> { | |||
return mailboxController.getMailboxAsync(mailboxObjectId).mapNotNull { it.obj?.signatures } | |||
return mailboxController.getMailboxAsync(mailboxObjectId).mapNotNull { it.obj?.local?.signatures } |
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.
Is it worth it to query the whole mailbox when we only need the local values' object? (This pattern appears in other controllers as well)
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.
This is an EmbeddedObject, we can't query it directly.
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? I asked @sirambd because I feared this exact situation and he told me we could. Maybe he did not understand what I meant
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.
We can query it, but not directly.
There is no PrimaryKey to search for since it's an EmbeddedObject.
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.
As long as we can query it indirectly by checking its parent's primary key, it should be enough. But I don't know to what extent this is feasible
@@ -99,19 +101,10 @@ class MailboxController @Inject constructor( | |||
val remoteMailboxesIds = remoteMailboxes.map { remoteMailbox -> | |||
|
|||
SentryLog.d(RealmDatabase.TAG, "Mailboxes: Get current data") | |||
val localMailbox = getMailbox(userId, remoteMailbox.mailboxId, realm = this) | |||
val previousLocalValues = getMailbox(userId, remoteMailbox.mailboxId, realm = this)?.local?.copyFromRealm() |
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 reason that makes this copyFromRealm() required? How does it fix the bimi issue? Because I'm not sure I understand correctly how copyFromRealm() should properly be used
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.
We are replacing the mailboxLocalValues
with another one that's coming from Realm.
We need to copyFromRealm()
it if we want it to work.
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.
Yeah I figured we update the value here and apparently copyFromRealm()
seems to be needed, but why? How does it work? What does it bring to the table? Why does it work? What's missing if we don't use it? How does it fix the bimi issue?
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.
You need to copy the value from Realm to be able to put it back in Realm later.
If we don't, Realm crashes, that's all.
@@ -204,7 +204,7 @@ class NewMessageAiManager @Inject constructor( | |||
|
|||
fun observeAiFeatureFlagUpdates() { | |||
newMessageViewModel.currentMailboxLive.observeNotNull(viewLifecycleOwner) { mailbox -> | |||
val isAiEnabled = mailbox.featureFlags.contains(FeatureFlag.AI) | |||
val isAiEnabled = mailbox.local.featureFlags.contains(FeatureFlag.AI) |
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.
This live data is only ever used to get the current mailbox to now if its local values has the ai flag, would it make sens to replace it with a live data that only returns ai's enabled status? You can still keep the currentMailboxLive as a private live data and map it in a second public isAiEnabled
live data or something I guess. Or directly query the local values from realm without querying the whole mailbox if it makes sens
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.
This is an EmbeddedObject, we can't query it directly.
We can expose a LiveData that's named about the AI and not the Mailbox, if you want.
But that's not relevant for this PR.
9f489ce
to
4a94b50
Compare
2d9e505
to
a2c0105
Compare
4a94b50
to
537a377
Compare
b1657cb
to
a96b542
Compare
7d716d7
to
cde8f48
Compare
a96b542
to
0c838f3
Compare
cde8f48
to
32475d2
Compare
This PR/issue depends on:
|
98d549c
to
13066e0
Compare
13066e0
to
774e409
Compare
Quality Gate passedIssues Measures |
Depends on #2059