From 5aa5896b221ba73773a370fc01d1a9235eca33dd Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Wed, 24 Apr 2019 08:11:19 +0900
Subject: [PATCH] Cache meta

---
 src/misc/fetch-meta.ts                         | 18 ++++++++++++++++--
 src/misc/fetch-proxy-account.ts                |  2 +-
 src/misc/reaction-lib.ts                       |  2 +-
 src/prelude/await-all.ts                       |  2 +-
 src/queue/processors/inbox.ts                  |  3 +--
 src/remote/activitypub/kernel/announce/note.ts |  3 +--
 src/remote/activitypub/models/image.ts         |  2 +-
 src/remote/activitypub/models/note.ts          |  3 +--
 src/remote/activitypub/request.ts              |  3 +--
 src/server/api/endpoints/ap/show.ts            |  2 +-
 src/server/api/endpoints/drive.ts              |  4 ++--
 .../api/endpoints/federation/instances.ts      |  4 ++--
 src/server/api/endpoints/hashtags/trend.ts     |  4 ++--
 src/server/api/endpoints/i/update-email.ts     |  4 ++--
 src/server/api/endpoints/meta.ts               |  4 ++--
 src/server/api/endpoints/notes/create.ts       |  2 +-
 .../api/endpoints/notes/global-timeline.ts     |  3 +--
 .../api/endpoints/notes/hybrid-timeline.ts     |  3 +--
 .../api/endpoints/notes/local-timeline.ts      |  3 +--
 src/server/api/endpoints/sw/register.ts        |  4 ++--
 src/server/api/private/signup.ts               |  4 ++--
 src/server/api/service/discord.ts              |  4 ++--
 src/server/api/service/github.ts               |  4 ++--
 src/server/api/service/twitter.ts              |  4 ++--
 .../api/stream/channels/global-timeline.ts     |  2 +-
 .../api/stream/channels/hybrid-timeline.ts     |  2 +-
 .../api/stream/channels/local-timeline.ts      |  2 +-
 src/server/nodeinfo.ts                         |  4 ++--
 src/server/web/index.ts                        |  4 ++--
 src/server/web/manifest.ts                     |  4 ++--
 src/server/web/url-preview.ts                  |  2 +-
 src/services/drive/add-file.ts                 |  2 +-
 src/services/note/reaction/create.ts           |  2 +-
 src/services/push-notification.ts              |  2 +-
 34 files changed, 62 insertions(+), 55 deletions(-)

diff --git a/src/misc/fetch-meta.ts b/src/misc/fetch-meta.ts
index 800f0b9e63..db82adb2a4 100644
--- a/src/misc/fetch-meta.ts
+++ b/src/misc/fetch-meta.ts
@@ -1,7 +1,11 @@
 import { Meta } from '../models/entities/meta';
 import { getConnection } from 'typeorm';
 
