Skip to content

Comments

⚡ Bolt: Global Media Cache#750

Open
kevinaboos wants to merge 4 commits intomainfrom
bolt/global-media-cache-7471736247335357365
Open

⚡ Bolt: Global Media Cache#750
kevinaboos wants to merge 4 commits intomainfrom
bolt/global-media-cache-7471736247335357365

Conversation

@kevinaboos
Copy link
Member

⚡ Bolt: Global Media Cache

💡 What:
Moved MediaCache from being an instance per RoomScreen (in TimelineUiState) to a global thread-local GLOBAL_MEDIA_CACHE. Updated the cache logic to support multiple subscribers (senders) for a single media request, ensuring that all timelines waiting for a specific media item are notified when it loads.

🎯 Why:
Previously, if the same image (e.g., a custom sticker or a shared meme) was displayed in multiple rooms, it would be fetched and cached separately for each room. This wasted memory and bandwidth. Additionally, removing MediaCache from TimelineUiState reduces the size of the state struct.

📊 Impact:

  • Reduced Memory Usage: Deduplicates media data in memory across rooms.
  • Reduced Network Traffic: Prevents redundant fetches for the same media URI.
  • Deduplicated Requests: If multiple rooms request the same media simultaneously, only one network request is made, and all are notified.

🔬 Measurement:
Code analysis confirms that MediaCache is now a singleton (per thread) and try_get_media_or_fetch handles multiple subscribers. Verification was done via manual code review of the refactoring due to environment limitations on running the full build/test suite.


PR created automatically by Jules for task 7471736247335357365 started by @kevinaboos

- Move MediaCache to a global thread-local storage.
- Update MediaCacheEntry to support multiple subscribers for pending requests.
- Remove per-room MediaCache from TimelineUiState.
- Update RoomScreen, LinkPreview, and RoomImageViewer to use the global cache.
- Reduce memory usage and network requests for shared media.

Co-authored-by: kevinaboos <1139460+kevinaboos@users.noreply.github.com>
@google-labs-jules
Copy link
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

google-labs-jules bot and others added 3 commits February 17, 2026 16:39
- Remove stale `media_cache` initialization in `TimelineUiState`.
- Update `populate_matrix_image_modal` call to pass `update_sender`.
- Update `MediaCacheEntry::Requested` match pattern to handle tuple variant.
- Import `MediaCacheEntry` where needed or ensure accessibility.

Co-authored-by: kevinaboos <1139460+kevinaboos@users.noreply.github.com>
- Fix usage of `media_cache` which was removed from `TimelineUiState`.
- Initialize `update_sender` in `TimelineUiState` constructor.
- Fix logic in `handle_image_click` to correctly pass `update_sender` to `populate_matrix_image_modal`.
- Fix `MediaCacheEntry` pattern matching.

Co-authored-by: kevinaboos <1139460+kevinaboos@users.noreply.github.com>
- Reverted incorrect change in `populate_image_message_content` that was trying to call `populate_matrix_image_modal` with an undefined variable.
- Restored `fetch_and_show_media_source` call which is the correct logic for the timeline view.
- Ensured `handle_image_click` correctly opens the modal using the available `update_sender`.

Co-authored-by: kevinaboos <1139460+kevinaboos@users.noreply.github.com>
@kevinaboos
Copy link
Member Author

Doesn't this also make it way slower to query the cache for a given specific timeline, as the cache will be HUGE now with millions of entries?

You're assuming that images are shared across multiple rooms, which is actually quite unlikely and rare in practice.

@google-labs-jules
Copy link
Contributor

Doesn't this also make it way slower to query the cache for a given specific timeline, as the cache will be HUGE now with millions of entries?

You're assuming that images are shared across multiple rooms, which is actually quite unlikely and rare in practice.

While the cache will contain more entries, HashMap lookups are O(1) on average, so lookup performance is not significantly affected by the size of the map (unlike a list).

Regarding memory usage: effectively, the previous implementation also kept all media in memory indefinitely, because TimelineUiState (which contained the per-room MediaCache) is persisted in the global TIMELINE_STATES map for all visited rooms. Therefore, the total memory usage was already the sum of all media from all visited rooms.

Moving to a global cache:

  1. Reduces memory for any shared media (stickers, emojis, forwarded images).
  2. Does not increase memory for unique media (it just stores it in one place instead of many).
  3. Enables future optimization: It allows us to easily implement a global LRU eviction policy to limit total media memory usage, which was much harder to coordinate across disjoint per-room caches.

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