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
{{ message }}
Repository navigation
[BUG] store.clear does not trigger a refetch in the collected stream (not sure if this is a bug or expected behavior) #731
In our application we have instances of the Store that use cache5 in the source of truth.
In some cases we need to invalidate the content of the store and we use store.clear(), but even if the cache is cleared (because deleteAll is invoked), no new values are emitted from the store.stream(..) ).
To Reproduce
Steps to reproduce the behavior:
Let's suppose we have a:
class Store5Cache:
Cache<MyKey, MyValue> by CacheBuilder<MyKey, MyValue>().build()
@KM-wilmaa Thanks for the report and the cache5 / nonFlowReader repro. I traced this on current main (74a5988, 5.1.0-beta01). It still happens, and it looks like the current contract rather than a regression from 5.0.0.
Store.clear(key) and Store.clear() are documented as purges: they invalidate the memory cache and call SourceOfTruth.delete / deleteAll. They do not update the remote source, and they do not restart an active stream. Existing tests only cover a new read after clear, which does fetch again (ClearStoreByKeyTests, ClearAllStoreTests).
For this setup that is enforced by three separate mechanisms:
SourceOfTruth.of(nonFlowReader = ...) reads once (flow { emit(realReader(key)) }). deleteAll does not re-subscribe that reader. SourceOfTruthWithBarrier restarts readers around writes, but delete / deleteAll bypass the barrier.
StoreReadRequest.cached(key, refresh = true) completes the one-shot network lock when the stream starts. A later disk null does not arm a second fetch. That is also true for a Flow-backed source of truth that emits null after a row disappears.
With no active collector, clear does not call the fetcher. localOnly never fetches.
So after clear(), the same collector keeps its last value until it is cancelled and collected again.
Could you confirm which contract you want?
A. Purge only (current): clear / clear(key) do not refetch. Callers that want new data collect again, or call fresh / stream(cached(refresh = true)) again.
B. Refetch active streams: clear(key) refetches collectors of that key with fetch = true, and clear() does the same per active key, still de-duplicated by FetcherController. localOnly stays local. This would be a behavior change for a stable API (clear(key)); clear() is still experimental.
I would not implement B without that confirmation, because a clear() during logout while a screen is still collecting would hit the network and refill the caches.
Activity
djain2405 commentedon Oct 16, 2026
@KM-wilmaa Thanks for the report and the cache5 / nonFlowReader repro. I traced this on current main (74a5988, 5.1.0-beta01). It still happens, and it looks like the current contract rather than a regression from 5.0.0.
Store.clear(key) and Store.clear() are documented as purges: they invalidate the memory cache and call SourceOfTruth.delete / deleteAll. They do not update the remote source, and they do not restart an active stream. Existing tests only cover a new read after clear, which does fetch again (ClearStoreByKeyTests, ClearAllStoreTests).
For this setup that is enforced by three separate mechanisms:
SourceOfTruth.of(nonFlowReader = ...) reads once (flow { emit(realReader(key)) }). deleteAll does not re-subscribe that reader. SourceOfTruthWithBarrier restarts readers around writes, but delete / deleteAll bypass the barrier.
StoreReadRequest.cached(key, refresh = true) completes the one-shot network lock when the stream starts. A later disk null does not arm a second fetch. That is also true for a Flow-backed source of truth that emits null after a row disappears.
With no active collector, clear does not call the fetcher. localOnly never fetches.
So after clear(), the same collector keeps its last value until it is cancelled and collected again.
Could you confirm which contract you want?
A. Purge only (current): clear / clear(key) do not refetch. Callers that want new data collect again, or call fresh / stream(cached(refresh = true)) again.
B. Refetch active streams: clear(key) refetches collectors of that key with fetch = true, and clear() does the same per active key, still de-duplicated by FetcherController. localOnly stays local. This would be a behavior change for a stable API (clear(key)); clear() is still experimental.
I would not implement B without that confirmation, because a clear() during logout while a screen is still collecting would hit the network and refill the caches.