← notes

A gateway websocket and a web server in one process

Sep 2, 2023

Capture Discord server metrics over time and serve them from a small web app in the same process.

discord.py and Flask want incompatible things. The Discord client holds a persistent websocket to the gateway and expects to own the event loop; Flask on a WSGI server expects to block. Putting both in one program is the first real decision, and there is no free option, separate processes over a shared database, threads, or an async server hosting both.

Whichever way you go, SQLite is where it gets sharp. A gateway event handler writing while the web app reads is exactly the concurrency SQLite handles by locking, and the reader gets database is locked at a moment unrelated to what it was doing.

The metrics split into two kinds people conflate. Some are gauges you sample, like member count. Others are counters derived from gateway events, like joins and leaves. Sampling a counter loses events between samples; counting a gauge is meaningless. Getting that wrong makes a dashboard subtly and permanently wrong.

View Audit Log is the permission that matters, and it needs more trust than a typical bot.

The gateway only reports the present, so anything before the bot joined cannot be backfilled.