Alfa
STYGION Panel a0.3.3
The console was not slow and it was not disconnected. It had stopped redrawing.
The console draws again
Measured in a real browser: a WebSocket opened inside the page received ten lines while the console's own element in the DOM did not change by a character. The page had frozen on whatever happened to be on it at first paint and was, from then on, a picture of a console rather than a console.
One line caused it. The rendered list handed Svelte the same array whenever there was no half-written line in flight, and Svelte compares by identity — the same reference means no change. While the server still sent raw chunks of output there was almost always a partial line left over, and copying it produced a fresh reference by accident. The moment 0.3.2 started sending whole lines, that accident disappeared and so did every redraw.
Two more things fell out of the same test:
- A command was printed twice — once by the panel, which echoes it to everybody watching, and once more by the page for the person who typed it. The panel's echo is the one that stayed: it means the server actually took it.
- A reconnect duplicated the whole scrollback. The panel replays what it holds on every connect, and the page wrote it underneath what it already had.
- Every Start or Stop tore the socket down, because the effect that owned it read the whole server object, which those actions replace — so the console was reconnecting at exactly the moment it mattered most.
Commands survive a panel restart
0.3.2 shipped with a note: "restart your servers once after updating". That was a detour. This is the fix.
podman attach closes the container's input however the attach ends.
Measured against podman 5.7, all three ways: cleanly, with the ctrl-p ctrl-q
detach sequence, and killed. EOF-SEEN every time. Minecraft reads that as
end-of-input and takes no further command for the rest of its run.
So every panel restart — and a self-update is a panel restart — permanently silenced the console of every server that was running at the time. And the panel lied about it: the next attach wrote into a stream nothing was reading, the write succeeded, and the command was echoed as delivered.
A server now reads its commands from a named pipe the panel owns:
if [ -p /home/container/.stygion/console.in ]; then
exec 0<>/home/container/.stygion/console.in
fi
A pipe opened for reading and writing always has a writer, so it never reports
end-of-input, however often the panel comes and goes. And because opening it for
writing fails outright when nobody is reading, the panel can tell a delivered
command from a lost one — attach stays only as the fallback for containers
built before the pipe existed.
Those rebuild themselves at their next Start. The data directory is a bind mount and is not touched; only the container instance is rebuilt, which is the same thing saving the Startup tab has always done. Nobody has to know any of this exists.
Also
- A failed action is written into the console. A Start that announced itself and then went quiet is the most confusing thing that page can do: the banner is up, so silence reads as "still booting" when the container never ran at all.
- Stop and Kill announce themselves when pressed, not when they finish. A graceful stop waits up to half a minute for the world to save, and a silent console in that time looks like a dead button.
- CI compiles again.
//go:embed all:distneeds the directory to exist in a clean checkout; the placeholder that guaranteed it had been gone since 0.3.1, and only the release build — which builds the frontend first — did not notice.
Upgrading from 0.3.2 needs nothing of you. Servers still running from before the update move onto the console pipe by themselves the next time they are started.