Mm 68768 auto cache rolling cleanup#9958
Conversation
Coverage Comparison Report |
There was a problem hiding this comment.
Pull request overview
Adds a daily “rolling” auto-cache cleanup to prevent unbounded local growth of cached posts, playbook runs, and AI threads, integrating with ephemeral-mode configuration and adding UI-state-based protections to avoid evicting currently viewed content.
Changes:
- Introduces
autoCacheCleanup(daily) and wires it to run on WebSocket reconnect, gated by a server config value (MobileEphemeralModeAutoCacheCleanupDays). - Implements atomic post cleanup via SQL (
deletePostsInChannelsByCutoff) including dependent table cleanup and CRT bookkeeping adjustments. - Adds runtime protections (visible channel anchor, open thread root, file viewer post, viewed playbook run) via
EphemeralStore+ PostList viewability callbacks and relevant screens.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| app/store/ephemeral_store.ts | Adds ephemeral fields/getters/setters used to protect currently viewed content from eviction. |
| app/screens/pdf_viewer/pdf_viewer.tsx | Sets/clears file-viewer post protection while the secure PDF viewer is open. |
| app/screens/gallery/index.tsx | Sets/updates file-viewer post protection as the gallery index changes. |
| app/screens/channel/channel_post_list/channel_post_list.tsx | Tracks the oldest visible post createAt to anchor eviction protection and resets pagination behavior after cleanup. |
| app/components/post_list/post_list.tsx | Plumbs an optional onViewableItemsChanged callback up to callers. |
| app/queries/servers/post.ts | Adds query helpers used by cleanup protection calculations (active thread roots, nth-older post). |
| app/actions/local/post.ts | Adds an atomic SQL-based bulk delete by channel+cutoff with related table cleanup/bookkeeping. |
| app/actions/local/post.test.ts | Adds unit coverage validating the SQL batch content/order and error handling. |
| app/actions/local/ephemeral_mode/cleanup.ts | New centralized daily rolling cleanup for posts, AI threads, and playbook runs + protections + vacuum + stamping last-run. |
| app/actions/local/ephemeral_mode/cleanup.test.ts | Adds broad unit coverage for cutoff/protection routing, AI/playbook cleanup behavior, and last-run/vacuum behavior. |
| app/products/playbooks/database/queries/run.ts | Adds a cutoff-based query for stale playbook runs. |
| app/products/playbooks/screens/playbook_run/playbook_run.tsx | Sets/clears the “currently viewed playbook run” protection. |
| app/products/playbooks/screens/playbook_run/playbook_run.test.tsx | Updates tests to pass the new required playbookRunId prop. |
| app/products/agents/database/queries/thread.ts | Adds a cutoff-based query for stale AI threads. |
| app/managers/ephemeral_mode_manager/index.ts | Observes and stores the new auto-cleanup-days config value. |
| app/actions/websocket/index.ts | Triggers auto cache cleanup on reconnect alongside other cleanups. |
| app/constants/post.ts | Adds the protection buffer constant used when computing eviction cutoffs. |
| app/constants/database.ts | Adds a system identifier for the last auto cache cleanup run timestamp. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
app/screens/channel/channel_post_list/channel_post_list.tsx:135
onViewablePostsChangedonly updates the stored anchor when it finds at least one viewable post. If the viewport contains only non-post items (date separators, etc.) or becomes empty (oncePostListforwards empty updates), the store keeps the previous channel’s/viewport’s createAt, which can make cleanup protections stale.
Clear currentChannelOldestVisibleCreateAt when no viewable post is found.
const onViewablePostsChanged = useCallback((viewableItems: ViewToken[]) => {
let oldest = Infinity;
for (const {item, isViewable} of viewableItems) {
if (isViewable && item.type === 'post') {
const createAt = item.value.currentPost.createAt;
if (createAt < oldest) {
oldest = createAt;
}
}
}
if (oldest < Infinity) {
EphemeralStore.setCurrentChannelOldestVisibleCreateAt(oldest);
}
}, []);
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
app/screens/pdf_viewer/pdf_viewer.tsx:144
- While the PDF viewer is open, the file-viewer protection can incorrectly keep the previous post ID when the file lookup fails or returns no postId. In that case,
currentFileViewerPostIdremains set to a stale value and may exclude an unrelated post from eviction during rolling cleanup. Clear the protection on mount and only set it when a backing postId is successfully resolved, then restore the previous value on unmount.
useDidMount(() => {
let active = true;
const previousFileViewerPostId = EphemeralStore.getCurrentFileViewerPostId();
(async () => {
try {
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
app/components/post_list/post_list.tsx:393
onViewableItemsChangedPropis only invoked after theif (!viewableItems.length) return;guard, so the new callback will never be notified when the list transitions to 0 viewable items. That can leaveEphemeralStore.currentChannelOldestVisibleCreateAt(and any future consumers) stuck with a stale value until unmount/channel change. Call the prop before the empty-check so it also receives[]and can clear state when nothing is viewable.
onViewableItemsChangedProp?.(viewableItems);
if (onViewableItemsChangedListener.current) {
onViewableItemsChangedListener.current(viewableItems);
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
app/components/post_list/post_list.tsx:391
onViewableItemsChangedPropis currently invoked only whenviewableItems.length > 0due to the early return. Callers (e.g. channel cache-protection logic) can’t clear derived state when the viewport becomes empty, leaving stale values behind. Invoke the prop callback before the empty-check (and remove the later call).
onViewableItemsChangedProp?.(viewableItems);
| useDidMount(() => { | ||
| EphemeralStore.setCurrentPlaybookRunId(playbookRunId); | ||
| return () => EphemeralStore.clearCurrentPlaybookRunId(); | ||
| }); |
Summary
Auto cache cleanup for posts, playbook runs, and AI threads.
Adds automatic rolling cleanup of cached posts, playbook runs, and AI agent threads so local data doesn't grow unbounded, centralized in a new
app/actions/local/ephemeral_mode/cleanup.tsMost post cleanup processing lives in the SQL/query layer (
app/queries/servers/post.ts) to make the cleanup atomic, while playbook runs and AI threads processing lives in the JS-sideCleanup process runs daily.
Ticket Link
https://mattermost.atlassian.net/browse/MM-68768
Checklist
Device Information
This PR was tested on:
Release Note