-
-
Notifications
You must be signed in to change notification settings - Fork 7.5k
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
recent_view: Refactor conversation data to prevent fetching messages. #30137
base: main
Are you sure you want to change the base?
Conversation
const sample_messages = []; | ||
sample_messages[0] = { | ||
stream_id: stream1, | ||
id: (id += 1), | ||
id: 1, |
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 changed these to numbers so it would be easier to find the messages by their ids when setting up tests, but I can change it back if that's preferred.
5f629a8
to
cf157e0
Compare
web/src/recent_view_data.ts
Outdated
|
||
if (msg.type === "private") { | ||
// Display recipient contains user information for DMs. | ||
assert(typeof msg.display_recipient !== "string"); |
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.
This is just preserving old logic, but ideally we'd refactor the message type so that we don't have to make this assertion.
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.
So, we need to also think about how we are going to update the properties here which can change.
Like we used to update unread_count
by simply calling inplace_rerender
since that would get the latest unread count from last_msg_id
and update it, but that won't work anymore since we are using a cached value.
We need to hook server_events for this. We could use the process_message
as an opportunity to update them but that won't be reliabl, so probably a good idea to skip updating them here.
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.
Agreed with @amanagr that we're going to need to be very careful to make sure things that could change any of the data that you're caching here, which is quite a lot (name changes go into display_recipient
, etc.).
Realistically that means this is the wrong design; we should be only caching the metadata that we think is stable, not computed properties like display_recipient
, which can just as well be processed later.
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.
Just to lay out a bit more how I'm thinking this should work: A server API endpoint that sent data on what recent conversations exist would not include the following:
- unread data -- clients should combine its unread data set with the recent view data to display a complete view.
- Metadata on users, like names/etc. that go into display recipients -- I'd expect it to just have stream/user IDs.
Instead, I'd expect it to just have (1) list of participated user IDs, (2) last_message_id
, (3) last_message_timestamp
, (4) type and location of the message.
So I think it's correct for the data structure we're defining here to have those properties as well, and rely on combining that reasonably normalized data set with the unread
data set and people/stream_data
data sets, just like it will with which topics are followed in order to display that detail.
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 just pushed to this branch with an extra commit to try addressing this -- let me know what you think! I wasn't totally sure which data we can rely on to be stable.
participated: boolean; | ||
type: "private" | "stream"; | ||
}; | ||
type Row = ConversationData; |
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.
Do we need to define this type if they are the same?
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.
Could be an additional commit to clean that up if that's convenient.
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 wasn't sure here -- they were separate types before despite being the same. Was there a reason for that? I thought maybe there was a semantic reason for it or something. Would you prefer they both be called ConversationData
?
FYI @timabbott Aman said on CZO:
|
stream_id: number; | ||
topic: string; | ||
}, | ||
): string { |
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.
Should this instead just take a ConversationData
? Not sure why you're defining this other abbreviated type here.
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's because we call it in process_message
with a message:
const key = get_key_from_conversation_data(msg);
and ConversationData
has attributes that aren't on Message
which also aren't needed here, but these attributes I listed are on both types and are the only attributes we need here.
cf157e0
to
1bab8e1
Compare
@@ -19,7 +19,7 @@ export type DisplayRecipientUser = { | |||
email: string; | |||
full_name: string; | |||
id: number; | |||
is_mirror_dummy: boolean; | |||
is_mirror_dummy?: boolean; |
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 doesn't seem like this is used at all in the frontend, so maybe we want to remove it completely here?
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.
Yeah, looks like we can avoid sending it to the client to reduce response data. @timabbott FYI
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.
@evykassirer I think you should start a czo discussion to fast track that.
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.
// See `echo.build_display_recipient` for more on this. | ||
return { | ||
// TODO(evy): What to do here for typing purposes? Or can we assume all users are defined here? | ||
// I don't know much aobut zephyr and when it's relevant. |
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.
question here!
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.
For recent view, I think it makes sense to treat them as normal users unless we have problems generating their avatar and display user profile popover. I don't have much context here either.
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'll let @timabbott comment before removing it then
} | ||
|
||
// This mirrors the structure of `echo.build_display_recipient`, using data | ||
// found in `ConversationData`. |
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 felt like it would be pretty hard to generalize echo.build_display_recipient
to work for this case too, so I just built a variation on it for here.
1bab8e1
to
ee82b81
Compare
@timabbott this is ready for your review again. I've responded to the open comments, some I wanted to check in with you about what to do or if what I did seems right. Thanks! |
The motivation is that when we're able to provide a dedicated efficient API for the recent view, it's probably not going to preserve the invariant that any topic in this view has a message in message_store.
Further discussion here