From 781165170987a95e162986ea130280191e8b6712 Mon Sep 17 00:00:00 2001 From: Ole Langbehn <ole.langbehn@inoio.de> Date: Mon, 2 Dec 2024 19:57:43 +0100 Subject: [PATCH] feat: add /health, /ready endpoints, define readiness and liveness check --- app/goodnews.ts | 5 ++--- app/server.ts | 16 ++++++++++++---- deno.json | 2 +- terraform/environments/deployment.tf | 15 +++++++++++++++ 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/app/goodnews.ts b/app/goodnews.ts index bb364a1..499a301 100644 --- a/app/goodnews.ts +++ b/app/goodnews.ts @@ -103,9 +103,8 @@ const fetchPage = const fetchResult = await fetch(url) const resultJson = await fetchResult.json() return resultJson - // deno-lint-ignore no-explicit-any - } catch (err: any) { - logger.error('fetching articles failed: ' + err.message) + } catch (err) { + logger.error('fetching articles failed:', err as Error) throw err } finally { const duration = Date.now() - start diff --git a/app/server.ts b/app/server.ts index fdc5ea7..dcf2436 100644 --- a/app/server.ts +++ b/app/server.ts @@ -1,5 +1,5 @@ import { GoodNewsArticleQueryResponse, GoodNewsLanguage } from './api_types.ts' -import { createSchema, createYoga, gql, serve, useResponseCache } from './deps.ts' +import { createSchema, createYoga, gql, useResponseCache } from './deps.ts' import { DEFAULT_LANGUAGE, executeArticlesQuery, SUPPORTED_LANGUAGES } from './goodnews.ts' import { logger } from './logging.ts' @@ -94,6 +94,8 @@ export interface ServerConfig { contentful: ContentfulConfig } +const isAlive = () => new Response(`${true}`) + export const createGraphQLServer = (config: ServerConfig): GraphQLServer => { const plugins = config.cacheEnabled || DEFAULT_CACHE_ENABLED ? [ @@ -128,17 +130,23 @@ export type GraphQLContext = { } } -export const startServer = (config: ServerConfig): Promise<void> => { +export const startServer = (config: ServerConfig): Deno.HttpServer<Deno.NetAddr> => { const graphQLServer: GraphQLServer = createGraphQLServer(config) - return serve(graphQLServer, { + return Deno.serve({ port: config.port || DEFAULT_PORT, + handler: (req: Request) => { + const url = new URL(req.url) + const pathname = url.pathname + if (pathname.startsWith('/health') || pathname.startsWith('/ready')) return isAlive() + return graphQLServer.handleRequest(req) + }, onListen({ port, hostname }) { logger.info( `Server started at http://${hostname === '0.0.0.0' ? 'localhost' : hostname}:${port}/graphql`, ) if (config.contentful.fake) { logger.info( - `Server is serving fake data due to FAKE env var set to true`, + 'Server is serving fake data due to FAKE env var set to true', ) } }, diff --git a/deno.json b/deno.json index 0952ad5..5697d87 100644 --- a/deno.json +++ b/deno.json @@ -4,7 +4,7 @@ "lint": "deno lint", "fmt": "deno fmt", "fmt:check": "deno fmt --check", - "test": "deno test --allow-import ", + "test": "deno test --allow-import", "updateDeps": "deno cache --allow-import --lock=deno.lock --lock-write app/deps.ts app/dev_deps.ts", "install": "deno cache --allow-import --reload --lock=deno.lock app/deps.ts app/dev_deps.ts", "cache": "deno cache --allow-import app/main.ts", diff --git a/terraform/environments/deployment.tf b/terraform/environments/deployment.tf index a728e61..585cad1 100644 --- a/terraform/environments/deployment.tf +++ b/terraform/environments/deployment.tf @@ -44,6 +44,21 @@ resource "google_cloud_run_service" "goodnews_api" { ports { container_port = 8002 } + startup_probe { + http_get { + path = "/ready" + } + timeout_seconds = 10 + period_seconds = 10 + failure_threshold = 6 + } + liveness_probe { + http_get { + path = "/health" + } + timeout_seconds = 20 + period_seconds = 60 + } env { name = "ENVIRONMENT" value = local.environment -- GitLab