You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
re_data_store, which hosts the very low-level APIs used to fetch raw cells from the store (either latest-at or range).
These APIs should never be used directly by downstream crates:
- Nothing should ever query re_data_store directly #6017
re_query, which wraps the low-level APIs in a higher level abstraction that takes care of nullability, promise resolution, error handling, etc.
re_query_cache, which does everything that re_query does, but also handles caching on top of that. re_query_cache is NOT built on top of re_query. It's built atop re_data_store.
The fact that both re_query and re_query_cache exist is a giant PITA.
While they look functionally similar on the surface, they have very different semantics in all aspects that matter upon closer look.
Here's a non exhaustive list of examples:
re_query doesn't store any typed data, while re_query_cache does.
re_query can easily expose owned data, but not reference data. re_query_cache is the exact opposite.
re_query supports fine grained errors within data ranges, re_query_cache on the other hand only supports coarse errors at both ends of the range.
re_query_cache exposes data that is protected behind mutex guards, whereas re_query doesn't.
The list goes on.
These differences make it impossible to abstract over both re_query and re_query_cache in a way that doesn't completely nullify the advantages of each respective API.
Because we can't abstract these differences away, we have to duplicate a lot of the logic between the two, and this logic ends up behaving in subtly different ways, every time. And because Rust is Rust, those different types and traits poison all neighbor functions and suddenly you have two maintain two separate code bases. It's basically a homegrown case of function coloring.
This creates a never ending stream of issues in the code, which begs the question: why do we have uncached APIs to start with?
The reason is that, because of limitations in our data and caching models, we are currently forced to not cache certain things, such as images and meshes, else the memory overhead would become unmanageable.
The only way to fix these limitations is to address these two issues:
The 1M index entries problem #5967
Fixing this would remove the need for the deserialization cache, which means not having to keep yet another extra copy of images and meshes -> less memory pressure.
Fixing these issues is no small task.
In the mean time, I might try and see if it's possible to tweak the cached APIs so that we can disable caching for specific components. It's ugly and weird and non-sensical, but it's still infinitely better than the hell we have to deal with right now.
We currently have three layers of query APIs:
re_data_store, which hosts the very low-level APIs used to fetch raw cells from the store (either latest-at or range).These APIs should never be used directly by downstream crates:
- Nothing should ever query
re_data_storedirectly #6017re_query, which wraps the low-level APIs in a higher level abstraction that takes care of nullability, promise resolution, error handling, etc.re_query_cache, which does everything thatre_querydoes, but also handles caching on top of that.re_query_cacheis NOT built on top ofre_query. It's built atopre_data_store.The fact that both
re_queryandre_query_cacheexist is a giant PITA.While they look functionally similar on the surface, they have very different semantics in all aspects that matter upon closer look.
Here's a non exhaustive list of examples:
re_querydoesn't store any typed data, whilere_query_cachedoes.re_querycan easily expose owned data, but not reference data.re_query_cacheis the exact opposite.re_querysupports fine grained errors within data ranges,re_query_cacheon the other hand only supports coarse errors at both ends of the range.re_query_cacheexposes data that is protected behind mutex guards, whereasre_querydoesn't.These differences make it impossible to abstract over both
re_queryandre_query_cachein a way that doesn't completely nullify the advantages of each respective API.Because we can't abstract these differences away, we have to duplicate a lot of the logic between the two, and this logic ends up behaving in subtly different ways, every time. And because Rust is Rust, those different types and traits poison all neighbor functions and suddenly you have two maintain two separate code bases. It's basically a homegrown case of function coloring.
This creates a never ending stream of issues in the code, which begs the question: why do we have uncached APIs to start with?
The reason is that, because of limitations in our data and caching models, we are currently forced to not cache certain things, such as images and meshes, else the memory overhead would become unmanageable.
The only way to fix these limitations is to address these two issues:
Fixing this would remove the need for the deserialization cache, which means not having to keep yet another extra copy of images and meshes -> less memory pressure.
Fixing this would prevent all the different caching layers from growing indefinitely -> less memory pressure.
Fixing these issues is no small task.
In the mean time, I might try and see if it's possible to tweak the cached APIs so that we can disable caching for specific components. It's ugly and weird and non-sensical, but it's still infinitely better than the hell we have to deal with right now.