https://bugs.kde.org/show_bug.cgi?id=525548
--- Comment #1 from Sergey <[email protected]> --- Correction to the reproduction steps, with the measurements behind it. After filing this I tried to reproduce the wireplumber churn deterministically, and it did NOT reproduce. I am posting the negative result because the steps in comment 0 are probably wrong, and I do not want to send anyone chasing them. HOW I TESTED I did not drive plasmashell. I wrote a small standalone client that uses the same PulseAudioQt::Context the applet uses, linked against the installed libKF6PulseAudioQt.so.5 (pulseaudio-qt 1.8.1), and ran it for the whole session while the audio stack was cycled underneath it. It logs every stateChanged, autoConnectingChanged, sinkAdded and sinkRemoved together with the resulting model size, so the client model can be compared against the server's actual object set at any moment. Everything ran inside its own dbus-run-session with a private XDG_RUNTIME_DIR, so the machine's real session was never touched. Server truth was read with pactl in the same sandbox. Real ALSA hardware was present in the sandbox, not just the dummy device - pactl showed alsa_output.usb-C-Media_...Lunacy_Louder...analog-stereo and alsa_output.pci-0000_00_1f.3.analog-stereo. (My first attempt only had auto_null, i.e. module-always-sink's dummy, and was meaningless; I redid it after checking pw-dump showed the real nodes coming up.) TEST A - the scenario from comment 0 (only wireplumber cycled) pipewire and pipewire-pulse stayed up the whole time; wireplumber was stopped and started 5 times, 6 s down / 15 s up each cycle. This is what a session-switch helper does. Result: no duplicates, 5 cycles out of 5. Model size tracked the server exactly: cycle 1: sinkRemoved pci index=61 -> count=1 sinkRemoved usb index=57 -> count=0 sinkAdded auto_null -> count=1 sinkRemoved auto_null -> count=0 sinkAdded usb index=108 -> count=1 sinkAdded pci index=113 -> count=2 ...same shape for cycles 2-5, ending at count=2 state was Ready(4) throughout, autoConnecting never went to 1, no Failed state. With pipewire-pulse alive the client context is never torn down, so every removal and addition is delivered normally and the model stays consistent. I now doubt that wireplumber churn alone can produce the duplicates reported here. TEST B - restarting the audio server itself Same client, but pipewire-pulse was killed for >25 s and then restarted, twice. This DID produce a stale entry: T+125033ms | EVENT sinkAdded name='auto_null' index=33 -> count=2 | sink name='auto_null' index=34 | sink name='auto_null' index=33 <- stale, left over Server truth at that moment (pactl list short sinks): a single entry, index 34. So the client model had one object the server did not. That matches the retry logic in pulseaudio-qt's context.cpp (checked against tag v1.8.1): on a bad state, reset() - which is what clears the model - is only called if retries are still left: } else if (!PA_CONTEXT_IS_GOOD(state)) { if (!m_connectTimer.isActive() && hasConnectionTriesLeft()) { reset(); m_connectTimer.start(std::chrono::seconds(5)); maxTries is 5 with a 5 s timer, so after roughly 25 s of downtime the condition is false, reset() is skipped, and objects from the previous connection survive while new ones are added on top. Two things I also observed and cannot explain yet: the client recovers on its own via the QDBusServiceWatcher even after giving up (so auto-reconnect is not permanently disabled), and in test B the second outage produced state=Failed(5) with autoConnecting=0, i.e. it did not retry at all in that window. CAVEAT - what this does and does not prove This exercises PulseAudioQt::Context only. The applet additionally goes through QML model classes (PulseObjectFilterModel) and a kded proxy (kded.contextConnected). Duplicates could live in that layer, and I have not tested it. So: the base context model does not duplicate on wireplumber churn, but I cannot rule out that the applet still does. I will come back with the applet-layer result. If it turns out duplicates only appear on a server restart, this bug would be about the skip of reset() above rather than about device churn, and I am happy to have it retitled or moved. I kept the harness and the full raw logs of both tests, and can attach them here if that helps. -- You are receiving this mail because: You are watching all bug changes.
