v0.7.4: the dash unit walked into the selectors.py trap
socialmag-dash crash-looped on a real box. WorkingDirectory was the repo and ExecStart was `python -m http.server`, so socketserver's `import selectors` found the repo's selectors.py and the unit died with "module 'selectors' has no attribute 'SelectSelector'" every 5 seconds. :8321 never bound. This is the SAME root cause already fixed twice this evening — once for `-m socialmag` (console scripts, cli.py) and once for `-m venv` (run python from /). Both fixes were about keeping the repo off sys.path, and then the unit file put it right back on. A `-m` anywhere near this directory is the hazard, not any particular entry point. The dash now serves with --directory and sits in / instead of standing in the tree it serves. The by-hand fallback instructions carried the identical bug and now do the same, with a line saying why. openbridge and refresh were never affected: they exec console scripts, which do not put the working directory on sys.path. That is exactly why cli.py exists. The real fix is renaming selectors.py and queue.py. Until then this trap keeps finding new ways in, and that is not a prediction — it is three for three. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,14 +4,20 @@ After=network.target
|
|||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
# Serves the repo directory itself, so the page is at
|
# WorkingDirectory is deliberately NOT the repo. `-m http.server` puts the
|
||||||
# http://127.0.0.1:8321/dashboard.html — refresher writes dashboard.json in
|
# working directory first on sys.path, and the repo ships selectors.py — so
|
||||||
# here too, both resolved off the package's own __file__.
|
# serving the repo by sitting in it makes socketserver import ours instead of
|
||||||
WorkingDirectory=@REPO@
|
# the stdlib's and the unit crash-loops on
|
||||||
|
# "module 'selectors' has no attribute 'SelectSelector'".
|
||||||
|
# --directory serves the files without standing in them.
|
||||||
|
WorkingDirectory=/
|
||||||
|
# The page is at http://127.0.0.1:8321/dashboard.html — refresher writes
|
||||||
|
# dashboard.json into the same directory, both resolved off the package's own
|
||||||
|
# __file__.
|
||||||
# No --bind: the page is reachable from the LAN, not only from this box.
|
# No --bind: the page is reachable from the LAN, not only from this box.
|
||||||
# openbridge stays loopback-only, so a LAN viewer just falls back to opening a
|
# openbridge stays loopback-only, so a LAN viewer just falls back to opening a
|
||||||
# new tab — progressive enhancement, and the page is never worse than it was.
|
# new tab — progressive enhancement, and the page is never worse than it was.
|
||||||
ExecStart=@VENV@/bin/python -m http.server 8321
|
ExecStart=@VENV@/bin/python -m http.server 8321 --directory @REPO@
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
RestartSec=5
|
RestartSec=5
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -120,10 +120,11 @@ if [[ -z "$USER_BUS" ]]; then
|
|||||||
warn " systemctl status user@$(id -u).service # start here"
|
warn " systemctl status user@$(id -u).service # start here"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
warn "until then, run the three by hand from $REPO:"
|
warn "until then, run the three by hand (from anywhere EXCEPT $REPO):"
|
||||||
warn " $VENV/bin/socialmag-openbridge &"
|
warn " $VENV/bin/socialmag-openbridge &"
|
||||||
warn " $VENV/bin/python -m http.server 8321 &"
|
warn " $VENV/bin/python -m http.server 8321 --directory $REPO &"
|
||||||
warn " $VENV/bin/socialmag-refresh # one pass, whenever you want it"
|
warn " $VENV/bin/socialmag-refresh # one pass, whenever you want it"
|
||||||
|
warn " (-m from inside the repo imports its selectors.py over the stdlib's)"
|
||||||
else
|
else
|
||||||
mkdir -p "$UNIT_DIR"
|
mkdir -p "$UNIT_DIR"
|
||||||
for src in "$REPO"/deploy/user/*.in; do
|
for src in "$REPO"/deploy/user/*.in; do
|
||||||
|
|||||||
Reference in New Issue
Block a user