emacs-circe / circe

Circe, a Client for IRC in Emacs
GNU General Public License v3.0
395 stars 51 forks source link

Auto-reconnect after suspend #327

Open humitos opened 6 years ago

humitos commented 6 years ago

Hi! Thanks for this plugin :)

I'm migrating from ERC to Circe and I found a couple of things that are too much simpler and they "just works" -most of them I spent hours to make it work in ERC :)

One thing that I'm not being able to configure as I had in my ERC setup is that "I want to be connected to Freenode everytime that I have emacs opened". So, I auto connect when emacs starts just by running

(circe "Freenode")

at the end of my circe settings.

Then, when I close the lid of the notebook it gets suspended and when I opened it and resume I'd like Circe to detect that I'm offline and re-connect automatically. How I can do that?

I used to have this hack in my ERC setup, as a reference: it checks every 25 seconds if the ERC server process is alive and if not reconnects.

;; check if we are connected to "#readthedocs" and reconnect if not
(defun erc-check-connected-and-reconnect ()
  (if (equal (erc-server-process-alive "#readthedocs") nil)
      (progn
        (switch-to-buffer "#readthedocs")
        ;; we need to be in ERC buffer to call this function
        (erc-server-reconnect)
        (switch-to-buffer (other-buffer)))))

(setq erc-check-connected-and-reconnect-timer
      (run-with-timer nil 25 'erc-check-connected-and-reconnect))

All my circe settings: https://github.com/humitos/emacs-configuration/blob/bd1f39d917f3e4150514db0b1b261090cf641f0f/startup.d/circe.el

jorgenschaefer commented 6 years ago

You can use lagmon – (circe-lagmon-mode) – to reconnect if you get disconnected.

I'm currently amazed that apparently, process-status will show a process as dead on disconnect without a sentinel being triggered. That seems like a bug in Emacs.

humitos commented 6 years ago

Thanks @jorgenschaefer! That answer my questions and I was able to make it work properly. I don't have to worry about suspending my laptop again ;)

I didn't get your last comment, though :/ --seems more technical that I can handle :)

ghost commented 6 years ago

I think this should be highlighted in wiki - I've hit this issue as well. It also might make sense to enable lagmon by default until this Emacs bug is resolved.

I've enabled lagmon via customize and have looked at related options as well. What's the value for "Circe Lagmon Timer Tick" is it seconds ot smth else? Would be nice to expand docs to make it easier to understand.

jorgenschaefer commented 6 years ago

@humitos Yeah, that was a technical observation. "Emacs does not do the right thing there even though it should know better, wow!" :-)

@osmoc Yes, better documentation would be nice. If you have good ideas, please change the wiki and suggest something via a PR :-)

Apparently, if the observation above is correct, we can file an Emacs bug report. Can someone who experiences this problem run M-: (process-status (circe-server-process)) while Circe is disconnected, but does not reconnect automatically?

untoreh commented 6 years ago

i see the gitter irc bridge server reconnecting every 2 minutes, but maybe its just gitter's fault since freenode is stable

humitos commented 6 years ago

Do we have a workaround for this?

Can someone who experiences this problem run M-: (process-status (circe-server-process)) while Circe is disconnected, but does not reconnect automatically?

@jorgenschaefer I just seen this comment. Sorry for the late response. I will test it when I hit this issue.

A quick test was to discconnect my laptop from wifi and run that command. It returns run immediately and also after 5 and 10 minutes. After like 15 or 20 minutes it returns signal.

After the signal was returned, I reconnect my wifi and after a couple of minutes, write a message in a circe buffer and I got Proccess irc.freenode.net is not running in the messages buffer. The process-status command still returns signal.

(message "%s" circe-server-process)
"nil"
(process-status (circe-server-process))
signal

I tried to follow a little bit the circe-lagmon.el code and I it seems that we need registered in the function circe-lagmon-timer-tick to finally call circe-lagmon-server-check. Isn't it possible to call circe-lagmon-server-check without checking for the process status?

Let me know what else I can provide or how I can help.

i see the gitter irc bridge server reconnecting every 2 minutes, but maybe its just gitter's fault since freenode is stable

@untoreh I'm not experimenting this issue with my gitter account.

humitos commented 6 years ago

Another thing that I found...

This line

https://github.com/jorgenschaefer/circe/blob/f7f7cb62a992120bf80c3a078bec1c029f8ff0cd/circe-lagmon.el#L106-L108

shouldn't be

                 (eq (irc-connection-state (circe-server-process))
                     'registered)

Note that I'm calling (circe-server-process) instead of accessing the variable.

humitos commented 6 years ago

When the server is running and connected

(circe-lagmon-server-check)

I see this message in my circe buffer:

*** Unknown CTCP request LAGMON from humitos (~humitos@186.66.164.207): 1522257056.9204223
jorgenschaefer commented 6 years ago

Yes, you have to enable the lagmon mode so it can install a lagmon handler.

The tests you ran means that Emacs knows that a process disconnected, but it does not tell the program (Circe) that is running on it about that. That's terrible. :-(

To work around this, Circe would have to continuously check the status. Emacs really should notify the process sentinel there. (Anyone want to volunteer submitting an Emacs bug report? :-D)

jgkamat commented 6 years ago

For me at least, the command returns run when I'm disconnected and connected. I use the tls network connection, so I tried to connect directly with gnutls-cli and openssl directly to freenode, and they both seem to hang doing nothing if the wifi network is switched or the computer is put to sleep and woken up. So at least for me, I don't think the issue is on emacs's end. I'm not sure if these tools are supposed to be quitting when a disconnect happens, do you know anything about that? For some reason, connecting via nc disconnects when the network fails, but connecting with gnutls-cli seems to hang...

jorgenschaefer commented 6 years ago

Both tools probably suffer from a similar problem as Emacs. They should indeed notice a problem and disconnect. Maybe openssl/gnutls have a keepalive option somewhere? That would help.

vuori commented 6 years ago

I'm dealing with similar problems. I'm not familiar with Emacs networking, but how difficult would it be to use open-network-stream instead of make-tls-process? The former should automatically use Emacs built-in GnuTLS support instead of external tools when possible, which would eliminate at least one source of problems.

jorgenschaefer commented 6 years ago

I suspect there are still problems with o-n-s for windows, but I'd be very happy with switching to o-n-s in irc.el – getting rid of that self-made openssl wrapper would be good, too.

untoreh commented 6 years ago

@humitos because the def value of lagmon reconnect is 120 so it keeps reconnecting even though it is still connected but somehow the health check done by circe times out. Maybe it's because gitter has only US location. I tried increasing the reconnect interval but doesn't seem to help

jgkamat commented 6 years ago

Gitter's irc bridge dosent transmit CTCP messages so lagmon wont work (and probably interferes). I wouldn't reccomend using it there.

custoz commented 4 years ago

Hi! Is it possible to enable circe-lagmon-mode for this scope only on a specific server (e.g. Freenode) and keep it disabled for others?

wasamasa commented 4 years ago

There's the :lagmon-disabled option for networks.

custoz commented 4 years ago

I didn't notice it :( Thanks a lot! This solves my issues with bitlbee :)