summaryrefslogtreecommitdiff
path: root/packages/backend/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/backend/src')
-rw-r--r--packages/backend/src/boot/entry.ts3
-rw-r--r--packages/backend/src/boot/ready.ts6
-rw-r--r--packages/backend/src/server/HealthServerService.ts54
-rw-r--r--packages/backend/src/server/ServerModule.ts2
-rw-r--r--packages/backend/src/server/ServerService.ts3
5 files changed, 68 insertions, 0 deletions
diff --git a/packages/backend/src/boot/entry.ts b/packages/backend/src/boot/entry.ts
index 6b8e83d4f9..04c6ca9723 100644
--- a/packages/backend/src/boot/entry.ts
+++ b/packages/backend/src/boot/entry.ts
@@ -15,6 +15,7 @@ import Logger from '@/logger.js';
import { envOption } from '../env.js';
import { masterMain } from './master.js';
import { workerMain } from './worker.js';
+import { readyRef } from './ready.js';
import 'reflect-metadata';
@@ -79,6 +80,8 @@ if (cluster.isWorker || envOption.disableClustering) {
await workerMain();
}
+readyRef.value = true;
+
// ユニットテスト時にMisskeyが子プロセスで起動された時のため
// それ以外のときは process.send は使えないので弾く
if (process.send) {
diff --git a/packages/backend/src/boot/ready.ts b/packages/backend/src/boot/ready.ts
new file mode 100644
index 0000000000..591ae5cb58
--- /dev/null
+++ b/packages/backend/src/boot/ready.ts
@@ -0,0 +1,6 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+export const readyRef = { value: false };
diff --git a/packages/backend/src/server/HealthServerService.ts b/packages/backend/src/server/HealthServerService.ts
new file mode 100644
index 0000000000..2c3ed85925
--- /dev/null
+++ b/packages/backend/src/server/HealthServerService.ts
@@ -0,0 +1,54 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import { Inject, Injectable } from '@nestjs/common';
+import * as Redis from 'ioredis';
+import { DataSource } from 'typeorm';
+import { bindThis } from '@/decorators.js';
+import { DI } from '@/di-symbols.js';
+import { readyRef } from '@/boot/ready.js';
+import type { FastifyInstance, FastifyPluginOptions } from 'fastify';
+import type { MeiliSearch } from 'meilisearch';
+
+@Injectable()
+export class HealthServerService {
+ constructor(
+ @Inject(DI.redis)
+ private redis: Redis.Redis,
+
+ @Inject(DI.redisForPub)
+ private redisForPub: Redis.Redis,
+
+ @Inject(DI.redisForSub)
+ private redisForSub: Redis.Redis,
+
+ @Inject(DI.redisForTimelines)
+ private redisForTimelines: Redis.Redis,
+
+ @Inject(DI.db)
+ private db: DataSource,
+
+ @Inject(DI.meilisearch)
+ private meilisearch: MeiliSearch | null,
+ ) {}
+
+ @bindThis
+ public createServer(fastify: FastifyInstance, options: FastifyPluginOptions, done: (err?: Error) => void) {
+ fastify.get('/', async (request, reply) => {
+ reply.code(await Promise.all([
+ new Promise<void>((resolve, reject) => readyRef.value ? resolve() : reject()),
+ this.redis.ping(),
+ this.redisForPub.ping(),
+ this.redisForSub.ping(),
+ this.redisForTimelines.ping(),
+ this.db.query('SELECT 1'),
+ ...(this.meilisearch ? [this.meilisearch.health()] : []),
+ ]).then(() => 200, () => 503));
+ reply.header('Cache-Control', 'no-store');
+ });
+
+ done();
+ }
+}
diff --git a/packages/backend/src/server/ServerModule.ts b/packages/backend/src/server/ServerModule.ts
index f43968d236..12d5061985 100644
--- a/packages/backend/src/server/ServerModule.ts
+++ b/packages/backend/src/server/ServerModule.ts
@@ -8,6 +8,7 @@ import { EndpointsModule } from '@/server/api/EndpointsModule.js';
import { CoreModule } from '@/core/CoreModule.js';
import { ApiCallService } from './api/ApiCallService.js';
import { FileServerService } from './FileServerService.js';
+import { HealthServerService } from './HealthServerService.js';
import { NodeinfoServerService } from './NodeinfoServerService.js';
import { ServerService } from './ServerService.js';
import { WellKnownServerService } from './WellKnownServerService.js';
@@ -55,6 +56,7 @@ import { ReversiGameChannelService } from './api/stream/channels/reversi-game.js
ClientServerService,
ClientLoggerService,
FeedService,
+ HealthServerService,
UrlPreviewService,
ActivityPubServerService,
FileServerService,
diff --git a/packages/backend/src/server/ServerService.ts b/packages/backend/src/server/ServerService.ts
index da17a88e03..3572f16627 100644
--- a/packages/backend/src/server/ServerService.ts
+++ b/packages/backend/src/server/ServerService.ts
@@ -28,6 +28,7 @@ import { ApiServerService } from './api/ApiServerService.js';
import { StreamingApiServerService } from './api/StreamingApiServerService.js';
import { WellKnownServerService } from './WellKnownServerService.js';
import { FileServerService } from './FileServerService.js';
+import { HealthServerService } from './HealthServerService.js';
import { ClientServerService } from './web/ClientServerService.js';
import { OpenApiServerService } from './api/openapi/OpenApiServerService.js';
import { OAuth2ProviderService } from './oauth/OAuth2ProviderService.js';
@@ -61,6 +62,7 @@ export class ServerService implements OnApplicationShutdown {
private wellKnownServerService: WellKnownServerService,
private nodeinfoServerService: NodeinfoServerService,
private fileServerService: FileServerService,
+ private healthServerService: HealthServerService,
private clientServerService: ClientServerService,
private globalEventService: GlobalEventService,
private loggerService: LoggerService,
@@ -108,6 +110,7 @@ export class ServerService implements OnApplicationShutdown {
fastify.register(this.wellKnownServerService.createServer);
fastify.register(this.oauth2ProviderService.createServer, { prefix: '/oauth' });
fastify.register(this.oauth2ProviderService.createTokenServer, { prefix: '/oauth/token' });
+ fastify.register(this.healthServerService.createServer, { prefix: '/healthz' });
fastify.get<{ Params: { path: string }; Querystring: { static?: any; badge?: any; }; }>('/emoji/:path(.*)', async (request, reply) => {
const path = request.params.path;