Browse Source

Feature/liveness probe (#8037)

* Setup liveness probe endpoint

* Update documentation

* Update changelog
pull/8035/head^2
Thomas Kaul 4 days ago
committed by GitHub
parent
commit
047a2f705b
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 4
      CHANGELOG.md
  2. 24
      README.md
  3. 16
      apps/api/src/app/health/health.controller.ts
  4. 2
      libs/common/src/lib/interfaces/index.ts
  5. 3
      libs/common/src/lib/interfaces/responses/liveness-health-response.interface.ts

4
CHANGELOG.md

@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
### Added
- Extended the _Public API_ with the liveness probe endpoint (`GET api/v1/health/liveness`) (experimental)
### Changed
- Upgraded `@simplewebauthn/browser` and `@simplewebauthn/server` from version `13.3` to `14.0`

24
README.md

@ -193,6 +193,8 @@ You can get the _Bearer Token_ via `POST http://localhost:3333/api/v1/auth/anony
### Health Check (experimental)
The endpoint checks the connection to the database and to _Redis_. It is suitable as the readiness probe of an orchestrator (e.g. `readinessProbe` in _Kubernetes_) and as the `healthcheck` in _Docker Compose_. The check of _Redis_ can take up to 5 seconds. Thus, set the timeout of the probe to at least 5 seconds (e.g. `timeoutSeconds: 5` in _Kubernetes_).
#### Request
`GET http://localhost:3333/api/v1/health`
@ -211,6 +213,28 @@ You can get the _Bearer Token_ via `POST http://localhost:3333/api/v1/auth/anony
}
```
### Liveness Probe (experimental)
The endpoint answers without a check of the database or _Redis_. It is suitable as the liveness probe of an orchestrator (e.g. `livenessProbe` in _Kubernetes_), so that an outage of a dependency after the start does not restart the container. The database migrations run before the server starts. Thus, also use the endpoint as the startup probe (e.g. `startupProbe` in _Kubernetes_), so that a long migration does not restart the container.
#### Request
`GET http://localhost:3333/api/v1/health/liveness`
**Info:** No Bearer Token is required for liveness probe
#### Response
##### Success
`200 OK`
```
{
"status": "OK"
}
```
### Import Portfolio Data
#### Prerequisites

16
apps/api/src/app/health/health.controller.ts

@ -3,7 +3,8 @@ import { TransformDataSourceInRequestInterceptor } from '@ghostfolio/api/interce
import {
AiServiceHealthResponse,
DataEnhancerHealthResponse,
DataProviderHealthResponse
DataProviderHealthResponse,
LivenessHealthResponse
} from '@ghostfolio/common/interfaces';
import {
@ -33,9 +34,11 @@ export class HealthController {
@Get()
public async getHealth(@Res() response: Response) {
const databaseServiceHealthy = await this.healthService.isDatabaseHealthy();
const redisCacheServiceHealthy =
await this.healthService.isRedisCacheHealthy();
const [databaseServiceHealthy, redisCacheServiceHealthy] =
await Promise.all([
this.healthService.isDatabaseHealthy(),
this.healthService.isRedisCacheHealthy()
]);
if (databaseServiceHealthy && redisCacheServiceHealthy) {
return response
@ -116,4 +119,9 @@ export class HealthController {
.json({ status: getReasonPhrase(StatusCodes.SERVICE_UNAVAILABLE) });
}
}
@Get('liveness')
public getLiveness(): LivenessHealthResponse {
return { status: getReasonPhrase(StatusCodes.OK) };
}
}

2
libs/common/src/lib/interfaces/index.ts

@ -68,6 +68,7 @@ import type { ExportResponse } from './responses/export-response.interface';
import type { HistoricalResponse } from './responses/historical-response.interface';
import type { ImportResponse } from './responses/import-response.interface';
import type { InfoResponse } from './responses/info-response.interface';
import type { LivenessHealthResponse } from './responses/liveness-health-response.interface';
import type { LookupResponse } from './responses/lookup-response.interface';
import type { MarketDataOfMarketsResponse } from './responses/market-data-of-markets-response.interface';
import type { OAuthResponse } from './responses/oauth-response.interface';
@ -156,6 +157,7 @@ export {
InfoResponse,
InvestmentItem,
LineChartItem,
LivenessHealthResponse,
LookupItem,
LookupResponse,
MarketData,

3
libs/common/src/lib/interfaces/responses/liveness-health-response.interface.ts

@ -0,0 +1,3 @@
export interface LivenessHealthResponse {
status: string;
}
Loading…
Cancel
Save