Alpha

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:dist needs 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.