Don't remove nulls in cache merge#411
Conversation
chiragsalian
left a comment
There was a problem hiding this comment.
I think the code is fine but i thought we were using null to clear unused onyx data to free up memory so I'm unsure if this code would cause a negative impact.
Either way I'll let @marcaaron also review since he's more familiar here.
Sorry, I am not sure what this means. Is there more context? Can you show where we are removing the |
marcaaron
left a comment
There was a problem hiding this comment.
@chiragsalian maybe we can get more eyes on this one. I don't have the bandwidth to help validate this right now, but left some comments.
| // lodash adds a small overhead so we don't use it here | ||
| // eslint-disable-next-line prefer-object-spread, rulesdir/prefer-underscore-method | ||
| this.storageMap = Object.assign({}, utils.fastMerge(this.storageMap, data)); | ||
| this.storageMap = Object.assign({}, utils.fastMerge(this.storageMap, data, false)); |
There was a problem hiding this comment.
Does this mean we would just leave in the storage map a bunch of keys with null and never delete them? I think it does.
It is a bit hard to wrap one's head around what the side effects of this change would be 😄
One possible problem is here:
Lines 125 to 129 in cd54318
Since a value that we are setting again after deleting previously would be undefined but now would be regarded as null so we would not check to see if it should be read from storage.
There was a problem hiding this comment.
We will have more null values in cache storage yes, but this is only the in memory cache and not the persisted storage so I think it is fine to speedup lookup of values that we know do not exist in storage.
The behavior for deleted values should not change since the cache has a drop method which should be used to remove values completely. The only case I know of that we remove values from cache so they will be fetched from storage again is
react-native-onyx/lib/OnyxCache.js
Line 185 in cd54318
I hope that clears up any confusion.
There was a problem hiding this comment.
it is fine to speedup lookup of values that we know do not exist in storage.
That's a good point - I was thinking more along the lines of whether this could lead to anything unexpected e.g. could it somehow be possible for the value to exist in storage, but still null in the cache? But doesn't seem likely.
|
at the very least I think we should do some testing for this PR against the App |
|
Sorry I think this PR lacked a little bit more context around this change. The idea was to improve Onyx caching by caching This PR is a bug fix since calling merge will wipe all |
|
@chiragsalian We have a method that clears least recently used keys from cache, but it doesn't use the merge method that is affected here, the cache has a drop method which should be used to fully remove items from cache and cause them to be fetched again from storage. Also note this is only the caching layer and doesn't affect persisted storage. |
|
@chiragsalian @marcaaron Thanks for having a look, lmk if there's anything I forgot to address. |
I think there is a subtle difference here. null is used to clear onyx data to free up disk space, not memory. To my knowledge, we haven't done much with optimizing memory.
I definitely always agree with this one (I have learned my own hard lessons from it). To alleviate this concern a little bit, this PR is coming immediately on the heels of doing a lot of extensive in-app testing and it fixes one of the last remaining bugs that was found which prevents Onyx from being updated in App. |
|
More context around the discussion and testing was in this Slack thread. |
|
Thanks for the thorough explanation @janicduplessis. With the additional context there are no blocking concerns from me. |
mountiny
left a comment
There was a problem hiding this comment.
Thank you for the explanation indeed
Sorry for the late reply! I also don't think there's anything wrong with this PR, as long as it's only for the cache 👍 @janicduplessis |
Details
When merging cache we should not remove null values, they are useful to know an item was fetched but doesn't exist.
Related Issues
#408 (comment)
Automated Tests
Added a unit test to assert behaviour of null values in OnyxCache.
Manual Tests
Tested in Expensify app and made sure the money request button renders at the same time as the rest of the header.
Author Checklist
### Related Issuessection aboveTestssectiontoggleReportand notonIconClick)myBool && <MyComponent />.STYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)/** comment above it */thisproperly so there are no scoping issues (i.e. foronClick={this.submit}the methodthis.submitshould be bound tothisin the constructor)thisare necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);ifthis.submitis never passed to a component event handler likeonClick)Avataris modified, I verified thatAvataris working as expected in all cases)mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Web
Mobile Web - Chrome
Mobile Web - Safari
Desktop
iOS
Android