This is a pre-release. djust 0.9.7 has shipped since: read the djust 0.9.7 release notes.
Fixed
- ๐จ P0 โ WS-event save block now gated on
enable_state_snapshot(#1475). PR #1466 (0.9.7rc1) shipped an unconditional save block inhandle_event(python/djust/websocket.py:3127-3224) โ every successful WS event for every LiveView triggered async Django-session writes (2-4 round-trips per event:aset(__private),aset(view_key),_save_components_to_sessionviasync_to_async,asave()). The CHANGELOG entry for 0.9.7rc2 called this out as a deliberate design choice for HTTP-path symmetry. That symmetry argument broke on snapshot-on-idle infrastructure: HTTP requests are bounded by the response cycle, but WS events leave async session-backend I/O in flight beyondsend_json. When djustlive's fc-proxy snapshotted a firecracker microVM 200ms after closing all backend WS conns at the host TCP layer, uvicorn ended up with pending async tasks frozen in the snapshot โ TCP listener accepted post-restore but never returned response bytes. Forever. Site down indefinitely on idle cycles. 0.9.6 worked fine with the same 200ms settle; only the new save block extended the close-time tail latency beyond it. Fix: AND the existing top-level-identity gate withgetattr(self.view_instance, "enable_state_snapshot", False). Default views ship 0.9.6 close-path semantics (zero async writes per event); only opt-in views pay the latency for the feature they asked for. Defense-in-depth: wraps the save body inasyncio.wait_for(..., timeout=0.150)so even opt-in views can't extend close-time tail latency under DB/Redis backpressure. On timeout, logs warning and continues โ saves never break event handling. 3 new regression tests inpython/djust/tests/test_ws_reconnect_state_1465.py: opt-out integration test via realWebsocketCommunicator(load-bearing negative assertion that session key stays absent), source-pin for the AND'd gate, andasyncio.wait_forsemantics validation. Action #254 gate-off self-test: reverting the gate causes the 3 new + 2 source-pin tests to fail at their load-bearing assertions. Unblocks djustlive on 0.9.7+. djustlive operators: revert the 0.9.6 rootfs pin to 0.9.7rc3 once this release is published.
Added
- Pre-commit auto-restage commit wrapper โ opt-in (#1464). New
scripts/git-commit-with-precommit.shandmake commit MSG="..."target. Runsuvx pre-commit run --files <staged>first; if hooks (ruff-format, ruff --fix, etc.) rewrote staged files the wrapper computes a per-file hash diff andgit adds only the files whose content actually changed, then proceeds togit commit. Eliminates the ruff-bounce friction class where vanillagit commitexits non-zero with the reformat left unstaged โ the failure mode hit 5ร across v0.9.7-2 PRs (#1454, #1457, #1462, #1463, #1466) at ~30s per bounce. Baregit commitpath unchanged; wrapper is opt-in. Path handling is NUL-delimited (git diff --cached -z) so filenames containing spaces or glob metacharacters round-trip safely. The per-file (not bulk-A) restage preserves unstaged hunks from agit add -ppartial stage. Post-commit Action #122 verification (git rev-parse HEADadvanced) is built in. Pre-flightgit rev-parse --git-dircheck gives a clean exit-1 outside a repo. macOS bash 3.2 compatible (nodeclare -A, nomapfile -d). 9 regression tests intests/test_git_commit_with_precommit.py.