-
-
Notifications
You must be signed in to change notification settings - Fork 731
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tibber: recover from disconnect #18504
Conversation
select { | ||
case <-tick: | ||
case <-ctx.Done(): | ||
return | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't that really
select { | |
case <-tick: | |
case <-ctx.Done(): | |
return | |
} | |
select { | |
case <-ctx.Done(): | |
return | |
default: | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No really. The tick is to ensure we don't hammer the pulse in case it just asked to disconnect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Das macht doch schon der loop?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nein, der Loop initialisiert den tick
doch nur einmalig. Das Warten entsteht dann durch den select auf dem tick
, oder hab ich das jetzt komplett falsch verstanden?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, stimmt. Tricky. Das warten könnte man auch im for machen.
I don't understand this PR. It will exit the loop on any client error. Imho it also doesn't fix the stuck clients, these would accumulate. |
That's not my understanding. On errors, the clients internal logic will do a resubscribe, so it never gets here.
Well that's the thing. The clients are not stuck, they just exit. I posted my analysis here. And this exactly is what this change is about. The specific scenario is that the Pulse denies the subscription (although the given data for the subscription is known valid just a few seconds ago). When it does this, it sends the client a request to properly shutdown - which the client library obeys. That is exactly when you land back in this go routine I changed, but with So in a nutshell what we do is, we follow the ask of the server (i.e. Pulse) to shutdown the websocket gracefully, and then after 10s we bring it back up anew. |
They are clearly stuck because the error channel is blocked as the pprof tells? |
Not to my understanding. The routine that waits on the error channel inside The actual issue (based on my understanding of the pprof) is that the "main" routine of the client exits and so does then the evcc routine that called If you are not convinced, I would suggest we patch |
Long story short: es müsste mal jemand diesen PR ausprobieren 👍🏻 |
Ist das schon im nightly Docker Build? Dann könnte ich es sofort ausprobieren |
@GrimmiMeloni es blockt beim Schreiben (nicht beim Lesen!) in den Error Channel. Der Client bliebt also hängen- schau bitte nochmal in das pprof. |
Ja, ich habe in meiner Erklärung die Threads vertauscht, dumm. Sorry für die Verwirrung. Die Analyse ist aber trotzdem sauber. Du hast Recht, das dieser Writer auf dem Channel blockt und somit hängt. An den Logs können wir ferner erkennen, daß eine Nachricht für den Shutdown der wsClient Verbindung empfangen wird. Wir kommen also hier vorbei, was den Reader (und somit den einzigen consumer des error channel) beendet: Das Denn - nehmen wir an, der Reader würde den Writer noch sauber beenden. Dann bliebe doch gar nichts mehr im pprof was noch mit Tibber zu tun hat. Nochmal anders gesagt: In allen Fällen in denen wir aus |
Ja. Ändert aber nix dran dass der damit hängt und weiter Speicher verbraucht. Aber zur Not ist das so
Verstehe ich weiter nicht. Run wird beendet. Der ganze Sinn Deines |
In dem hier diskutierten Szenario geht er nicht mit Fehler raus. Aus Sicht der Client Lib kommt ein sauberer Request durch, der dann auf ws-Protokoll Ebene ein Verbindungsende anfordert. Daraus würde ich jetzt nicht unbedingt ableiten, daß es im Fehlerfall richtig(er) ist, auch wieder den Client neuzustarten. Andererseits gibt es in evcc auch keine andere Möglichkeit das noch abzufangen. Dann also Vorschlag: Return raus nehmen, und Immer restarten (in tibber-pulse.go). |
Co-authored-by: Michael Heß <[email protected]>
fix #17925
@andig I have no tibber to actually test this, but the logic is simple enough...