Skip to content

Deck splash never recovers if a mode service's own Restart=on-failure exhausts #11

Description

@dubpixel

Bug

dpx-deck-splash.service never automatically comes back if the currently-active mode service dies and its own Restart=on-failure retry limit is exhausted. The deck is left frozen on whatever was last drawn, with no live process listening for key presses — GO (or any key) appears completely unresponsive, but it's not a logic bug in execute_staged()/GO's handler; there's simply no process running to receive the press at all.

Root cause

dpx-deck-splash.service only has a Conflicts= relationship with the three mode services (bitfocus-buttons-usb-relay.service satellite.service companion.service) — mutual exclusion, starting one stops the others. Each mode service independently has its own Restart=on-failure. But nothing ties the two together in the other direction: if a mode service's own restart attempts exhaust (systemd's StartLimitBurst) and it ends up genuinely failed/inactive, nothing notices and starts dpx-deck-splash.service back up. Conflicts= alone doesn't do this — it only prevents simultaneous activity, it's not a trigger.

Confirmed live 2026-08-31 — reported as two symptoms that are actually the same root cause:

  • "What's not clear is when the splash comes back" — currently, only if a mode is switched via the web UI/SSH; the deck itself has no path back to a live screen once its own process isn't running.
  • "Sometimes when the device is already in a mode but not started, hitting GO does not start the thing" — GO's own logic (gotcha #15's mode_dead check in execute_staged()) is correct and unaffected; the actual problem is there's no live dpx-deck-splash process to receive the keypress in the first place.

Proposed direction (needs a design decision, not blindly implemented)

Some kind of watchdog that starts dpx-deck-splash.service if none of the three mode services end up active, rather than relying solely on Conflicts=. Options to consider:

  • A periodic timer unit that checks "is any mode service active?" and starts dpx-deck-splash.service if not
  • OnFailure= on the mode services pointed at some intermediary check (risk: could fire on every transient restart attempt, not just final exhaustion — would fight the mode service's own recovery if not scoped carefully)
  • Tie into the existing switch_mode()/mode_service_active() pattern somehow, though that's currently only exercised from the web UI's own request path, not a standalone watchdog

Environment

  • Confirmed on real Pi 4 hardware, build main @ 8080ce3
  • Likely applies to all boards/builds equally — this is a systemd unit relationship issue, not board/OS-specific

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions