I just revised the implementation of “tracking” and “watching” of tags and categories:
Watching categories and tags has always been a rather limited feature. When you started watching a category you would only watch topics in that category from that time on. (with an edge case that allowed you to also watch recategorized old topics)
The new implementation now attacks the history problem in a rather clean way.
Topic tracking state
For every topic you visit Discourse will store a record with user information about said topic.
- When did you first visit it?
- What post are you up to?
- Are you tracking/watching/muting?
- and so on
When an account is first created there are no records in this table, it is created, on demand as you visit topics.
This means that on an old established forum with 200k topics we don’t need to create 200k rows per user with tracking state for every new account.
This is the original reason,
watching, used to be a “going forward from now”. I did not want to have to backfill 100s of thousands of rows when you watch a category. It would be a performance nightmare.
The new implementation attacks this issue by defining a concept on “implicitly watching”. When a new post is created we also check category and tag prefs (in addition to topic level prefs) to decide who to notify. This allows us to cleanly notify on old topics without having to carry record in topic tracking state (until the last moment).
When a new topic is entered and we create the tracking state row we also check on a user’s tag and category prefs to see if they should be watching in the initialized object.
New and tracking and watching implementation
The new watching implementation works like this
When a user watches a category/tag:
- Any old topics tracking state records that are in “tracking” or “regular” in that category become “watched” (with “you are watching this category” reason)
- We store a record to denote user is watching category
- Topics with missing state are watched implicitly, a tracking record is created when we notify users.
When a user stops watching a category/tag:
- Any watched topics in that category that were watched due to a category watch will become tracked
- We remove the record denoting user is watching category
Note: I removed the "decision making* about what to do with history from the user. Since is is fairly straightforward to “stop tracking” if needed by hitting “Dismiss”. Vast majority of the time the decision to stop watching is correct and there is not reason to involve the user here.
Tracking implementation is simpler:
- Any old topics tracking state that are in “regular” become “tracked”.
- Rest of stuff is tracked implicitly without record
We do not “stop tracking” stuff for you if you stop tracking a category, the expectation is that you will not just be fiddling with settings there and reverting is not trivial. What if you read the topic or posted in the topic or manually tracked it or met the read time? Simpler implementation is just to leave it up to users to hit the “dismiss” button if they are stuck with topics they don’t want to track.
Categories as "mailing lists"
This implementation unlocks the ability to use “category” or “tag” watches as mailing list replacements. This feature has been frequently asked for.
There is no “migration” from old system to new system. If you have a lot of “tracking state” for old topics and a “category watch” you should
- Stop watching category
- Start watching category
This will fix up all the tracking state. I will consider adding a migration for this perhaps in a week or so when the system is fully stabilized.
I hope you prefer this simplified implementation, feedback? Questions?