Repository navigation
Conversation
… if labels are modified in ui
Member
Author
|
The version of this update should be: 0.0.1-alpha. |
nazbert
added a commit
to nazbert/Deckard
that referenced
this pull request
Jul 12, 2026
Completes the item-StreamController#1 pattern (issue StreamController#55) in the sibling method: the loop re-read controller.active_page per check, so a non-None guard could race a concurrent (dis)connect clearing it and then deref None.json_path. Snapshot it once, mirroring update_input/update_key_image (item StreamController#8). _pages_lock is the wrong tool here -- it guards self.pages, not active_page writes. Also document that _save_locks grows one entry per page path and is never pruned (bounded by page count; no eviction machinery warranted). Extends scenario_reload_similar_pages with a flip-to-None probe (red-checked: pre-fix raises AttributeError on .json_path).
nazbert
added a commit
to nazbert/Deckard
that referenced
this pull request
Jul 12, 2026
…longer freezes the deck (StreamController#1) The writer thread (sole path for paints/brightness/Clear/ClearAndClose since the single-writer migration) ran unguarded: any uncaught exception killed it, freezing the deck until replug while control_q grew unbounded. run() now delegates to _run_one_tick() inside a guarded loop: a tick exception is logged with full traceback (rate-limited to 1/5s with a suppressed-repeat count -- local limiter until StreamController#91), _stop is honored in the except path so a failing body can't strand close(), and a 0.25s wake-event backoff bounds a persistent failure at ~4 retries/s instead of a 100% spin. @log.catch on run() would log once and let the thread die -- the guard must live inside the while. Composes with StreamController#80: the hooks report an escaping death; this prevents the death. The five audit-verified crash vectors are also fixed at the source: (a) init_inputs is build-then-swap and the screensaver drops its `inputs = {}` pre-clear (was an empty-dict window on every screensaver entry); the loop snapshots the dict once per tick and uses .get(); (b) the loop snapshots background.video once (set_video(None) race); (c) touchscreen get_current_image guards a nulled active_page (blank strip); (d) the touchscreen tick gate snapshots state.background_video (_release_background_video race); (e) _exec_clear snapshots the touchscreen slot and nulls it identity-compared -- the crash half of StreamController#1 and this site's half of StreamController#8. tests/scenario_writer_survival.py (first leg of StreamController#61) runs the REAL loop over the stub tier: survives a poisoned tick, resumes paints, caps the log storm, and stop() joins while every tick raises. fixtures gains _QuietInputState (get_active_state) since the live loop path never executed on stubs before (StreamController#69 stub-drift). Suite: 34/34.
nazbert
added a commit
to nazbert/Deckard
that referenced
this pull request
Jul 12, 2026
…ks, finally'd running flag (StreamController#1 review round 1) Review round 1 on MR !3 confirmed two starvation holes in the new guard plus cheap hardening items; all applied: - Batch recovery [MEDIUM]: a caught tick exception had already popped the tick's image_tasks/touchscreen_task, so the failing frame's siblings were lost with it and nothing scheduled recovery -- after e.g. a TypeError on key 3 of a 15-key repaint, the remaining keys kept the previous page's imagery silently forever. The except path now arms _schedule_full_repaint(); its existing 2s rate limit keeps a deterministic per-tick failure from repaint-storming. - Drain-first ticks [MEDIUM]: check_resume_gap/_run_pending_repaint ran before drain_control_queue inside the same guard, so a persistent pre-drain failure starved SetBrightnessMsg/ClearMsg/ClearAndCloseMsg (deck never blanked/closed on quit) -- and the 'drains first, unconditionally' comment was false. The drain now truly leads the tick; comment updated to cover both orderings. - running=False moved into a finally [LOW]: the guard is except Exception, so an escaping BaseException (SystemExit/KeyboardInterrupt) left running=True and every later stop() burned its full 2s join timeout. - Bounded except-path backoff [LOW]: every producer sets _wake_event, so a single wait(0.25) under a set_media storm returned immediately and the retry rate tracked the producer rate; re-wait until the backoff truly elapsed, only _stop cuts it short. - Reworded the rate-limiter suffix ('N earlier repeats were suppressed') -- the old 'in the last 5s' wording was wrong when the suffix emitted hours after the burst. - Updated the stale 'loop has no exception guard' comment in DeckController.__init__. Tests: scenario_writer_survival gains batch-recovery and control-drain legs mirroring the review's probes; both red-tested against their reverted fixes. Harness 34/34.
nazbert
added a commit
to nazbert/Deckard
that referenced
this pull request
Jul 12, 2026
fix(deck): guard the sole-writer media loop (StreamController#1) Closes StreamController#1 See merge request naz/StreamController!3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First beta version of StreamController. Enjoy it!