fix: resolve read/unread state persistence issue#48
Merged
Alam-2U merged 1 commit intorelease-ulmofrom May 7, 2026
Merged
Conversation
naincy128
approved these changes
May 7, 2026
There was a problem hiding this comment.
Pull request overview
Fixes incorrect persistence of thread read/unread state by preventing read-state calculation/return when the request lacks valid user context (avoids overwriting a previously-correct UI state on reload/tab switch).
Changes:
- Thread serializer now returns
Noneforread/unread_comments_countwhenuser_idis missing and recalculates read state via backend when present. - MySQL backend
get_read_statesnow treatsuser_id=Noneas “no user context” and returns an empty result. - Bumped package version to
0.5.9.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| forum/serializers/thread.py | Adjusts read/unread serialization to avoid using stale/invalid context and (currently) recomputes via backend. |
| forum/backends/mysql/api.py | Treats missing user context (None) as non-computable for read states. |
| forum/init.py | Version bump reflecting the fix. |
Comments suppressed due to low confidence (2)
forum/serializers/thread.py:132
get_read()now callsbackend.get_read_states()per thread, which can create an N+1 query pattern on list endpoints (andget_unread_comments_count()does a second call for the same thread). To avoid a significant performance regression, consider using the precomputedobj['read']/obj['unread_comments_count']whenuser_idis present, and/or caching/bulk-fetching read states once for the serializer instead of querying inside each field method.
course_id = obj["course_id"]
thread_key = obj["_id"]
is_read, _ = self.backend.get_read_states(
[obj["_id"]], user_id, course_id
).get(thread_key, (False, obj["comment_count"]))
forum/serializers/thread.py:156
get_unread_comments_count()repeats the sameget_read_states([obj['_id']], ...)lookup done inget_read(), doubling backend/DB work per thread. Consider reusing a single computed read-state result (e.g., memoize per thread in the serializer instance or attach it toobj) so read/unread count are derived from one backend call.
course_id = obj["course_id"]
thread_key = obj["_id"]
_, unread_count = self.backend.get_read_states(
[obj["_id"]], user_id, course_id
).get(thread_key, (False, obj["comment_count"]))
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This was referenced May 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR fixes an issue where discussion forum threads marked as read were incorrectly showing as unread after a page reload or tab switch.
Cause
Thread read state was being overwritten by requests that did not contain valid user context, causing already-read threads to appear unread.
Fix
Updated the discussion thread read-state handling to ignore requests without valid user context and preserve the correct read/unread status.
Ticket
COSMO2-904
Related PR
edx/frontend-app-discussions#30