Changeset View
Standalone View
keyserver/src/fetchers/thread-fetchers.js
Show First 20 Lines • Show All 302 Lines • ▼ Show 20 Lines | |||||
async function serverThreadInfoFromMessageInfo( | async function serverThreadInfoFromMessageInfo( | ||||
message: RawMessageInfo | MessageInfo, | message: RawMessageInfo | MessageInfo, | ||||
): Promise<?ServerThreadInfo> { | ): Promise<?ServerThreadInfo> { | ||||
const threadID = message.threadID; | const threadID = message.threadID; | ||||
const threads = await fetchServerThreadInfos(SQL`t.id = ${threadID}`); | const threads = await fetchServerThreadInfos(SQL`t.id = ${threadID}`); | ||||
return threads.threadInfos[threadID]; | return threads.threadInfos[threadID]; | ||||
} | } | ||||
async function fetchThreadsWithLatestMessages( | |||||
ashoat: Hmm... one concern here is that we're fetching the parents for a sidebar, but not including… | |||||
michalAuthorUnsubmitted Done Inline ActionsIt should be fine (but kinda brittle) in this case. The cutoff for displaying the sidebars is 3 days, while we stop sending messages after 2 weeks. So sidebars that would be fetched with this endpoint won't be displayed anyway. michal: It should be fine (but kinda brittle) in this case. The cutoff for displaying the sidebars is 3… | |||||
ashoatUnsubmitted Not Done Inline ActionsThat appears to only be true if the sidebars are marked as read. If the sidebars are unread, it looks like we show up to 5 of them indefinitely ashoat: That appears to only be true if the sidebars are marked as read. If the sidebars are unread, it… | |||||
michalAuthorUnsubmitted Done Inline ActionsYes, but unread status is kept in threadInfo which is always available. And there's no problem with displaying sidebars without messages in messageStore because they don't have a preview. michal: Yes, but unread status is kept in threadInfo which is always available. And there's no problem… | |||||
ashoatUnsubmitted Not Done Inline ActionsThen why are we querying for sidebars at all? It seems like what we want is a list of top-level chats, ordered by the most recent message in that chat or any of its sidebars. Instead, you're querying for a list of all chats (including sidebars), ordered by the most recent message in that chat. If you could find a MySQL query that gives you the result you want directly, we'll see the following benefits:
I assume such a query would have to be more complicated, so it would be good if you can give me an example query I can run on my production keyserver, so we can audit the performance of the new query. What do you think? ashoat: Then why are we querying for sidebars at all?
It seems like what we want is a list of top… | |||||
userID: string, | |||||
home: boolean, | |||||
fromMessageID: string, | |||||
): Promise<{ | |||||
+allThreads: $ReadOnlyArray<string>, | |||||
+threadsExcludingParents: Set<string>, | |||||
}> { | |||||
const query = SQL` | |||||
SELECT m.thread, t.type, t.parent_thread_id | |||||
FROM memberships m | |||||
LEFT JOIN threads t ON m.thread = t.id | |||||
WHERE m.user = ${userID} AND | |||||
m.role > 0 AND | |||||
m.last_message < ${fromMessageID} AND | |||||
JSON_EXTRACT(m.subscription, '$.home') IS ${home} | |||||
ORDER BY m.last_message DESC | |||||
LIMIT 25 | |||||
`; | |||||
const [result] = await dbQuery(query); | |||||
const allThreads = new Set(); | |||||
const threadsExcludingParents = new Set(); | |||||
for (const row of result) { | |||||
allThreads.add(row.thread.toString()); | |||||
threadsExcludingParents.add(row.thread.toString()); | |||||
if (row.type === threadTypes.SIDEBAR) { | |||||
allThreads.add(row.parent_thread_id); | |||||
} | |||||
} | |||||
return { | |||||
allThreads: [...allThreads], | |||||
threadsExcludingParents, | |||||
}; | |||||
} | |||||
export { | export { | ||||
fetchServerThreadInfos, | fetchServerThreadInfos, | ||||
fetchThreadInfos, | fetchThreadInfos, | ||||
rawThreadInfosFromServerThreadInfos, | rawThreadInfosFromServerThreadInfos, | ||||
verifyThreadIDs, | verifyThreadIDs, | ||||
verifyThreadID, | verifyThreadID, | ||||
determineThreadAncestry, | determineThreadAncestry, | ||||
personalThreadQuery, | personalThreadQuery, | ||||
fetchPersonalThreadID, | fetchPersonalThreadID, | ||||
serverThreadInfoFromMessageInfo, | serverThreadInfoFromMessageInfo, | ||||
fetchThreadsWithLatestMessages, | |||||
}; | }; |
Hmm... one concern here is that we're fetching the parents for a sidebar, but not including "sibling sidebars" that might be displayed in the UI. If the user scrolls down and we load another sibling sidebar, that sibling would be displayed above where the user scrolled to, so they will miss it. I wonder if we should do some work to make sure we include all of the sidebars that would normally be rendered in the UI today (there is an algorithm for determing which sidebars to show here)