Re: bug#62044: 30.0.50; ERC 5.5: Auto-reconnect is broken
"J.P." <[email protected]>
| Newsgroups | gmane.emacs.erc.general |
|---|---|
| Message-ID | <[email protected]> |
xoddf2 <[email protected]> writes: > J.P. writes: > >> Hi xoddf2, >> >> [...] For starters, we need to find a recipe, all the way from >> emacs -Q, that triggers the unwanted behavior. That way, we can dispense >> with any possible complications arising from your init.el and any >> third-party packages [...] > > After running emacs-snapshot -Q, I yanked the below Emacs Lisp code into > the *scratch* buffer, evaluated it, then ran M-x erc. I left server and > port at default (irc.libera.chat and 6667, respectively), set nick to > aoddf2, and left the server password blank. I then joined ##test. I > said something in that channel from my usual client, disconnected the VM > from the network in NetworkManager Applet, and then waited a few > minutes. I reconnected and then waited again. ERC had still not > reconnected. Thanks for the logs and the lowdown As with many things IRC, there are two senses of "connectivity" at play here with regard to automatic reconnections: network and application. In your initial report, underlying connectivity is present in some form because ERC reaches the "Logging in as" stage and attempts to send an application payload, though there's no telling how far it actually gets. In your followup, network connectivity is absent due to your "disconnecting the VM", something confirmed by the logs. While I think this simulation is worth exploring, we probably shouldn't assume it's failing in a meaningfully similar way to the real-life connection you're losing to your bouncer, at least not without trying the settings you laid out initially and also seeking a better understanding of what the NM applet is actually doing when you flip the switch. So to keep things sane, we should probably treat auto-reconnecting across connectivity gaps as a wishlist item and auto-reconnecting atop healthy connections as an existing, previously unreported bug. As for the new feature, I've attached a POC patch that you can try if you're willing (usage is self-explanatory, but feel free to modify or iterate as needed). As for the other issue, I think we're going to need some genuine session logs to really get anywhere. That is, we'll likely need you to enable logging and tracing during a real session with your bouncer over a hopefully not-too-prolonged period to capture an actual reconnect sequence failing. But hold off on that for another round unless you're feeling adventurous. Thanks again.
0001-Add-conditional-erc-server-reconnect-function.patch
(text/x-patch, 2.7 KB)
From 7c0d22d187400cf2445044f6526814a72b45a86d Mon Sep 17 00:00:00 2001 From: "F. Jason Park" <[email protected]> Date: Wed, 8 Mar 2023 06:14:36 -0800 Subject: [PATCH] Add conditional erc-server-reconnect-function * lisp/erc/erc-backend.el (erc--server-reconnect-timer, erc-server-delayed-check-reconnect): Add possible alternate value for option `erc-server-reconnect-function' that only attempts to reconnect after hearing back from the server. Also add helper variable. --- lisp/erc/erc-backend.el | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el index 567443f5329..d1738e4f92d 100644 --- a/lisp/erc/erc-backend.el +++ b/lisp/erc/erc-backend.el @@ -744,6 +744,47 @@ erc-server-delayed-reconnect (with-current-buffer buffer (erc-server-reconnect)))) +(defvar-local erc--server-reconnect-timeout nil) + +(defun erc-server-delayed-check-reconnect (buffer) + "Wait for internet connectivity before trying to reconnect. +BUFFER is the server buffer for the current connection." + (with-current-buffer buffer + (setq erc--server-reconnect-timeout + (min 300 (* (or erc--server-reconnect-timeout + erc-server-reconnect-timeout) + 2))) + (let ((reschedule + (lambda (proc) + (let ((erc-server-reconnect-timeout + erc--server-reconnect-timeout)) + (with-current-buffer buffer + (delete-process proc) + (erc-display-message nil 'error buffer "Nobody home...") + (erc-schedule-reconnect buffer 0)))))) + (condition-case _ + (make-network-process + :name "*erc-connectivity-check" + :host erc-session-server + :service erc-session-port + :nowait t + :filter + (lambda (proc _) + (delete-process proc) + (with-current-buffer buffer + (setq erc--server-reconnect-timeout nil)) + (run-at-time nil nil #'erc-server-delayed-reconnect buffer)) + :sentinel + (lambda (cproc event) + (with-current-buffer buffer + (pcase event + ("open\n" + (run-at-time nil nil #'send-string + cproc "PING *connect-check*\r\n")) + ("connection broken by remote peer\n" + (funcall reschedule cproc)))))) + (file-error (funcall reschedule nil)))))) + (defun erc-server-filter-function (process string) "The process filter for the ERC server." (with-current-buffer (process-buffer process) -- 2.39.2