diff --git a/infra/workers/cast-albums/src/index.ts b/infra/workers/cast-albums/src/index.ts index 750158d966..6759126c17 100644 --- a/infra/workers/cast-albums/src/index.ts +++ b/infra/workers/cast-albums/src/index.ts @@ -1,4 +1,4 @@ -/** Proxy file and thumbnail requests for the cast web app */ +/** Proxy file and thumbnail requests for the cast web app. */ export default { async fetch(request: Request) { diff --git a/infra/workers/health-check/package.json b/infra/workers/health-check/package.json new file mode 100644 index 0000000000..73802a826b --- /dev/null +++ b/infra/workers/health-check/package.json @@ -0,0 +1,10 @@ +{ + "name": "health-check", + "private": true, + "devDependencies": { + "@cloudflare/workers-types": "^4.20240614.0", + "typescript": "^5", + "wrangler": "^3" + }, + "packageManager": "yarn@1.22.22" +} diff --git a/infra/workers/health-check/src/index.ts b/infra/workers/health-check/src/index.ts new file mode 100644 index 0000000000..183530237d --- /dev/null +++ b/infra/workers/health-check/src/index.ts @@ -0,0 +1,45 @@ +/** Ping api.ente.io every minute and yell if it doesn't pong. */ + +export default { + async scheduled(_, env: Env, ctx: ExecutionContext) { + ctx.waitUntil(ping(env)); + }, +} satisfies ExportedHandler; + +interface Env { + NOTIFY_URL: string; + CHAT_ID: string; +} + +const ping = async (env: Env) => { + const notify = async (msg: string) => + sendMessage(`${msg} on ${Date()}`, env); + + try { + let timeout = setTimeout(() => notify("Ping timed out"), 5000); + const res = await fetch("https://api.ente.io/ping", { + headers: { + "User-Agent": "health-check", + }, + }); + clearTimeout(timeout); + if (!res.ok) await notify(`Ping failed (HTTP ${res.status})`); + } catch (e) { + await notify(`Ping failed (${e instanceof Error ? e.message : e})`); + } +}; + +const sendMessage = async (message: string, env: Env) => { + console.log(message); + return fetch(env.NOTIFY_URL, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + chat_id: parseInt(env.CHAT_ID), + parse_mode: "html", + text: message, + }), + }); +}; diff --git a/infra/workers/health-check/tsconfig.json b/infra/workers/health-check/tsconfig.json new file mode 100644 index 0000000000..a65b752070 --- /dev/null +++ b/infra/workers/health-check/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "../tsconfig.base.json", "include": ["src"] } diff --git a/infra/workers/health-check/wrangler.toml b/infra/workers/health-check/wrangler.toml new file mode 100644 index 0000000000..5ce77da112 --- /dev/null +++ b/infra/workers/health-check/wrangler.toml @@ -0,0 +1,17 @@ +name = "health-check" +main = "src/index.ts" +compatibility_date = "2024-06-14" + +[vars] +# Added as a secret via the Cloudflare dashboard +# NOTIFY_URL = "" +# CHAT_ID = "" + +# Disable the default route, this worker does not handle fetch. +workers_dev = false + +[triggers] +# Every minute +crons = [ "*/1 * * * *" ] + +tail_consumers = [{ service = "tail" }]