Skip to content

Mm 68768 auto cache rolling cleanup#9958

Draft
carlisgg wants to merge 13 commits into
mainfrom
MM-68768-cache-rolling-cleanup
Draft

Mm 68768 auto cache rolling cleanup#9958
carlisgg wants to merge 13 commits into
mainfrom
MM-68768-cache-rolling-cleanup

Conversation

@carlisgg

Copy link
Copy Markdown
Contributor

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.ts
Most 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-side

Cleanup process runs daily.

Ticket Link

https://mattermost.atlassian.net/browse/MM-68768

Checklist

  • Added or updated unit tests (required for all new features)

Device Information

This PR was tested on:

  • Android 17 and iOS 26.5 emulators
  • Pixel 6A with Android 17
  • iPhone 15 with iOS 26.5

Release Note

- Adds support for auto cache cleanup setting coming from server and preventing CUI accumulation by performing rolling cleanups on cached content.

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown

Coverage Comparison Report

Generated on July 22, 2026 at 11:23:39 UTC

+-----------------+------------+------------+-----------+
| Metric          | Main       | This PR    | Diff      |
+-----------------+------------+------------+-----------+
| Lines           |     88.08% |     88.12% |     0.04% |
| Statements      |     87.94% |     87.97% |     0.03% |
| Branches        |     76.88% |     76.95% |     0.07% |
| Functions       |     87.34% |     87.30% |    -0.04% |
+-----------------+------------+------------+-----------+
| Total           |     85.06% |     85.08% |     0.02% |
+-----------------+------------+------------+-----------+

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Comment thread app/screens/pdf_viewer/pdf_viewer.tsx
Comment thread app/actions/local/ephemeral_mode/cleanup.ts
Comment thread app/actions/local/ephemeral_mode/cleanup.ts
Comment thread app/actions/local/ephemeral_mode/cleanup.ts
Comment thread app/actions/local/ephemeral_mode/cleanup.ts
@carlisgg
carlisgg requested a review from Copilot July 21, 2026 11:25
@mattermost-build mattermost-build added the E2E/Run Triggers E2E tests on both iOS and Android via Matterwick label Jul 21, 2026
@carlisgg
carlisgg removed the request for review from mattermost-code July 21, 2026 11:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.

Comment thread app/actions/local/ephemeral_mode/cleanup.ts Outdated
Comment thread app/queries/servers/post.ts Outdated
@mattermost-build mattermost-build added E2E/Run Triggers E2E tests on both iOS and Android via Matterwick and removed E2E/Run Triggers E2E tests on both iOS and Android via Matterwick labels Jul 21, 2026
@carlisgg
carlisgg requested a review from Copilot July 21, 2026 11:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.

Comment thread app/actions/local/post.ts
Comment thread app/actions/local/post.ts
@mattermost-build mattermost-build added E2E/Run Triggers E2E tests on both iOS and Android via Matterwick and removed E2E/Run Triggers E2E tests on both iOS and Android via Matterwick labels Jul 21, 2026
@carlisgg
carlisgg requested a review from Copilot July 21, 2026 12:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.

Comment thread app/managers/ephemeral_mode_manager/index.ts
Comment thread app/actions/local/ephemeral_mode/cleanup.ts
@mattermost-build mattermost-build added E2E/Run Triggers E2E tests on both iOS and Android via Matterwick and removed E2E/Run Triggers E2E tests on both iOS and Android via Matterwick labels Jul 21, 2026
@carlisgg
carlisgg requested a review from Copilot July 21, 2026 13:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.

Comment thread app/actions/websocket/index.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

  • onViewablePostsChanged only 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 (once PostList forwards 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);
        }
    }, []);

Comment thread app/components/post_list/post_list.tsx
@carlisgg
carlisgg requested a review from Copilot July 21, 2026 13:58
@mattermost-build mattermost-build added E2E/Run Triggers E2E tests on both iOS and Android via Matterwick and removed E2E/Run Triggers E2E tests on both iOS and Android via Matterwick labels Jul 21, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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, currentFileViewerPostId remains 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 {

@mattermost-build mattermost-build removed the E2E/Run Triggers E2E tests on both iOS and Android via Matterwick label Jul 21, 2026
@carlisgg
carlisgg requested a review from Copilot July 22, 2026 07:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.

Comment thread app/components/post_list/post_list.tsx Outdated
Comment thread app/actions/local/ephemeral_mode/cleanup.ts
@mattermost-build mattermost-build added the E2E/Run Triggers E2E tests on both iOS and Android via Matterwick label Jul 22, 2026
@carlisgg
carlisgg requested a review from Copilot July 22, 2026 11:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated no new comments.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

  • onViewableItemsChangedProp is only invoked after the if (!viewableItems.length) return; guard, so the new callback will never be notified when the list transitions to 0 viewable items. That can leave EphemeralStore.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);

Comment thread app/queries/servers/post.ts
@mattermost-build mattermost-build removed the E2E/Run Triggers E2E tests on both iOS and Android via Matterwick label Jul 22, 2026
@carlisgg
carlisgg requested a review from Copilot July 22, 2026 14:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

  • onViewableItemsChangedProp is currently invoked only when viewableItems.length > 0 due 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);

Comment on lines +205 to +208
useDidMount(() => {
EphemeralStore.setCurrentPlaybookRunId(playbookRunId);
return () => EphemeralStore.clearCurrentPlaybookRunId();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants