Skip to content

feat: adding a flow wrapper for persistent cache#12

Closed
ethan-berg-kr wants to merge 2 commits intokrogerco:alphafrom
ethan-berg-kr:main
Closed

feat: adding a flow wrapper for persistent cache#12
ethan-berg-kr wants to merge 2 commits intokrogerco:alphafrom
ethan-berg-kr:main

Conversation

@ethan-berg-kr
Copy link
Copy Markdown
Collaborator

Adds a wrapper to observe changes to a cached value

@ethan-berg-kr ethan-berg-kr changed the title Adding a flow wrapper for persistent cache feat: Adding a flow wrapper for persistent cache Sep 11, 2025
@ethan-berg-kr ethan-berg-kr changed the title feat: Adding a flow wrapper for persistent cache feat: adding a flow wrapper for persistent cache Dec 9, 2025
@ethan-berg-kr ethan-berg-kr changed the base branch from main to alpha March 25, 2026 21:29
import kotlinx.coroutines.launch

/**
* MIT License
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The license headers should be the very first line of each source file. If you rebase this on main, I just added some tooling that will help with checking and applying these headers.

@@ -0,0 +1,97 @@
package com.kroger.cache.internal
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is meant to be public API, it shouldn't go in the internal package.

public class CacheFlowWrapper<T>(
private val cache: SnapshotPersistentCache<T>,
private val scope: CoroutineScope,
) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The API seems like it could be improved by making this class implement MutableStateFlow directly. That would allow for an asFlow() extension on SnapshotPersistentCache:

fileCache.asFlow(scope).collect { it }

public fun <T> SnapshotPersistentCache<T>.asFlow(scope: CoroutineScope): MutableStateFlow<T> {
    return CacheFlowWrapper<T>(this, scope)
}

And all of the MutableStateFlow members could be implemented by delegating to the internal _cacheValueState

/**
* A Wrapper class for a SnapshotPersistentCache that exposes changes to the cache via a flow.
*
* **Note this works best when used as a singleton
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

works best when used as a singleton

This note needs to be more specific. Does using two wrappers on a cache expose you to data correctness issues? Or is this just about performance?

import org.junit.jupiter.api.Test

@OptIn(ExperimentalCoroutinesApi::class)
class CacheFlowWrapperTest {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of these tests were failing when I ran them locally 🫤

@krogrammer krogrammer closed this Mar 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants