-
Notifications
You must be signed in to change notification settings - Fork 358
feat(threads): store the "bump_stamps" in the thread subscriptions #5589
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #5589 +/- ##
==========================================
- Coverage 88.65% 88.65% -0.01%
==========================================
Files 345 345
Lines 96132 96225 +93
Branches 96132 96225 +93
==========================================
+ Hits 85230 85312 +82
+ Misses 6676 6674 -2
- Partials 4226 4239 +13 ☔ View full report in Codecov by Sentry. |
CodSpeed Performance ReportMerging #5589 will not alter performanceComparing Summary
|
poljar
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really requesting many changes but I'm not sure if I misunderstood something of if this is incorrect in some edge cases.
| impl ThreadSubscriptionStatus { | ||
| /// Represent the status as a static string ref, for it to be stored into a | ||
| /// persistent format. | ||
| /// | ||
| /// Note: this is serialized in some databases implementations, so make sure | ||
| /// to not change it lightly, and keep it in sync with | ||
| /// [`Self::from_str`]. | ||
| pub fn as_str(&self) -> &'static str { | ||
| match self { | ||
| ThreadSubscriptionStatus::Subscribed { automatic } => { | ||
| if *automatic { | ||
| "automatic" | ||
| } else { | ||
| "manual" | ||
| } | ||
| } | ||
| ThreadSubscriptionStatus::Unsubscribed => "unsubscribed", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason why we're using as_str() for database storage instead of our usual Serialize serde stuff?
Additionally if we use any of the more usual traits for this, then we can use insta to add more protection to this. Display, Debug, or Serialize would work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It makes for a denser format to use as_str() (it flattens the subscription into a string, instead of a JSON map), and it allows future use cases like "find the list of all subscribed threads in this room" (which we couldn't do if we serialized the ThreadSubscription as a blob inside the DB, b/o encrypted DBs).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well I'm not saying that you shouldn't flatten out the serialized format, just that a different trait is usually used for this. A custom Serialize implementation can produce the same serialized format as you already have.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it'd be wrong to use a custom Serialize impl in the sqlite impl, which has status and bump_stamps columns.
| (Some(prev_bump), Some(new_bump)) if new_bump <= prev_bump => { | ||
| return Ok(()); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, but this will avoid a transition from unsubscribed to subscribed if the bump stamps are equal, no?
Is such a transition impossible or undesirable?
Furthermore, as you said, this logic is duplicated a couple of times. Can't we make the bump stamp a separate type BumpStamp(u64) and the implement either a is_better() method or even add a PartialEq implementation that will contain this logic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's not possible, because the bump stamps will increase if the thread subscription goes from subscribed to unsubscribed. My understanding is that same bump stamp = same subscription information; it forms an "index" when combined with the (room id, thread root event id) pair. Will ask to clarify this in the MSC, and maybe I can add a small comment here.
But yeah, the duplication isn't great, will find a way to avoid it.
…stored thread subscription
…nal consumers, and rename previous one to `StoredThreadSubscription` External consumers are likely not interested about unsubscriptions and the bump stamp values themselves, so let's not expose these to them.
…correct upsert semantics
bb71983 to
32ef255
Compare
See also MSC4308 for details about the bumpstamps. They allow to order two subscriptions, and avoid bad race conditions where one would get a thread subscription by both paginating and sync'ing them.
It's a bit of a shame that the code comparing bumpstamps looks a bit duplicated, but note that, among the 3 implementations, only 2 are duplicated, for real: the last one uses the
PersistedThreadSubscriptionin lieu ofStoreThreadSubscriptiontype.Part of #5038.