tmux-plugins / tmux-resurrect

Persists tmux environment across system restarts.
MIT License
11.27k stars 420 forks source link

What is the best way to close down a complex tmux session - after having saved? #120

Open michael-coleman opened 8 years ago

michael-coleman commented 8 years ago

When I have lots of windows and panes - and programs inside those panes, e.g. vim, htop etc, and say I want to do a computer restart, I normally:

I do it manually like this because its generally not recommended to interrupt a running process. I'm just wondering how other people do this - is it possible to close everything all at once?

bruno- commented 8 years ago

Hey, good question.

For closing individual tmux sessions I use tmux-sessionist prefix - X key binding. It's similar to $ tmux kill-session command plus some benefits.

For closing all tmux sessions I just use $ tmux kill-server command.

Above approaches ignore the advice not to interrupt running processes in the panes and I've never had any issues with this (and I've manually tested and banged on tmux and tmux-resurrect really really hard).

Also, I think I once did a quick investigation to find out if any of the programs are still running after $ tmux kill-server. None of the programs/processes were running after tmux was killed.

michael-coleman commented 8 years ago

thanks for the reply, Yes it would be nice to close everything all at once! So in terms of restoring afterwards, if you are running both tmux-continuum and tmux-resurrect - and you save the session with <prefix><C-s> prior to closing. Which save file does resurrect restore from? the latest of the files automatically created by continuum or the one manually created by <prefix><C-s> ? It looks like they both write to the same file e.g.

~/.tmux/resurrect/last -> tmux_resurrect_2015-11-22T05:41:37.txt

So I'm guessing that if you do a manual save prior to closing down with <prefix><C-s> - it writes out a new timestamped resurrect file like above - and because tmux continuum only makes a new save file if 15 mins has passed - you don't have the problem of tmux-continuum creating another save - at some partially closed down state - if you are closing down one pane at a time and take a few minutes before you actually close the session?

bruno- commented 8 years ago

Hey,

Which save file does resurrect restore from? the latest of the files automatically created by continuum or the one manually created by ?

Whichever happens the latest. As you noticed, both manual save and tmux-continuum store saved file in the same way (in fact, tmux-continuum just delegates the saving work to tmux-resurrect plugin so saving process is identical).

if you do a manual save prior to closing down with - it writes out a new timestamped resurrect file like above - and because tmux continuum only makes a new save file if 15 mins has passed - you don't have the problem of tmux-continuum creating another save

The idea with tmux-continuum is that you don't have to bother with saving ever again. So if you use tmux-continuum and then additionally perform manual saves, that goes against its purpose.

at some partially closed down state - if you are closing down one pane at a time and take a few minutes before you actually close the session?

You can pretty much guess what will happen here. If the 15 minutes interval hits while the user is halfway through closing panes, then the save will be partial. You can manually restore from the previous save file. It's not that hard, but let's not get into that here. My hope is that working with tmux doesn't take you that much time. Minutes for closing down is a lot. Closing tmux sessions or killing the whole tmux server should happen in a snap.

michael-coleman commented 8 years ago

Hi, thanks for the reply ! Yes shutting down using tmux-sessionist- would nicely solve the problem of - which restore file gets used? I have an issue which prevents closing down the session like that: restoring vim sessions, i.e. set set -g @resurrect-strategy-vim 'session' in .tmux.conf. Sometimes I need to manually establish that there is a Session.vim file in the directory vim is using, if not, the vim session/state won't be captured in the tmux-resurrect save. Because there is possibly a few windows like that, my preference is to:

By doing that I can have some confidence the vim sessions will be restored. This can take a few minutes or more - file permission problems writing out Session.vim files etc. My testing (and your comments reinforce) found that the continuum timestamp check ignores the save made by the manual resurrect save - so its likely that automatic save will occur while shutting down windows. The easiest solution I can think of currently is to pass this into tmux command prompt before I begin session close down

set -g @continuum-save-interval '0'

Running tmux show-options -g confirms it sets the option in tmux. I just haven't tested it.
I've also looked into the source to see how you're checking the timestamps, and wondering if you would consider a pull request where the timestamp check takes into account manual saves - because if someone manually saves - then shouldn't that take priority over the auto save? I'm also trying to work out what triggers the whole plugin . I've read that tmux updates its status bar periodically - when this happens does tmux.conf get run again, thereby triggering the plugin again? ,e.g.

run-shell ~/.tmux/plugins/tmux-continuum/continuum.tmux
timblaktu commented 1 year ago

@michael-coleman, to your final question there, I'm pretty sure tmux.conf is NOT re-loaded every status bar update. The tmux designers were smarter than that, which would be very cumbersome amount of config thrashing.

Moreover, I wanted to resurrect this resurrection convo and ask where you landed with this. (You remember everything you were doing 8 years ago, right?) I'm tackling a similar problem now - running Hyprland WM and wanting to add support to my "shutdown everything" script for gracefully saving/exiting my vim and tmux sessions, since I'm finding intermittent, unexpected vim .swp files on resurrection.

In my case, I want complete automation, and map SUPER+x to a script runs that shuts everything down gracefully, ending in a final sudo shutdown call. For the tmux part, I believe I need to:

# ensure tmux session(s) are saved and exited gracefully
TMUX_SESSION=0
# disable tmux-continuum auto-saving
tmux set -g @continuum-save-interval '0'
# save the session with tmux-resurrect
tmux send-keys -t${TMUX_SESSION} C-a C-s
# kill the session with tmux-sessionist
tmux send-keys -t${TMUX_SESSION} C-a C-x

Because:

I believe I must execute the same scripts that the tmux plugins run via keybindings. Above, I've chosen to send the mapped key bindings to the session, but I could have instead run-shell <path to plugin script bound to keys>. This is the part that I'm implementing/testing and wanting collaborate on. So far, it appears to work, but I'll only know for sure after using it a long time without any unexpected vim .swp files on resurrect...

timblaktu commented 8 months ago

Came back around to this recently after toiling a bit with my previous approach mentioned above. I've figured out IMO the best solution to this issue: let systemd handle it. With the below system service instantiated for your $USER and enabled, systemd will automatically and synchronously call this plugin's save script to force a session save before killing the session. The additional benefit is that the tmux server starts earlier during boot, before user login, and creates a session named after the user. This means the session, which will have been auto-restored by this plugin, will be ready for use by the time you login and attach to it. So, for sessions with any amount of complexity, this can save time, at least on first creation..

> cat /etc/systemd/system/tmux@.service
[Unit]
Description=tmux session for %I
Documentation=man:tmux(1)

[Service]
Type=forking
User=%I
# WARNING: use %I instead of %u here; %u=root in system services.
ExecStart=/usr/bin/tmux -v new-session -s %I -d
ExecStop=/home/%I/.tmux/plugins/tmux-resurrect/scripts/save.sh
ExecStop=/usr/bin/tmux -v kill-session -t %I
WorkingDirectory=~

[Install]
WantedBy=multi-user.target