[mastodon-client] Refresh user data in background on UserConverter.encode

This commit is contained in:
Laura Hausmann 2023-10-25 14:15:03 +02:00
parent 2575588fa3
commit 7c56ee348b
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
3 changed files with 20 additions and 13 deletions

View file

@ -12,6 +12,7 @@ import { Cache } from "@/misc/cache.js";
import { IMentionedRemoteUsers } from "@/models/entities/note.js"; import { IMentionedRemoteUsers } from "@/models/entities/note.js";
import { UserProfile } from "@/models/entities/user-profile.js"; import { UserProfile } from "@/models/entities/user-profile.js";
import { RecursionLimiter } from "@/models/repositories/user-profile.js"; import { RecursionLimiter } from "@/models/repositories/user-profile.js";
import { promiseEarlyReturn } from "@/prelude/promise.js";
const logger = remoteLogger.createSubLogger("resolve-user"); const logger = remoteLogger.createSubLogger("resolve-user");
const uriHostCache = new Cache<string>("resolveUserUriHost", 60 * 60 * 24); const uriHostCache = new Cache<string>("resolveUserUriHost", 60 * 60 * 24);
@ -27,11 +28,12 @@ type ProfileMention = {
}; };
}; };
type refreshType = 'refresh' | 'refresh-in-background' | 'refresh-timeout-1500ms' | 'no-refresh';
export async function resolveUser( export async function resolveUser(
username: string, username: string,
host: string | null, host: string | null,
refresh: boolean = true, refresh: refreshType = 'refresh',
awaitRefresh: boolean = true,
limiter: RecursionLimiter = new RecursionLimiter(20) limiter: RecursionLimiter = new RecursionLimiter(20)
): Promise<User> { ): Promise<User> {
const usernameLower = username.toLowerCase(); const usernameLower = username.toLowerCase();
@ -118,7 +120,7 @@ export async function resolveUser(
// If user information is out of date, return it by starting over from WebFinger // If user information is out of date, return it by starting over from WebFinger
if ( if (
refresh && awaitRefresh && ( (refresh === 'refresh' || refresh === 'refresh-timeout-1500ms') && (
user.lastFetchedAt == null || user.lastFetchedAt == null ||
Date.now() - user.lastFetchedAt.getTime() > 1000 * 60 * 60 * 24 Date.now() - user.lastFetchedAt.getTime() > 1000 * 60 * 60 * 24
) )
@ -176,9 +178,15 @@ export async function resolveUser(
); );
} }
await updatePerson(fingerRes.self.href); if (refresh === 'refresh') {
await updatePerson(fingerRes.self.href);
logger.info(`return resynced remote user: ${finalAcctLower}`);
}
else if (refresh === 'refresh-timeout-1500ms') {
const res = await promiseEarlyReturn(updatePerson(fingerRes.self.href), 1500);
logger.info(`return possibly resynced remote user: ${finalAcctLower}`);
}
logger.info(`return resynced remote user: ${finalAcctLower}`);
return await Users.findOneBy({ uri: fingerRes.self.href }).then((u) => { return await Users.findOneBy({ uri: fingerRes.self.href }).then((u) => {
if (u == null) { if (u == null) {
throw new Error("user not found"); throw new Error("user not found");
@ -186,10 +194,10 @@ export async function resolveUser(
return u; return u;
} }
}); });
} else if (refresh && !awaitRefresh && (user.lastFetchedAt == null || Date.now() - user.lastFetchedAt.getTime() > 1000 * 60 * 60 * 24)) { } else if (refresh === 'refresh-in-background' && (user.lastFetchedAt == null || Date.now() - user.lastFetchedAt.getTime() > 1000 * 60 * 60 * 24)) {
// Run the refresh in the background // Run the refresh in the background
// noinspection ES6MissingAwait // noinspection ES6MissingAwait
resolveUser(username, host, true, true, limiter); resolveUser(username, host, 'refresh', limiter);
} }
logger.info(`return existing remote user: ${acctLower}`); logger.info(`return existing remote user: ${acctLower}`);
@ -199,7 +207,7 @@ export async function resolveUser(
export async function resolveMentionToUserAndProfile(username: string, host: string | null, objectHost: string | null, limiter: RecursionLimiter) { export async function resolveMentionToUserAndProfile(username: string, host: string | null, objectHost: string | null, limiter: RecursionLimiter) {
return profileMentionCache.fetch(`${username}@${host ?? objectHost}`, async () => { return profileMentionCache.fetch(`${username}@${host ?? objectHost}`, async () => {
try { try {
const user = await resolveUser(username, host ?? objectHost, false, false, limiter); const user = await resolveUser(username, host ?? objectHost, 'no-refresh', limiter);
const profile = await UserProfiles.findOneBy({ userId: user.id }); const profile = await UserProfiles.findOneBy({ userId: user.id });
const data = { username, host: host ?? objectHost }; const data = { username, host: host ?? objectHost };

View file

@ -6,7 +6,7 @@ import { populateEmojis } from "@/misc/populate-emojis.js";
import { escapeMFM } from "@/server/api/mastodon/converters/mfm.js"; import { escapeMFM } from "@/server/api/mastodon/converters/mfm.js";
import mfm from "mfm-js"; import mfm from "mfm-js";
import { awaitAll } from "@/prelude/await-all.js"; import { awaitAll } from "@/prelude/await-all.js";
import { AccountCache } from "@/server/api/mastodon/helpers/user.js"; import { AccountCache, UserHelpers } from "@/server/api/mastodon/helpers/user.js";
import { MfmHelpers } from "@/server/api/mastodon/helpers/mfm.js"; import { MfmHelpers } from "@/server/api/mastodon/helpers/mfm.js";
import { MastoContext } from "@/server/api/mastodon/index.js"; import { MastoContext } from "@/server/api/mastodon/index.js";
import { IMentionedRemoteUsers } from "@/models/entities/note.js"; import { IMentionedRemoteUsers } from "@/models/entities/note.js";
@ -99,6 +99,8 @@ export class UserConverter {
bot: u.isBot, bot: u.isBot,
discoverable: u.isExplorable discoverable: u.isExplorable
}).then(p => { }).then(p => {
// noinspection ES6MissingAwait
UserHelpers.updateUserInBackground(u);
cache.accounts.push(p); cache.accounts.push(p);
return p; return p;
}); });

View file

@ -245,7 +245,7 @@ export class UserHelpers {
if (p) return p; if (p) return p;
throw new MastoApiError(404); throw new MastoApiError(404);
}) })
: resolveUser(split[0], split[1], true, false).catch(() => { : resolveUser(split[0], split[1], 'no-refresh').catch(() => {
throw new MastoApiError(404); throw new MastoApiError(404);
}); });
} }
@ -522,9 +522,6 @@ export class UserHelpers {
public static async getUserOr404(id: string): Promise<User> { public static async getUserOr404(id: string): Promise<User> {
return getUser(id).catch(_ => { return getUser(id).catch(_ => {
throw new MastoApiError(404); throw new MastoApiError(404);
}).then(u => {
this.updateUserInBackground(u);
return u;
}); });
} }