-export default async function(): Promise<Meta> {
+let cache: Meta;
+
+export async function fetchMeta(noCache = false): Promise<Meta> {
+	if (!noCache && cache) return cache;
+
 	return await getConnection().transaction(async transactionalEntityManager => {
 		// バグでレコードが複数出来てしまっている可能性があるので新しいIDを優先する
 		const meta = await transactionalEntityManager.findOne(Meta, {
@@ -11,11 +15,21 @@ export default async function(): Promise<Meta> {
 		});
 
 		if (meta) {
+			cache = meta;
 			return meta;
 		} else {
-			return await transactionalEntityManager.save(Meta, {
+			const saved = await transactionalEntityManager.save(Meta, {
 				id: 'x'
 			}) as Meta;
+
+			cache = saved;
+			return saved;
 		}
 	});
 }
+
+setInterval(() => {
+	fetchMeta(true).then(meta => {
+		cache = meta;
+	});
+}, 5000);
diff --git a/src/misc/fetch-proxy-account.ts b/src/misc/fetch-proxy-account.ts
index 17b021e91e..075873091c 100644
--- a/src/misc/fetch-proxy-account.ts
+++ b/src/misc/fetch-proxy-account.ts
@@ -1,4 +1,4 @@
-import fetchMeta from './fetch-meta';
+import { fetchMeta } from './fetch-meta';
 import { ILocalUser } from '../models/entities/user';
 import { Users } from '../models';
 import { ensure } from '../prelude/ensure';
diff --git a/src/misc/reaction-lib.ts b/src/misc/reaction-lib.ts
index 008991454b..ced90ce78f 100644
--- a/src/misc/reaction-lib.ts
+++ b/src/misc/reaction-lib.ts
@@ -1,5 +1,5 @@
 import { emojiRegex } from './emoji-regex';
-import fetchMeta from './fetch-meta';
+import { fetchMeta } from './fetch-meta';
 import { Emojis } from '../models';
 
 const basic10: Record<string, string> = {
diff --git a/src/prelude/await-all.ts b/src/prelude/await-all.ts
index 9492550483..24795f3ae5 100644
--- a/src/prelude/await-all.ts
+++ b/src/prelude/await-all.ts
@@ -10,7 +10,7 @@ export async function awaitAll<T>(obj: T): Promise<AwaitAll<T>> {
 	const values = Object.values(obj);
 
 	const resolvedValues = await Promise.all(values.map(value =>
-		(value || !value.constructor || value.constructor.name !== 'Object')
+		(!value || !value.constructor || value.constructor.name !== 'Object')
 			? value
 			: awaitAll(value)
 	));
diff --git a/src/queue/processors/inbox.ts b/src/queue/processors/inbox.ts
index e657859507..21a51c962b 100644
--- a/src/queue/processors/inbox.ts
+++ b/src/queue/processors/inbox.ts
@@ -10,7 +10,7 @@ import { registerOrFetchInstanceDoc } from '../../services/register-or-fetch-ins
 import { Instances, Users, UserPublickeys } from '../../models';
 import { instanceChart } from '../../services/chart';
 import { UserPublickey } from '../../models/entities/user-publickey';
-import fetchMeta from '../../misc/fetch-meta';
+import { fetchMeta } from '../../misc/fetch-meta';
 import { toPuny } from '../../misc/convert-host';
 import { validActor } from '../../remote/activitypub/type';
 import { ensure } from '../../prelude/ensure';
@@ -48,7 +48,6 @@ export default async (job: Bull.Job): Promise<void> => {
 	}
 
 	// ブロックしてたら中断
-	// TODO: いちいちデータベースにアクセスするのはコスト高そうなのでどっかにキャッシュしておく
 	const meta = await fetchMeta();
 	if (meta.blockedHosts.includes(host)) {
 		logger.info(`Blocked request: ${host}`);
diff --git a/src/remote/activitypub/kernel/announce/note.ts b/src/remote/activitypub/kernel/announce/note.ts
index f9822c5187..6843041475 100644
--- a/src/remote/activitypub/kernel/announce/note.ts
+++ b/src/remote/activitypub/kernel/announce/note.ts
@@ -6,7 +6,7 @@ import { fetchNote, resolveNote } from '../../models/note';
 import { resolvePerson } from '../../models/person';
 import { apLogger } from '../../logger';
 import { extractDbHost } from '../../../../misc/convert-host';
-import fetchMeta from '../../../../misc/fetch-meta';
+import { fetchMeta } from '../../../../misc/fetch-meta';
 
 const logger = apLogger;
 
@@ -26,7 +26,6 @@ export default async function(resolver: Resolver, actor: IRemoteUser, activity:
 	}
 
 	// アナウンス先をブロックしてたら中断
-	// TODO: いちいちデータベースにアクセスするのはコスト高そうなのでどっかにキャッシュしておく
 	const meta = await fetchMeta();
 	if (meta.blockedHosts.includes(extractDbHost(uri))) return;
 
diff --git a/src/remote/activitypub/models/image.ts b/src/remote/activitypub/models/image.ts
index f8b35ea21c..84a1040b2e 100644
--- a/src/remote/activitypub/models/image.ts
+++ b/src/remote/activitypub/models/image.ts
@@ -1,7 +1,7 @@
 import uploadFromUrl from '../../../services/drive/upload-from-url';
 import { IRemoteUser } from '../../../models/entities/user';
 import Resolver from '../resolver';
-import fetchMeta from '../../../misc/fetch-meta';
+import { fetchMeta } from '../../../misc/fetch-meta';
 import { apLogger } from '../logger';
 import { DriveFile } from '../../../models/entities/drive-file';
 import { DriveFiles } from '../../../models';
diff --git a/src/remote/activitypub/models/note.ts b/src/remote/activitypub/models/note.ts
index 8842342342..850b5e65e6 100644
--- a/src/remote/activitypub/models/note.ts
+++ b/src/remote/activitypub/models/note.ts
@@ -20,7 +20,7 @@ import { Note } from '../../../models/entities/note';
 import { IObject, INote } from '../type';
 import { Emoji } from '../../../models/entities/emoji';
 import { genId } from '../../../misc/gen-id';
-import fetchMeta from '../../../misc/fetch-meta';
+import { fetchMeta } from '../../../misc/fetch-meta';
 import { ensure } from '../../../prelude/ensure';
 
 const logger = apLogger;
@@ -233,7 +233,6 @@ export async function resolveNote(value: string | IObject, resolver?: Resolver):
 	if (uri == null) throw new Error('missing uri');
 
 	// ブロックしてたら中断
-	// TODO: いちいちデータベースにアクセスするのはコスト高そうなのでどっかにキャッシュしておく
 	const meta = await fetchMeta();
 	if (meta.blockedHosts.includes(extractDbHost(uri))) throw { statusCode: 451 };
 
diff --git a/src/remote/activitypub/request.ts b/src/remote/activitypub/request.ts
index 897dd9acac..da2113faea 100644
--- a/src/remote/activitypub/request.ts
+++ b/src/remote/activitypub/request.ts
@@ -10,7 +10,7 @@ import { ILocalUser } from '../../models/entities/user';
 import { publishApLogStream } from '../../services/stream';
 import { apLogger } from './logger';
 import { UserKeypairs } from '../../models';
-import fetchMeta from '../../misc/fetch-meta';
+import { fetchMeta } from '../../misc/fetch-meta';
 import { toPuny } from '../../misc/convert-host';
 import { ensure } from '../../prelude/ensure';
 
@@ -24,7 +24,6 @@ export default async (user: ILocalUser, url: string, object: any) => {
 	const { protocol, host, hostname, port, pathname, search } = new URL(url);
 
 	// ブロックしてたら中断
-	// TODO: いちいちデータベースにアクセスするのはコスト高そうなのでどっかにキャッシュしておく
 	const meta = await fetchMeta();
 	if (meta.blockedHosts.includes(toPuny(host))) return;
 
diff --git a/src/server/api/endpoints/ap/show.ts b/src/server/api/endpoints/ap/show.ts
index 1b992eeaa7..1bb15117dd 100644
--- a/src/server/api/endpoints/ap/show.ts
+++ b/src/server/api/endpoints/ap/show.ts
@@ -9,7 +9,7 @@ import { extractDbHost } from '../../../../misc/convert-host';
 import { Users, Notes } from '../../../../models';
 import { Note } from '../../../../models/entities/note';
 import { User } from '../../../../models/entities/user';
-import fetchMeta from '../../../../misc/fetch-meta';
+import { fetchMeta } from '../../../../misc/fetch-meta';
 import { validActor } from '../../../../remote/activitypub/type';
 
 export const meta = {
diff --git a/src/server/api/endpoints/drive.ts b/src/server/api/endpoints/drive.ts
index 0c820468b7..4d4516bd80 100644
--- a/src/server/api/endpoints/drive.ts
+++ b/src/server/api/endpoints/drive.ts
@@ -1,5 +1,5 @@
 import define from '../define';
-import fetchMeta from '../../../misc/fetch-meta';
+import { fetchMeta } from '../../../misc/fetch-meta';
 import { DriveFiles } from '../../../models';
 import { types, bool } from '../../../misc/schema';
 
@@ -32,7 +32,7 @@ export const meta = {
 };
 
 export default define(meta, async (ps, user) => {
-	const instance = await fetchMeta();
+	const instance = await fetchMeta(true);
 
 	// Calculate drive usage
 	const usage = await DriveFiles.clacDriveUsageOf(user);
diff --git a/src/server/api/endpoints/federation/instances.ts b/src/server/api/endpoints/federation/instances.ts
index 301338ed96..3c4e0037d6 100644
--- a/src/server/api/endpoints/federation/instances.ts
+++ b/src/server/api/endpoints/federation/instances.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy';
 import define from '../../define';
 import { Instances } from '../../../../models';
-import fetchMeta from '../../../../misc/fetch-meta';
+import { fetchMeta } from '../../../../misc/fetch-meta';
 
 export const meta = {
 	tags: ['federation'],
@@ -62,7 +62,7 @@ export default define(meta, async (ps, me) => {
 	}
 
 	if (typeof ps.blocked === 'boolean') {
-		const meta = await fetchMeta();
+		const meta = await fetchMeta(true);
 		if (ps.blocked) {
 			query.andWhere('instance.host IN (:...blocks)', { blocks: meta.blockedHosts });
 		} else {
diff --git a/src/server/api/endpoints/hashtags/trend.ts b/src/server/api/endpoints/hashtags/trend.ts
index e01e9d698f..84b750f2c1 100644
--- a/src/server/api/endpoints/hashtags/trend.ts
+++ b/src/server/api/endpoints/hashtags/trend.ts
@@ -1,5 +1,5 @@
 import define from '../../define';
-import fetchMeta from '../../../../misc/fetch-meta';
+import { fetchMeta } from '../../../../misc/fetch-meta';
 import { Notes } from '../../../../models';
 import { Note } from '../../../../models/entities/note';
 
@@ -24,7 +24,7 @@ export const meta = {
 };
 
 export default define(meta, async () => {
-	const instance = await fetchMeta();
+	const instance = await fetchMeta(true);
 	const hiddenTags = instance.hiddenTags.map(t => t.toLowerCase());
 
 	const tagNotes = await Notes.createQueryBuilder('note')
diff --git a/src/server/api/endpoints/i/update-email.ts b/src/server/api/endpoints/i/update-email.ts
index e02f53a643..d4b9721d82 100644
--- a/src/server/api/endpoints/i/update-email.ts
+++ b/src/server/api/endpoints/i/update-email.ts
@@ -2,7 +2,7 @@ import $ from 'cafy';
 import { publishMainStream } from '../../../../services/stream';
 import define from '../../define';
 import * as nodemailer from 'nodemailer';
-import fetchMeta from '../../../../misc/fetch-meta';
+import { fetchMeta } from '../../../../misc/fetch-meta';
 import rndstr from 'rndstr';
 import config from '../../../../config';
 import * as ms from 'ms';
@@ -63,7 +63,7 @@ export default define(meta, async (ps, user) => {
 			emailVerifyCode: code
 		});
 
-		const meta = await fetchMeta();
+		const meta = await fetchMeta(true);
 
 		const enableAuth = meta.smtpUser != null && meta.smtpUser !== '';
 
diff --git a/src/server/api/endpoints/meta.ts b/src/server/api/endpoints/meta.ts
index 71b950f4ce..793eb5a204 100644
--- a/src/server/api/endpoints/meta.ts
+++ b/src/server/api/endpoints/meta.ts
@@ -2,7 +2,7 @@ import $ from 'cafy';
 import * as os from 'os';
 import config from '../../../config';
 import define from '../define';
-import fetchMeta from '../../../misc/fetch-meta';
+import { fetchMeta } from '../../../misc/fetch-meta';
 import * as pkg from '../../../../package.json';
 import { Emojis } from '../../../models';
 import { types, bool } from '../../../misc/schema';
@@ -92,7 +92,7 @@ export const meta = {
 };
 
 export default define(meta, async (ps, me) => {
-	const instance = await fetchMeta();
+	const instance = await fetchMeta(true);
 
 	const emojis = await Emojis.find({ host: null });
 
diff --git a/src/server/api/endpoints/notes/create.ts b/src/server/api/endpoints/notes/create.ts
index 9822f56a53..6cd84b866f 100644
--- a/src/server/api/endpoints/notes/create.ts
+++ b/src/server/api/endpoints/notes/create.ts
@@ -3,7 +3,7 @@ import * as ms from 'ms';
 import { length } from 'stringz';
 import create from '../../../../services/note/create';
 import define from '../../define';
-import fetchMeta from '../../../../misc/fetch-meta';
+import { fetchMeta } from '../../../../misc/fetch-meta';
 import { ApiError } from '../../error';
 import { ID } from '../../../../misc/cafy-id';
 import { User } from '../../../../models/entities/user';
diff --git a/src/server/api/endpoints/notes/global-timeline.ts b/src/server/api/endpoints/notes/global-timeline.ts
index e26b9e7da3..3631208da7 100644
--- a/src/server/api/endpoints/notes/global-timeline.ts
+++ b/src/server/api/endpoints/notes/global-timeline.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy';
 import { ID } from '../../../../misc/cafy-id';
 import define from '../../define';
-import fetchMeta from '../../../../misc/fetch-meta';
+import { fetchMeta } from '../../../../misc/fetch-meta';
 import { ApiError } from '../../error';
 import { makePaginationQuery } from '../../common/make-pagination-query';
 import { Notes } from '../../../../models';
@@ -66,7 +66,6 @@ export const meta = {
 };
 
 export default define(meta, async (ps, user) => {
-	// TODO どっかにキャッシュ
 	const m = await fetchMeta();
 	if (m.disableGlobalTimeline) {
 		if (user == null || (!user.isAdmin && !user.isModerator)) {
diff --git a/src/server/api/endpoints/notes/hybrid-timeline.ts b/src/server/api/endpoints/notes/hybrid-timeline.ts
index 5c27d0c14d..c05c8dedd6 100644
--- a/src/server/api/endpoints/notes/hybrid-timeline.ts
+++ b/src/server/api/endpoints/notes/hybrid-timeline.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy';
 import { ID } from '../../../../misc/cafy-id';
 import define from '../../define';
-import fetchMeta from '../../../../misc/fetch-meta';
+import { fetchMeta } from '../../../../misc/fetch-meta';
 import { ApiError } from '../../error';
 import { makePaginationQuery } from '../../common/make-pagination-query';
 import { Followings, Notes } from '../../../../models';
@@ -109,7 +109,6 @@ export const meta = {
 };
 
 export default define(meta, async (ps, user) => {
-	// TODO どっかにキャッシュ
 	const m = await fetchMeta();
 	if (m.disableLocalTimeline && !user.isAdmin && !user.isModerator) {
 		throw new ApiError(meta.errors.stlDisabled);
diff --git a/src/server/api/endpoints/notes/local-timeline.ts b/src/server/api/endpoints/notes/local-timeline.ts
index ed2a5220e1..ca84fc6ef9 100644
--- a/src/server/api/endpoints/notes/local-timeline.ts
+++ b/src/server/api/endpoints/notes/local-timeline.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy';
 import { ID } from '../../../../misc/cafy-id';
 import define from '../../define';
-import fetchMeta from '../../../../misc/fetch-meta';
+import { fetchMeta } from '../../../../misc/fetch-meta';
 import { ApiError } from '../../error';
 import { Notes } from '../../../../models';
 import { generateMuteQuery } from '../../common/generate-mute-query';
@@ -83,7 +83,6 @@ export const meta = {
 };
 
 export default define(meta, async (ps, user) => {
-	// TODO どっかにキャッシュ
 	const m = await fetchMeta();
 	if (m.disableLocalTimeline) {
 		if (user == null || (!user.isAdmin && !user.isModerator)) {
diff --git a/src/server/api/endpoints/sw/register.ts b/src/server/api/endpoints/sw/register.ts
index 559937ca2f..a4838b4565 100644
--- a/src/server/api/endpoints/sw/register.ts
+++ b/src/server/api/endpoints/sw/register.ts
@@ -1,6 +1,6 @@
 import $ from 'cafy';
 import define from '../../define';
-import fetchMeta from '../../../../misc/fetch-meta';
+import { fetchMeta } from '../../../../misc/fetch-meta';
 import { genId } from '../../../../misc/gen-id';
 import { SwSubscriptions } from '../../../../models';
 
@@ -33,7 +33,7 @@ export default define(meta, async (ps, user) => {
 		publickey: ps.publickey,
 	});
 
-	const instance = await fetchMeta();
+	const instance = await fetchMeta(true);
 
 	if (exist != null) {
 		return {
diff --git a/src/server/api/private/signup.ts b/src/server/api/private/signup.ts
index 5715897535..c75f8fb296 100644
--- a/src/server/api/private/signup.ts
+++ b/src/server/api/private/signup.ts
@@ -3,7 +3,7 @@ import * as bcrypt from 'bcryptjs';
 import { generateKeyPair } from 'crypto';
 import generateUserToken from '../common/generate-native-user-token';
 import config from '../../../config';
-import fetchMeta from '../../../misc/fetch-meta';
+import { fetchMeta } from '../../../misc/fetch-meta';
 import * as recaptcha from 'recaptcha-promise';
 import { Users, RegistrationTickets } from '../../../models';
 import { genId } from '../../../misc/gen-id';
@@ -17,7 +17,7 @@ import { getConnection } from 'typeorm';
 export default async (ctx: Koa.BaseContext) => {
 	const body = ctx.request.body as any;
 
-	const instance = await fetchMeta();
+	const instance = await fetchMeta(true);
 
 	// Verify recaptcha
 	// ただしテスト時はこの機構は障害となるため無効にする
diff --git a/src/server/api/service/discord.ts b/src/server/api/service/discord.ts
index d8a979b5b2..589579b8e0 100644
--- a/src/server/api/service/discord.ts
+++ b/src/server/api/service/discord.ts
@@ -7,7 +7,7 @@ import { publishMainStream } from '../../../services/stream';
 import redis from '../../../db/redis';
 import * as uuid from 'uuid';
 import signin from '../common/signin';
-import fetchMeta from '../../../misc/fetch-meta';
+import { fetchMeta } from '../../../misc/fetch-meta';
 import { Users, UserProfiles } from '../../../models';
 import { ILocalUser } from '../../../models/entities/user';
 import { ensure } from '../../../prelude/ensure';
@@ -68,7 +68,7 @@ router.get('/disconnect/discord', async ctx => {
 });
 
 async function getOAuth2() {
-	const meta = await fetchMeta();
+	const meta = await fetchMeta(true);
 
 	if (meta.enableDiscordIntegration) {
 		return new OAuth2(
diff --git a/src/server/api/service/github.ts b/src/server/api/service/github.ts
index a4d274cc62..1b0ce6936c 100644
--- a/src/server/api/service/github.ts
+++ b/src/server/api/service/github.ts
@@ -7,7 +7,7 @@ import { publishMainStream } from '../../../services/stream';
 import redis from '../../../db/redis';
 import * as uuid from 'uuid';
 import signin from '../common/signin';
-import fetchMeta from '../../../misc/fetch-meta';
+import { fetchMeta } from '../../../misc/fetch-meta';
 import { Users, UserProfiles } from '../../../models';
 import { ILocalUser } from '../../../models/entities/user';
 import { ensure } from '../../../prelude/ensure';
@@ -65,7 +65,7 @@ router.get('/disconnect/github', async ctx => {
 });
 
 async function getOath2() {
-	const meta = await fetchMeta();
+	const meta = await fetchMeta(true);
 
 	if (meta.enableGithubIntegration && meta.githubClientId && meta.githubClientSecret) {
 		return new OAuth2(
diff --git a/src/server/api/service/twitter.ts b/src/server/api/service/twitter.ts
index 39fdfd8654..36299b1f29 100644
--- a/src/server/api/service/twitter.ts
+++ b/src/server/api/service/twitter.ts
@@ -6,7 +6,7 @@ import redis from '../../../db/redis';
 import { publishMainStream } from '../../../services/stream';
 import config from '../../../config';
 import signin from '../common/signin';
-import fetchMeta from '../../../misc/fetch-meta';
+import { fetchMeta } from '../../../misc/fetch-meta';
 import { Users, UserProfiles } from '../../../models';
 import { ILocalUser } from '../../../models/entities/user';
 import { ensure } from '../../../prelude/ensure';
@@ -65,7 +65,7 @@ router.get('/disconnect/twitter', async ctx => {
 });
 
 async function getTwAuth() {
-	const meta = await fetchMeta();
+	const meta = await fetchMeta(true);
 
 	if (meta.enableTwitterIntegration && meta.twitterConsumerKey && meta.twitterConsumerSecret) {
 		return autwh({
diff --git a/src/server/api/stream/channels/global-timeline.ts b/src/server/api/stream/channels/global-timeline.ts
index 7af6719d29..1271aae3a2 100644
--- a/src/server/api/stream/channels/global-timeline.ts
+++ b/src/server/api/stream/channels/global-timeline.ts
@@ -1,7 +1,7 @@
 import autobind from 'autobind-decorator';
 import shouldMuteThisNote from '../../../../misc/should-mute-this-note';
 import Channel from '../channel';
-import fetchMeta from '../../../../misc/fetch-meta';
+import { fetchMeta } from '../../../../misc/fetch-meta';
 import { Notes } from '../../../../models';
 import { PackedNote } from '../../../../models/repositories/note';
 
diff --git a/src/server/api/stream/channels/hybrid-timeline.ts b/src/server/api/stream/channels/hybrid-timeline.ts
index a1e5bf238e..b9feb70258 100644
--- a/src/server/api/stream/channels/hybrid-timeline.ts
+++ b/src/server/api/stream/channels/hybrid-timeline.ts
@@ -1,7 +1,7 @@
 import autobind from 'autobind-decorator';
 import shouldMuteThisNote from '../../../../misc/should-mute-this-note';
 import Channel from '../channel';
-import fetchMeta from '../../../../misc/fetch-meta';
+import { fetchMeta } from '../../../../misc/fetch-meta';
 import { Notes } from '../../../../models';
 import { PackedNote } from '../../../../models/repositories/note';
 import { PackedUser } from '../../../../models/repositories/user';
diff --git a/src/server/api/stream/channels/local-timeline.ts b/src/server/api/stream/channels/local-timeline.ts
index 82b957afa4..24cbc0a7bf 100644
--- a/src/server/api/stream/channels/local-timeline.ts
+++ b/src/server/api/stream/channels/local-timeline.ts
@@ -1,7 +1,7 @@
 import autobind from 'autobind-decorator';
 import shouldMuteThisNote from '../../../../misc/should-mute-this-note';
 import Channel from '../channel';
-import fetchMeta from '../../../../misc/fetch-meta';
+import { fetchMeta } from '../../../../misc/fetch-meta';
 import { Notes } from '../../../../models';
 import { PackedNote } from '../../../../models/repositories/note';
 import { PackedUser } from '../../../../models/repositories/user';
diff --git a/src/server/nodeinfo.ts b/src/server/nodeinfo.ts
index 686412383e..d3ad90fab5 100644
--- a/src/server/nodeinfo.ts
+++ b/src/server/nodeinfo.ts
@@ -1,6 +1,6 @@
 import * as Router from 'koa-router';
 import config from '../config';
-import fetchMeta from '../misc/fetch-meta';
+import { fetchMeta } from '../misc/fetch-meta';
 // import User from '../models/user';
 import { name as softwareName, version, repository } from '../../package.json';
 // import Note from '../models/note';
@@ -44,7 +44,7 @@ const nodeinfo2 = async () => {
 		// localPosts,
 		// localComments
 	] = await Promise.all([
-		fetchMeta(),
+		fetchMeta(true),
 		// User.count({ host: null }),
 		// User.count({ host: null, updatedAt: { $gt: new Date(Date.now() - 15552000000) } }),
 		// User.count({ host: null, updatedAt: { $gt: new Date(Date.now() - 2592000000) } }),
diff --git a/src/server/web/index.ts b/src/server/web/index.ts
index 5cadf1b124..1f87cd70f8 100644
--- a/src/server/web/index.ts
+++ b/src/server/web/index.ts
@@ -12,7 +12,7 @@ import * as views from 'koa-views';
 
 import docs from './docs';
 import packFeed from './feed';
-import fetchMeta from '../../misc/fetch-meta';
+import { fetchMeta } from '../../misc/fetch-meta';
 import * as pkg from '../../../package.json';
 import { genOpenapiSpec } from '../api/openapi/gen-spec';
 import config from '../../config';
@@ -206,7 +206,7 @@ router.get('/notes/:note', async ctx => {
 //#endregion
 
 router.get('/info', async ctx => {
-	const meta = await fetchMeta();
+	const meta = await fetchMeta(true);
 	const emojis = await Emojis.find({
 		where: { host: null }
 	});
diff --git a/src/server/web/manifest.ts b/src/server/web/manifest.ts
index 4acfb22de5..730082da28 100644
--- a/src/server/web/manifest.ts
+++ b/src/server/web/manifest.ts
@@ -1,11 +1,11 @@
 import * as Koa from 'koa';
 import * as manifest from '../../client/assets/manifest.json';
-import fetchMeta from '../../misc/fetch-meta';
+import { fetchMeta } from '../../misc/fetch-meta';
 
 module.exports = async (ctx: Koa.BaseContext) => {
 	const json = JSON.parse(JSON.stringify(manifest));
 
-	const instance = await fetchMeta();
+	const instance = await fetchMeta(true);
 
 	json.short_name = instance.name || 'Misskey';
 	json.name = instance.name || 'Misskey';
diff --git a/src/server/web/url-preview.ts b/src/server/web/url-preview.ts
index 7d0080b4d2..cdb6f13f59 100644
--- a/src/server/web/url-preview.ts
+++ b/src/server/web/url-preview.ts
@@ -1,7 +1,7 @@
 import * as Koa from 'koa';
 import * as request from 'request-promise-native';
 import summaly from 'summaly';
-import fetchMeta from '../../misc/fetch-meta';
+import { fetchMeta } from '../../misc/fetch-meta';
 import Logger from '../../services/logger';
 import config from '../../config';
 import { query } from '../../prelude/url';
diff --git a/src/services/drive/add-file.ts b/src/services/drive/add-file.ts
index 2f164a4d92..e569180354 100644
--- a/src/services/drive/add-file.ts
+++ b/src/services/drive/add-file.ts
@@ -9,7 +9,7 @@ import * as sharp from 'sharp';
 import { publishMainStream, publishDriveStream } from '../stream';
 import delFile from './delete-file';
 import config from '../../config';
-import fetchMeta from '../../misc/fetch-meta';
+import { fetchMeta } from '../../misc/fetch-meta';
 import { GenerateVideoThumbnail } from './generate-video-thumbnail';
 import { driveLogger } from './logger';
 import { IImage, ConvertToJpeg, ConvertToWebp, ConvertToPng } from './image-processor';
diff --git a/src/services/note/reaction/create.ts b/src/services/note/reaction/create.ts
index 7711ba0737..436347774b 100644
--- a/src/services/note/reaction/create.ts
+++ b/src/services/note/reaction/create.ts
@@ -5,7 +5,7 @@ import { deliver } from '../../../queue';
 import { renderActivity } from '../../../remote/activitypub/renderer';
 import { IdentifiableError } from '../../../misc/identifiable-error';
 import { toDbReaction } from '../../../misc/reaction-lib';
-import fetchMeta from '../../../misc/fetch-meta';
+import { fetchMeta } from '../../../misc/fetch-meta';
 import { User } from '../../../models/entities/user';
 import { Note } from '../../../models/entities/note';
 import { NoteReactions, Users, NoteWatchings, Notes, UserProfiles } from '../../../models';
diff --git a/src/services/push-notification.ts b/src/services/push-notification.ts
index 1830cad623..da1c1dbf5e 100644
--- a/src/services/push-notification.ts
+++ b/src/services/push-notification.ts
@@ -1,7 +1,7 @@
 import * as push from 'web-push';
 import config from '../config';
 import { SwSubscriptions } from '../models';
-import fetchMeta from '../misc/fetch-meta';
+import { fetchMeta } from '../misc/fetch-meta';
 
 export default async function(userId: string, type: string, body?: any) {
 	const meta = await fetchMeta();