Page MenuHomePhabricator

D13981.diff
No OneTemporary

D13981.diff

diff --git a/lib/utils/fc-cache.js b/lib/utils/fc-cache.js
--- a/lib/utils/fc-cache.js
+++ b/lib/utils/fc-cache.js
@@ -33,6 +33,11 @@
| Promise<?$ReadOnlyArray<NeynarChannel>>,
};
+type QueuedChannelQuery = {
+ +channelID: string,
+ +resolve: (?NeynarChannel) => void,
+};
+
class FCCache {
client: NeynarClient;
@@ -50,6 +55,8 @@
FollowedFarcasterChannelsQueryCacheEntry,
> = new Map();
+ queuedChannelQueries: Array<QueuedChannelQuery> = [];
+
constructor(client: NeynarClient) {
this.client = client;
}
@@ -186,6 +193,15 @@
}
const fetchFarcasterChannelPromise = (async () => {
+ let channelQuery;
+ const promise = new Promise<?NeynarChannel>(resolve => {
+ channelQuery = {
+ channelID,
+ resolve,
+ };
+ this.queuedChannelQueries.push(channelQuery);
+ });
+
// First, we finish any ongoing fetches of followed channels,
// since our channel might be one of them
const fidsInFollowedChannelQueryCache = [
@@ -216,34 +232,106 @@
if (channel.id !== channelID) {
continue;
}
+ this.queuedChannelQueries = this.queuedChannelQueries.filter(
+ possibleChannelQuery => possibleChannelQuery !== channelQuery,
+ );
return channel;
}
}
}
- let farcasterChannel;
- try {
- farcasterChannel = await Promise.race([
- this.client.fetchFarcasterChannelByID(channelID),
- throwOnTimeout(`channel for ${channelID}`),
- ]);
- } catch (e) {
- console.log(e);
- return null;
+ if (this.queuedChannelQueries.length === 0) {
+ return promise;
}
- this.farcasterChannelQueryCache.set(channelID, {
- channelID,
- expirationTime: Date.now() + cacheTimeout,
- farcasterChannel,
- });
+ const channelQueries = this.queuedChannelQueries;
+ this.queuedChannelQueries = [];
+
+ const channelIDs = channelQueries.map(query => query.channelID);
+ const bulkQueryPromise = (async () => {
+ // If we only need to query for one, don't bother with the bulk API
+ if (channelIDs.length === 1) {
+ const [chanID] = channelIDs;
+
+ let farcasterChannel;
+ try {
+ farcasterChannel = await Promise.race([
+ this.client.fetchFarcasterChannelByID(chanID),
+ throwOnTimeout(`channel for ${chanID}`),
+ ]);
+ } catch (e) {
+ console.log(e);
+ return null;
+ }
+
+ this.farcasterChannelQueryCache.set(chanID, {
+ channelID: chanID,
+ expirationTime: Date.now() + cacheTimeout,
+ farcasterChannel,
+ });
+
+ return farcasterChannel ? [farcasterChannel] : [];
+ }
+
+ let farcasterChannels;
+ try {
+ farcasterChannels = await Promise.race([
+ this.client.fetchFarcasterChannelsByIDs(channelIDs),
+ throwOnTimeout(`channels for ${JSON.stringify(channelIDs)}`),
+ ]);
+ } catch (e) {
+ console.log(e);
+ return null;
+ }
+
+ const channelIDsInResultSet = new Set<string>();
+ for (const farcasterChannel of farcasterChannels) {
+ const chanID = farcasterChannel.id;
+ channelIDsInResultSet.add(chanID);
+ this.farcasterChannelQueryCache.set(chanID, {
+ channelID: chanID,
+ expirationTime: Date.now() + cacheTimeout,
+ farcasterChannel,
+ });
+ }
- return farcasterChannel;
+ for (const chanID of channelIDs) {
+ if (!channelIDsInResultSet.has(chanID)) {
+ this.farcasterChannelQueryCache.set(chanID, {
+ channelID: chanID,
+ expirationTime: Date.now() + cacheTimeout,
+ farcasterChannel: undefined,
+ });
+ }
+ }
+
+ return farcasterChannels;
+ })();
+
+ for (const query of channelQueries) {
+ const { channelID: chanID, resolve } = query;
+ void (async () => {
+ const channels = await bulkQueryPromise;
+ if (!channels) {
+ resolve(null);
+ return;
+ }
+ for (const channel of channels) {
+ if (channel.id === chanID) {
+ resolve(channel);
+ return;
+ }
+ }
+ resolve(undefined);
+ })();
+ }
+
+ return promise;
})();
this.farcasterChannelQueryCache.set(channelID, {
channelID,
- expirationTime: Date.now() + queryTimeout * 2,
+ expirationTime: Date.now() + queryTimeout * 4,
farcasterChannel: fetchFarcasterChannelPromise,
});

File Metadata

Mime Type
text/plain
Expires
Thu, Nov 21, 8:16 AM (7 h, 25 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2555289
Default Alt Text
D13981.diff (4 KB)

Event Timeline