Improve server performance
This commit is contained in:
parent
d3c8368b0c
commit
8aa089178a
|
@ -0,0 +1,25 @@
|
||||||
|
export class Cache<T> {
|
||||||
|
private cache: Map<string | null, { date: number; value: T; }>;
|
||||||
|
private lifetime: number;
|
||||||
|
|
||||||
|
constructor(lifetime: Cache<never>['lifetime']) {
|
||||||
|
this.lifetime = lifetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set(key: string | null, value: T):void {
|
||||||
|
this.cache.set(key, {
|
||||||
|
date: Date.now(),
|
||||||
|
value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public get(key: string | null): T | null {
|
||||||
|
const cached = this.cache.get(key);
|
||||||
|
if (cached == null) return null;
|
||||||
|
if ((Date.now() - cached.date) > this.lifetime) {
|
||||||
|
this.cache.delete(key);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return cached.value;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,11 +7,15 @@ import { instanceChart } from '../../services/chart';
|
||||||
import { fetchInstanceMetadata } from '../../services/fetch-instance-metadata';
|
import { fetchInstanceMetadata } from '../../services/fetch-instance-metadata';
|
||||||
import { fetchMeta } from '../../misc/fetch-meta';
|
import { fetchMeta } from '../../misc/fetch-meta';
|
||||||
import { toPuny } from '../../misc/convert-host';
|
import { toPuny } from '../../misc/convert-host';
|
||||||
|
import { Cache } from '../../misc/cache';
|
||||||
|
import { Instance } from '../../models/entities/instance';
|
||||||
|
|
||||||
const logger = new Logger('deliver');
|
const logger = new Logger('deliver');
|
||||||
|
|
||||||
let latest: string | null = null;
|
let latest: string | null = null;
|
||||||
|
|
||||||
|
const suspendedHostsCache = new Cache<Instance[]>(1000 * 60 * 60);
|
||||||
|
|
||||||
export default async (job: Bull.Job) => {
|
export default async (job: Bull.Job) => {
|
||||||
const { host } = new URL(job.data.to);
|
const { host } = new URL(job.data.to);
|
||||||
|
|
||||||
|
@ -22,12 +26,15 @@ export default async (job: Bull.Job) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// isSuspendedなら中断
|
// isSuspendedなら中断
|
||||||
const suspendedHosts = await Instances.find({
|
let suspendedHosts = suspendedHostsCache.get(null);
|
||||||
|
if (suspendedHosts == null) {
|
||||||
|
suspendedHosts = await Instances.find({
|
||||||
where: {
|
where: {
|
||||||
isSuspended: true
|
isSuspended: true
|
||||||
},
|
},
|
||||||
cache: 60 * 1000
|
|
||||||
});
|
});
|
||||||
|
suspendedHostsCache.set(null, suspendedHosts);
|
||||||
|
}
|
||||||
if (suspendedHosts.map(x => x.host).includes(toPuny(host))) {
|
if (suspendedHosts.map(x => x.host).includes(toPuny(host))) {
|
||||||
return 'skip (suspended)';
|
return 'skip (suspended)';
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,11 @@ import isNativeToken from './common/is-native-token';
|
||||||
import { User } from '../../models/entities/user';
|
import { User } from '../../models/entities/user';
|
||||||
import { Users, AccessTokens, Apps } from '../../models';
|
import { Users, AccessTokens, Apps } from '../../models';
|
||||||
import { AccessToken } from '../../models/entities/access-token';
|
import { AccessToken } from '../../models/entities/access-token';
|
||||||
|
import { Cache } from '../../misc/cache';
|
||||||
|
|
||||||
const cache = {} as Record<string, User>;
|
// TODO: TypeORMのカスタムキャッシュプロバイダを使っても良いかも
|
||||||
|
// ref. https://github.com/typeorm/typeorm/blob/master/docs/caching.md
|
||||||
|
const cache = new Cache<User>(1000 * 60 * 60);
|
||||||
|
|
||||||
export default async (token: string): Promise<[User | null | undefined, AccessToken | null | undefined]> => {
|
export default async (token: string): Promise<[User | null | undefined, AccessToken | null | undefined]> => {
|
||||||
if (token == null) {
|
if (token == null) {
|
||||||
|
@ -11,8 +14,9 @@ export default async (token: string): Promise<[User | null | undefined, AccessTo
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNativeToken(token)) {
|
if (isNativeToken(token)) {
|
||||||
if (cache[token]) { // TODO: キャッシュされてから一定時間経過していたら破棄する
|
const cached = cache.get(token);
|
||||||
return [cache[token], null];
|
if (cached) {
|
||||||
|
return [cached, null];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch user
|
// Fetch user
|
||||||
|
@ -23,7 +27,7 @@ export default async (token: string): Promise<[User | null | undefined, AccessTo
|
||||||
throw new Error('user not found');
|
throw new Error('user not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
cache[token] = user;
|
cache.set(token, user);
|
||||||
|
|
||||||
return [user, null];
|
return [user, null];
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -3,10 +3,16 @@ import { Instances } from '../models';
|
||||||
import { federationChart } from './chart';
|
import { federationChart } from './chart';
|
||||||
import { genId } from '../misc/gen-id';
|
import { genId } from '../misc/gen-id';
|
||||||
import { toPuny } from '../misc/convert-host';
|
import { toPuny } from '../misc/convert-host';
|
||||||
|
import { Cache } from '../misc/cache';
|
||||||
|
|
||||||
|
const cache = new Cache<Instance>(1000 * 60 * 60);
|
||||||
|
|
||||||
export async function registerOrFetchInstanceDoc(host: string): Promise<Instance> {
|
export async function registerOrFetchInstanceDoc(host: string): Promise<Instance> {
|
||||||
host = toPuny(host);
|
host = toPuny(host);
|
||||||
|
|
||||||
|
const cached = cache.get(host);
|
||||||
|
if (cached) return cached;
|
||||||
|
|
||||||
const index = await Instances.findOne({ host });
|
const index = await Instances.findOne({ host });
|
||||||
|
|
||||||
if (index == null) {
|
if (index == null) {
|
||||||
|
@ -19,8 +25,10 @@ export async function registerOrFetchInstanceDoc(host: string): Promise<Instance
|
||||||
|
|
||||||
federationChart.update(true);
|
federationChart.update(true);
|
||||||
|
|
||||||
|
cache.set(host, i);
|
||||||
return i;
|
return i;
|
||||||
} else {
|
} else {
|
||||||
|
cache.set(host, index);
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue