Short version: How do you restart a lost X11 connection from within R when working on a remote machine ?
Long version:
I work with Mac 11.1 and connect to a remote Linux server to code in R (through Nvim-R). The steps I use are usually:
ssh -Y [email protected]
screen -r my_R_work_session
conda activate my_environment
nvim code.r
and then type \rf
command to open a R terminal within nvim
.
Then I am able to plot anything in R (eg. with plot(iris)
). The plot pops up in an external window (through X11
/ XQuartz
) on my Mac. It usually works fine at the beginning.
But at some point, I might lose the connection to the server for just a second (internet failure, vpn stops...), and everything seems to work fine when I get back the connection to the server (main ssh
connection is maintained) except the X11 connection.
At this point, the output of any plot(iris)
would be:
Error in .External2(C_X11, d$display, d$width, d$height, d$pointsize, :
unable to start device X11cairo
In addition: Warning message:
In function (display = "", width, height, pointsize, gamma, bg, :
unable to open connection to X11 display ''
The only solution I found for the moment is starting a new ssh connection to the server and re-do the whole process up to starting the R session and plotting stuff. Sometimes, closing only the screen
session works, but I still need to reload conda
and my R
session. But it's time-consuming (and annoying) and my guess is that there might be a better solution.
I found many posts googling this error, but still nothing that could resolve this issue.
- Check capabilities()
Before losing X11 connection, the output of capabilities()
is:
jpeg png tiff tcltk X11 aqua
TRUE TRUE TRUE TRUE TRUE FALSE
http/ftp sockets libxml fifo cledit iconv
TRUE TRUE TRUE TRUE TRUE TRUE
NLS profmem cairo ICU long.double libcurl
TRUE TRUE TRUE TRUE TRUE TRUE
After losing X11 connection, the only difference is then that X11
is set to FALSE
.
- Check DISPLAY
Refering to this post, I checked DISPLAY
but everything seems to be fine.
In terminal (before starting R or while r is running):
> echo $DISPLAY
localhost:10.0
In R:
> Sys.getenv("DISPLAY")
localhost:10.0
And I tried setting Sys.setenv("DISPLAY"=":0.0")
but does not make any difference.
- X11UseLocalhost
This post suggests changing X11UseLocalhost no
to X11UseLocalhost yes
in /etc/ssh/sshd_config
, but it does not make any difference to me.
- Xpra
Finally, I tried using Xpra
following the suggestions from this post (probably the most promising one) but did not make any difference either. Although here I am not sure if I use it properly. Here is what I did:
[local] ssh -Y [email protected]
[remote] screen -r xpra
[remote] xpra start :10
# exit screen
[local] xpra attach ssh:remote.server:10
[remote] screen -r my_R_work_session
[remote] conda activate my_environment
[remote] nvim code.r
Thanks a lot for any comment and help !
For anyone bumping into this post, I ended up finding a super simple solution: you just need to start a new ssh -Y
connection in parallel of your current session. Then you can redirect the DISPLAY
parameter in the current session to the value in the new connection.
Here is a more detailed example.
In the current session (before starting the new ssh connection), if you try in R
terminal :
> capabilites() # returns X11 = FALSE
> Sys.getenv('DISPLAY') # returns localhost:xx.0
localhost:12.0
> x11('localhost:12.0') # returns error message
Now you start the new ssh connection in parallel: ssh -Y [email protected]
. You need to find the value of DISPLAY
in this new session, eg:
In bash:
$ echo $DISPLAY
localhost:13.0
Or in R:
> Sys.getenv('DISPLAY')
localhost:13.0
Finally, in the original R terminal, set the DISPLAY
parameter to the new connection value:
> Sys.setenv('DISPLAY' = 'localhost:13.0')
> x11('localhost:13.0') # or x11() - both should work
There is also another option, is to modify the value of ForwardX11Timeout
in ssh config file (~/.ssh/config
). It is usually set to ~20 min by default (see man ssh
). You can try set this to one day (or more), eg: ForwardX11Timeout 1d
. This will prevent X11
to stop during any work session if it's opened less than 24 hours. You can even set ForwardX11Trusted yes
in this config file. However, these options can lead to security leaks, so they need to be considered with care.