question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Improvements to `Onyx.get`

See original GitHub issue

If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!


Problem:

  • Each time a component “connects” to Onyx we read that data from disk before returning it to withOnyx.
  • When multiple components ask for the same key at the same time (e.g. during init | switching chats) the key is requested multiple times from storage
  • This causes a lot of unnecessary traffic through the native bridge and adds unnecessary CPU / memory usage
  • Confirmed with the following manual benchmarks: https://github.com/Expensify/react-native-onyx/issues/63#issuecomment-832002373

Solution:

This was widely discussed in the following places and it was decided to go with the cache solution:

Prevent unnecessary reads from disk

When a request is made to retrieve something from disk capture the task that would resolve with the read data, as more calls for the same key arrive, instead of making a separate call for the same thing redirect the reads to be resolved from the already pending task. This way only one round trip would ever happen for a given key. As soon as the data for the first call is available - all calls are resolved at once.

Cache and lazy loading

As data is read from file, keep a reference/pointer to the data in memory in a cache dictionary Fill the cache lazily - only after a key was requested and read from file Remove cache entries after the last connection for the given key is disconnected


Additional Work

✔️ Should we implement any benchmarks / metering?

The general principle I like to apply for a benchmark is through method decoration like the same here: https://github.com/Expensify/react-native-onyx/issues/65#issuecomment-821027845

  1. Create a metrics capturing function that tracks call and response information
    • call start/end time
    • call execution time
    • arguments for the call
    • tag returned objects so we can see how much of them are still in memory (Or just tag the cache map since it should pretty much hold the same information - thought this is only possible after the update that adds cache…)
  2. Use a ENV variable (let’s say ONYX_BENCHMARK) to apply the metring function through decoration to a list of Onyx methods
    • in order to work the methods in the list need to return a promise or have a callback that is triggered when the call is over
    • e.g. the base methods like get, set, merge would pretty much work out of the box
  3. Use the same ENV var from above to expose a readCollectMetrics and resetMetrics as an Onyx method
    • you will be able to further aggregate data like: how much calls were there for get with the a specific key
    • this can also include information about how much data is currently in cache, after the update is made

Expected Result:

Onyx does not try to retrieve data that is already available in memory

Actual Result:

Onyx will always ask data from AsyncStorage

Action Performed:

N/A

Workaround:

Can the user still use Expensify without this being fixed? Have you informed them of the workaround?

Affected Platforms:

-[x] Web -[x] iOS -[x] Android -[x] Desktop App -[x] Mobile Web

Version Number: Logs: https://stackoverflow.com/c/expensify/questions/4856 Expensify/Expensify Issue URL:

View all open jobs on Upwork

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:1
  • Comments:23 (20 by maintainers)

github_iconTop GitHub Comments

1reaction
mallenexpensifycommented, Jun 18, 2021

Thanks for the ping @kidroca it was my responsibility and I missed it (we previously didn’t leave Contributor Managers assigned to issues, we now do). I paid in Upwork and added the bonus for writing the OP. Thanks!

1reaction
kidrocacommented, May 25, 2021

@tgolen It’s seconds, updated the table

Read more comments on GitHub >

github_iconTop Results From Across the Web

Onyx RIPCenter Upgrades - RPimaging, INC
Based on ROI calculations, printing just one more job per day can improve the profit margin in a shop by as much as...
Read more >
Disney Dreamlight Valley: How To Get Onyx | Nintendo Life
There is a very rare chance that you will get an Onyx on top of whatever the Mining Spot drops normally, which means...
Read more >
Why The New Subaru Outback Onyx Is Now Your Best Pick ...
The 2023 Wilderness trim doesn't get any new exterior upgrades. 2023 Subaru Outback features, upgrades, pricing, fuel mileage. Onyx Edition now ...
Read more >
Onyx Stone & Crystal - Meaning, Properties, Benefits, Chakra
The onyx stone improves the nervous system, and also works wonders for the immune system. It increases your stamina, helping you to get...
Read more >
Does the Black Onyx Undergo Treatment? | Angarajewelry
But is the jewel's beauty a result of artificial enhancements? Read this article to find out… But first, what is the Black Onyx?...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found