Skip to content

client: Guard SimpleCache construction and document cache key behaviour#6560

Closed
VelikovPetar wants to merge 1 commit into
v6from
fix/video-cache-simplecache-guard-v6
Closed

client: Guard SimpleCache construction and document cache key behaviour#6560
VelikovPetar wants to merge 1 commit into
v6from
fix/video-cache-simplecache-guard-v6

Conversation

@VelikovPetar

@VelikovPetar VelikovPetar commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Backport of the same fixes applied to #6542 (port/v6-to-develop/opt-in-video-disk-cache).

  • VideoMediaCache.create() now returns VideoMediaCache? — wraps SimpleCache construction in a try-catch. A stale directory lock left by a prior crash no longer aborts ChatClient initialisation; video caching is silently disabled instead. ChatClient.kt already uses ?.let {} so the nullable return is handled transparently.
  • VideoCacheConfig KDoc — added one sentence noting that cache entries are keyed by URL path only (query parameters are stripped).
  • LRU eviction test — comment extended to acknowledge the wall-clock dependency of Thread.sleep spacing and what to do if the test becomes flaky.

Test plan

  • ./gradlew :stream-chat-android-client:testDebugUnitTest --tests "*.cache.*" passes

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved video cache startup reliability by handling cache creation failures gracefully instead of crashing.
    • URLs that differ only by query parameters now share the same video cache entry, reducing duplicate cache usage.
    • Added clearer guidance around cache behavior and updated tests to better catch cache initialization issues.

- VideoMediaCache.create() now returns VideoMediaCache? and wraps
  SimpleCache construction in a try-catch; a stale directory lock from a
  prior crash no longer aborts ChatClient initialisation — video caching
  is silently disabled instead.
- VideoCacheConfig KDoc notes that cache entries are keyed by URL path
  only (query parameters are stripped).
- LRU eviction test comment acknowledges the wall-clock dependency of
  the Thread.sleep spacing and what to do if the test becomes flaky.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@VelikovPetar VelikovPetar requested a review from a team as a code owner July 9, 2026 10:00
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

PR checklist ❌

The following issues were detected:

  • Missing required label: at least one label starting with pr:.
  • Section Goal is missing or empty.
  • Section Implementation is missing or empty.
  • Section Testing is missing or empty.

What we check

  1. Title is concise (5–18 words) unless labeled pr:ignore-for-release.
  2. At least one pr: label exists (e.g., pr:bug, pr:new-feature).
  3. Sections ### Goal, ### Implementation, and ### Testing contain content, unless authored by dependabot.

@VelikovPetar

Copy link
Copy Markdown
Contributor Author

Closing — will be reopened via the correct workflow.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

VideoMediaCache.create now returns a nullable VideoMediaCache?, catching and logging construction exceptions instead of propagating them. Documentation for cache key behavior (URL path only, query stripped) was clarified. Test call sites were updated with !! to force-unwrap the previously nullable-compatible results.

Changes

VideoMediaCache Nullable Creation

Layer / File(s) Summary
Nullable create() implementation and docs
stream-chat-android-client/.../cache/internal/VideoMediaCache.kt, stream-chat-android-client/.../cache/StreamCacheConfig.kt
create signature changed to VideoMediaCache?, wraps SimpleCache construction in try/catch to log and return null on failure; cache config docs clarify entries are keyed by URL path with query parameters stripped.
Test call sites force-unwrap create() results
stream-chat-android-client/src/test/.../StreamMediaDataSourceCacheIntegrationTest.kt, stream-chat-android-client/src/test/.../VideoMediaCacheTest.kt
Tests force-unwrap VideoMediaCache.create(...) at setup, cache release/recreation, and eviction cache creation; a comment clarifies wall-clock timing sensitivity in the LRU eviction test.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: gpunto, andremion

Poem

