Page MenuHomePhabricator

D14154.diff
No OneTemporary

D14154.diff

diff --git a/lib/selectors/chat-selectors.js b/lib/selectors/chat-selectors.js
--- a/lib/selectors/chat-selectors.js
+++ b/lib/selectors/chat-selectors.js
@@ -23,7 +23,7 @@
import {
getSidebarItems,
getAllInitialSidebarItems,
- getAllFinalSidebarItems,
+ getCandidateSidebarItemsForThreadList,
type SidebarItem,
} from '../shared/sidebar-item-utils.js';
import { threadInChatList, threadIsPending } from '../shared/thread-utils.js';
@@ -111,12 +111,14 @@
const getFinalChatThreadItem = async () => {
const lastUpdatedTimePromise = lastUpdatedTime();
+ const candidateSidebarItemsPromise =
+ getCandidateSidebarItemsForThreadList(sidebars);
+
const lastUpdatedTimeIncludingSidebarsPromise = (async () => {
- const lastUpdatedTimePromises = [
- lastUpdatedTimePromise,
- ...sidebars.map(sidebar => sidebar.lastUpdatedTime()),
- ];
- const lastUpdatedTimes = await Promise.all(lastUpdatedTimePromises);
+ const candidateSidebarItems = await candidateSidebarItemsPromise;
+ const lastUpdatedTimes = candidateSidebarItems.map(
+ sidebarItem => sidebarItem.lastUpdatedTime,
+ );
const max = lastUpdatedTimes.reduce((a, b) => Math.max(a, b), -1);
return max;
})();
@@ -124,16 +126,16 @@
const [
lastUpdatedTimeResult,
lastUpdatedTimeIncludingSidebars,
- allSidebarItems,
+ candidateSidebarItems,
] = await Promise.all([
lastUpdatedTimePromise,
lastUpdatedTimeIncludingSidebarsPromise,
- getAllFinalSidebarItems(sidebars),
+ candidateSidebarItemsPromise,
]);
return {
...chatThreadItemBase,
- sidebars: getSidebarItems(allSidebarItems),
+ sidebars: getSidebarItems(candidateSidebarItems),
lastUpdatedTime: lastUpdatedTimeResult,
lastUpdatedTimeIncludingSidebars: lastUpdatedTimeIncludingSidebars,
};
diff --git a/lib/shared/sidebar-item-utils.js b/lib/shared/sidebar-item-utils.js
--- a/lib/shared/sidebar-item-utils.js
+++ b/lib/shared/sidebar-item-utils.js
@@ -8,6 +8,7 @@
maxUnreadSidebars,
type SidebarInfo,
} from '../types/thread-types.js';
+import ChatThreadItemLoaderCache from '../utils/chat-thread-item-loader-cache.js';
import { threeDays } from '../utils/date-utils.js';
export type SidebarThreadItem = {
@@ -113,4 +114,82 @@
return await Promise.all(allSidebarItemPromises);
}
-export { getSidebarItems, getAllInitialSidebarItems, getAllFinalSidebarItems };
+type SidebarItemForCache = {
+ +threadInfo: ThreadInfo,
+ +mostRecentNonLocalMessage: ?string,
+ +lastUpdatedTimeIncludingSidebars: number,
+};
+
+// This async function returns a set of candidates that can be passed to
+// getSidebarItems. It avoids passing all of the sidebarInfos so that we don't
+// need to `await lastUpdatedTime()` for all of them, which we've found can be
+// expensive on Hermes. Instead, we use ChatThreadItemLoaderCache to only
+// consider the top N candidates, such that passing the results to
+// getSidebarItems would yield the same set as if we had processed every single
+// sidebar.
+async function getCandidateSidebarItemsForThreadList(
+ sidebarInfos: $ReadOnlyArray<SidebarInfo>,
+): Promise<$ReadOnlyArray<SidebarThreadItem>> {
+ const loaders = sidebarInfos.map(sidebar => ({
+ threadInfo: sidebar.threadInfo,
+ lastUpdatedAtLeastTimeIncludingSidebars: sidebar.lastUpdatedAtLeastTime,
+ lastUpdatedAtMostTimeIncludingSidebars: sidebar.lastUpdatedAtMostTime,
+ initialChatThreadItem: {
+ threadInfo: sidebar.threadInfo,
+ mostRecentNonLocalMessage: sidebar.mostRecentNonLocalMessage,
+ lastUpdatedTimeIncludingSidebars: sidebar.lastUpdatedAtLeastTime,
+ },
+ getFinalChatThreadItem: async () => {
+ const lastUpdatedTime = await sidebar.lastUpdatedTime();
+ return {
+ threadInfo: sidebar.threadInfo,
+ mostRecentNonLocalMessage: sidebar.mostRecentNonLocalMessage,
+ lastUpdatedTimeIncludingSidebars: lastUpdatedTime,
+ };
+ },
+ }));
+
+ // We want the top maxReadSidebars threads (either read or unread),
+ // and the top maxUnreadSidebars unread threads
+ const generalCache = new ChatThreadItemLoaderCache<SidebarItemForCache>(
+ loaders,
+ );
+ const unreadCache = new ChatThreadItemLoaderCache<SidebarItemForCache>(
+ loaders.filter(loader => loader.threadInfo.currentUser.unread),
+ );
+
+ const topGeneralPromise =
+ generalCache.loadMostRecentChatThreadItems(maxReadSidebars);
+ const topUnreadPromise =
+ unreadCache.loadMostRecentChatThreadItems(maxUnreadSidebars);
+ const [topGeneralResults, topUnreadResults] = await Promise.all([
+ topGeneralPromise,
+ topUnreadPromise,
+ ]);
+
+ const topResults = [
+ ...topGeneralResults.slice(0, maxReadSidebars),
+ ...topUnreadResults.slice(0, maxUnreadSidebars),
+ ];
+
+ return topResults.map(result => {
+ const {
+ threadInfo,
+ mostRecentNonLocalMessage,
+ lastUpdatedTimeIncludingSidebars,
+ } = result;
+ return {
+ type: 'sidebar',
+ threadInfo,
+ lastUpdatedTime: lastUpdatedTimeIncludingSidebars,
+ mostRecentNonLocalMessage,
+ };
+ });
+}
+
+export {
+ getSidebarItems,
+ getAllInitialSidebarItems,
+ getAllFinalSidebarItems,
+ getCandidateSidebarItemsForThreadList,
+};

File Metadata

Mime Type
text/plain
Expires
Mon, Dec 23, 1:58 AM (18 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2671532
Default Alt Text
D14154.diff (5 KB)

Event Timeline