Three probes live here. Two dump raw Discord RPC traffic; they do not import any crate code — they speak the wire protocols directly, so they keep working (and stay truthful) even when the adapters change. The third is a plain shell sampler for RSS-hunting on a process that does not look like a leak in the code but does in btop.
The two Discord probes live in their own mini-crate under scripts/,
deliberately separate from the main package, so they never build with or
get installed by hyprlay. Their targets are examples, not bins: that
keeps the repo's cargo install --git scan at exactly one binary
package, so bare installs work. Run them from that directory:
cd scripts
cargo run --example ipcprobe # unix-socket IPC probe (current transport)
cargo run --example wsprobe # historical websocket bridge probescripts/rssprobe.sh samples one process's memory every couple of
seconds and appends one CSV row per interval:
epoch,timestamp,rss_kb,hwm_kb,note. It reads /proc/<pid>/status
directly — VmRSS plus the peak VmHWM — so every row shows both the
live footprint and the historical high-water mark. That pair is the
diagnosis signal:
- RSS at or near HWM — the process is at its historical peak; what you are watching is real growth.
- RSS well below HWM — memory was freed but not returned to the OS (allocator retention). The interesting question becomes what spiked it earlier, not what is growing now.
Usage — sampler in one terminal, markers from another while you work:
scripts/rssprobe.sh # sample `pidof hyprlayd` every 2s
scripts/rssprobe.sh -p <pid> -i 5 -o d.csv # explicit target/interval/output
scripts/rssprobe.sh mark "VC join" # append a labeled marker row
scripts/rssprobe.sh mark -o d.csv "VC join" # marker into the same CSVCtrl-C stops the sampler. Both commands append to the same CSV
(rssprobe.csv in the CWD by default; the header is written once),
so a later plot or diff shows exactly which scenario moved the
needle.
Runbook for the hyprlayd memory regression (spec: v031 memory, H1–H5):
- Cold idle: start the sampler on a freshly restarted daemon, mark
idle-start, wait 10 min, markidle-end. - H1 bait: mark
window-move-storm, sweep a window across the overlay withdim-on-hoveron (the poll path opens a fresh Hyprland socket per 50ms tick while connected with a non-empty roster), then repeat with it off. - VC join/leave cycles, camera/stream toggles: mark each; watch RSS vs HWM after the leave.
- Repeat the identical series on the v0.3.0 release build (
hyprlaydfrom that tag) and diff the CSVs.
The daemon talks to Discord over Discord's local unix socket at
$XDG_RUNTIME_DIR/discord-ipc-N; the client side lives in
src/daemon/adapters/ipc.rs. The wire format is 8-byte little-endian
framing (opcode u32 + payload length u32) carrying JSON payloads.
The probe connects to the socket, does the same framing, sends
HANDSHAKE then AUTHORIZE, and prints every frame for 60s. Use it to
see what a stock Discord client answers and how it frames data.
Start here when Discord changes something: confirm at the protocol level
whether opcodes or payloads moved before touching
src/daemon/adapters/discord.rs.
The socket has no HTTP layer, so there is no origin validation — any properly registered application id connects with zero portal configuration beyond the desktop redirect URI.
An earlier daemon build used the websocket bridge at ws://127.0.0.1:6463/.
That bridge sits behind an HTTP upgrade and validates each
(client_id, Origin) pair against per-application origins registered in
the Developer Portal; an application without a registered origin is
silently dropped before any protocol error surfaces. That gate is why the
daemon moved to the unix socket. The probe stays for reference only.
It connects to the bridge, waits for the READY dispatch, sends
AUTHORIZE, and prints every frame. The optional mode argument controls
the HTTP Origin header it sends:
| Mode | Origin sent |
|---|---|
no-origin |
none |
discord |
https://discord.com |
tauri |
tauri://localhost |
dev |
http://localhost:1420 |
| anything else | sent verbatim as the Origin header |