A cache that once crashed with a sigh,
Now logs its woes and says "null", not "why?"
Query strings stripped, paths clean and neat,
Tests unwrap tightly, no null defeat.
🐰 Hop, hop — safer disk cache today!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description skips the required template sections and only provides a summary and test plan. Add the required Goal, Implementation, UI Changes, Testing details, contributor/reviewer checklists, and GIF section to match the template.
Docstring Coverage ⚠️ Warning Docstring coverage is 44.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly reflects the main change: guarding SimpleCache construction and documenting cache key behavior.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/video-cache-simplecache-guard-v6

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@stream-chat-android-client/src/main/java/io/getstream/chat/android/client/cache/internal/VideoMediaCache.kt`:
- Around line 150-161: The VideoMediaCache.create path leaks the
StandaloneDatabaseProvider when SimpleCache construction fails, because the
provider is created successfully but never closed if the catch block is reached.
Move dbProvider handling so it is declared outside the try in
VideoMediaCache.create, and explicitly close it in the catch before returning
null; keep the existing logger.e message and ensure the cleanup covers the
failed SimpleCache(appContext, ...) construction path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3c2907f9-5498-4286-8bda-208c045a4198

📥 Commits

Reviewing files that changed from the base of the PR and between 7978e0a and 939f175.

📒 Files selected for processing (4)
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/cache/StreamCacheConfig.kt
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/cache/internal/VideoMediaCache.kt
  • stream-chat-android-client/src/test/java/io/getstream/chat/android/client/cache/internal/StreamMediaDataSourceCacheIntegrationTest.kt
  • stream-chat-android-client/src/test/java/io/getstream/chat/android/client/cache/internal/VideoMediaCacheTest.kt

Comment on lines +150 to +161
try {
val dbProvider = StandaloneDatabaseProvider(appContext)
val simpleCache = SimpleCache(
cacheDir,
LeastRecentlyUsedCacheEvictor(config.maxSizeBytes),
dbProvider,
)
VideoMediaCache(simpleCache, dbProvider, key).also { instances[key] = it }
} catch (@Suppress("TooGenericExceptionCaught") e: Exception) {
logger.e(e) { "[create] Failed to construct SimpleCache at '$key'; video caching disabled." }
null
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Close StandaloneDatabaseProvider when SimpleCache construction fails.

If StandaloneDatabaseProvider(appContext) succeeds but SimpleCache(...) throws, dbProvider is leaked — it holds an open SQLite handle that is only closed in release(), which never runs for a failed create. Since the failed attempt is not registered in instances, a subsequent create for the same directory would open a second database provider while the first remains open.

🔧 Proposed fix: declare `dbProvider` outside the try and close it in the catch
-                try {
-                    val dbProvider = StandaloneDatabaseProvider(appContext)
+                var dbProvider: StandaloneDatabaseProvider? = null
+                try {
+                    dbProvider = StandaloneDatabaseProvider(appContext)
                     val simpleCache = SimpleCache(
                         cacheDir,
                         LeastRecentlyUsedCacheEvictor(config.maxSizeBytes),
                         dbProvider,
                     )
                     VideoMediaCache(simpleCache, dbProvider, key).also { instances[key] = it }
                 } catch (`@Suppress`("TooGenericExceptionCaught") e: Exception) {
+                    dbProvider?.let {
+                        try {
+                            it.close()
+                        } catch (`@Suppress`("TooGenericExceptionCaught") closeEx: Exception) {
+                            logger.e(closeEx) { "[create] Failed to close StandaloneDatabaseProvider after cache construction failure" }
+                        }
+                    }
                     logger.e(e) { "[create] Failed to construct SimpleCache at '$key'; video caching disabled." }
                     null
                 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@stream-chat-android-client/src/main/java/io/getstream/chat/android/client/cache/internal/VideoMediaCache.kt`
around lines 150 - 161, The VideoMediaCache.create path leaks the
StandaloneDatabaseProvider when SimpleCache construction fails, because the
provider is created successfully but never closed if the catch block is reached.
Move dbProvider handling so it is declared outside the try in
VideoMediaCache.create, and explicitly close it in the catch before returning
null; keep the existing logger.e message and ensure the cleanup covers the
failed SimpleCache(appContext, ...) construction path.

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 5.26 MB 5.32 MB 0.05 MB 🟢
stream-chat-android-offline 5.49 MB 5.54 MB 0.04 MB 🟢
stream-chat-android-ui-components 10.64 MB 10.75 MB 0.11 MB 🟢
stream-chat-android-compose 12.87 MB 12.96 MB 0.09 MB 🟢

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.

1 participant