From d7a0147191f1616b0e2f4d60972d1b318daf59ff Mon Sep 17 00:00:00 2001 From: Safihre Date: Tue, 6 Dec 2016 15:52:23 +0100 Subject: [PATCH] Implement direct restarts (when possible) --- SABnzbd.py | 49 ++++++++++++++++++++++++------------------------- sabnzbd/__init__.py | 43 +++++++++++++++++++++++++++++++++---------- sabnzbd/interface.py | 8 +++----- sabnzbd/osxmenu.py | 9 +++------ sabnzbd/sabtray.py | 9 +++------ sabnzbd/sabtraylinux.py | 3 +-- 6 files changed, 67 insertions(+), 54 deletions(-) diff --git a/SABnzbd.py b/SABnzbd.py index 18d52f2..ceb4835 100755 --- a/SABnzbd.py +++ b/SABnzbd.py @@ -884,7 +884,7 @@ def main(): repair = 0 api_url = None no_login = False - re_argv = [sys.argv[0]] + sabnzbd.RESTART_ARGS = [sys.argv[0]] pid_path = None pid_file = None new_instance = False @@ -902,11 +902,11 @@ def main(): fork = True autobrowser = False sabnzbd.DAEMON = True - re_argv.append(opt) + sabnzbd.RESTART_ARGS.append(opt) elif opt in ('-f', '--config-file'): inifile = arg - re_argv.append(opt) - re_argv.append(arg) + sabnzbd.RESTART_ARGS.append(opt) + sabnzbd.RESTART_ARGS.append(arg) elif opt in ('-h', '--help'): print_help() exit_sab(0) @@ -950,11 +950,11 @@ def main(): pause = True elif opt in ('--force',): force_web = True - re_argv.append(opt) + sabnzbd.RESTART_ARGS.append(opt) elif opt in ('--https',): https_port = int(arg) - re_argv.append(opt) - re_argv.append(arg) + sabnzbd.RESTART_ARGS.append(opt) + sabnzbd.RESTART_ARGS.append(arg) elif opt in ('--repair',): repair = 1 pause = True @@ -967,19 +967,19 @@ def main(): no_login = True elif opt in ('--pid',): pid_path = arg - re_argv.append(opt) - re_argv.append(arg) + sabnzbd.RESTART_ARGS.append(opt) + sabnzbd.RESTART_ARGS.append(arg) elif opt in ('--pidfile',): pid_file = arg - re_argv.append(opt) - re_argv.append(arg) + sabnzbd.RESTART_ARGS.append(opt) + sabnzbd.RESTART_ARGS.append(arg) elif opt in ('--new',): new_instance = True elif opt in ('--sessions',): - re_argv.append(opt) + sabnzbd.RESTART_ARGS.append(opt) force_sessions = True elif opt in ('--console',): - re_argv.append(opt) + sabnzbd.RESTART_ARGS.append(opt) osx_console = True elif opt in ('--ipv6_hosting',): ipv6_hosting = arg @@ -1617,7 +1617,7 @@ def main(): # Check the threads if not sabnzbd.check_all_tasks(): autorestarted = True - cherrypy.engine.execv = True + sabnzbd.TRIGGER_RESTART = True # Notify guardian if sabnzbd.WIN_SERVICE and mail: mail.send('active') @@ -1626,20 +1626,19 @@ def main(): # 3 sec polling tasks # Check for auto-restart request - if cherrypy.engine.execv: - if sabnzbd.SCHED_RESTART: - scheduler.abort() - sabnzbd.halt() - else: - scheduler.stop() - sabnzbd.halt() - cherrypy.engine.exit() + # Or special restart cases like Mac and WindowsService + if sabnzbd.TRIGGER_RESTART: + # Shutdown + cherrypy.engine.exit() + sabnzbd.halt() sabnzbd.SABSTOP = True + if sabnzbd.downloader.Downloader.do.paused: - re_argv.append('-p') + sabnzbd.RESTART_ARGS.append('-p') if autorestarted: - re_argv.append('--autorestarted') - sys.argv = re_argv + sabnzbd.RESTART_ARGS.append('--autorestarted') + sys.argv = sabnzbd.RESTART_ARGS + os.chdir(org_dir) if sabnzbd.DARWIN: # When executing from sources on osx, after a restart, process is detached from console diff --git a/sabnzbd/__init__.py b/sabnzbd/__init__.py index ca9ad38..82322d0 100644 --- a/sabnzbd/__init__.py +++ b/sabnzbd/__init__.py @@ -48,6 +48,7 @@ KERNEL32 = None if os.name == 'nt': WIN32 = True + from util.apireg import del_connection_info try: import ctypes KERNEL32 = ctypes.windll.LoadLibrary("Kernel32.dll") @@ -132,6 +133,7 @@ START = datetime.datetime.now() MY_NAME = None MY_FULLNAME = None +RESTART_ARGS = [] NEW_VERSION = None DIR_HOME = None DIR_APPDATA = None @@ -167,7 +169,7 @@ SABSTOP = False RESTART_REQ = False PAUSED_ALL = False OLD_QUEUE = False -SCHED_RESTART = False # Set when restarted through scheduler +TRIGGER_RESTART = False # To trigger restart for Scheduler, WinService and Mac WINTRAY = None # Thread for the Windows SysTray icon WEBUI_READY = False LAST_WARNING = None @@ -388,6 +390,10 @@ def halt(): logging.info('SABnzbd shutting down...') __SHUTTING_DOWN__ = True + # Stop the windows tray icon + if sabnzbd.WINTRAY: + sabnzbd.WINTRAY.terminate = True + sabnzbd.zconfig.remove_server() rss.stop() @@ -437,9 +443,6 @@ def halt(): except: logging.error(T('Fatal error at saving state'), exc_info=True) - # Stop the windows tray icon - if sabnzbd.WINTRAY: - sabnzbd.WINTRAY.terminate = True # The Scheduler cannot be stopped when the stop was scheduled. # Since all warm-restarts have been removed, it's not longer @@ -452,6 +455,28 @@ def halt(): __INITIALIZED__ = False +def trigger_restart(): + """ Trigger a restart by setting a flag an shutting down CP """ + if sabnzbd.downloader.Downloader.do.paused: + sabnzbd.RESTART_ARGS.append('-p') + sys.argv = sabnzbd.RESTART_ARGS + + # Stop all services + sabnzbd.halt() + cherrypy.engine.exit() + + if sabnzbd.WIN32: + # Remove connection info for faster restart + del_connection_info() + + # Leave the harder restarts to the polling in SABnzbd.py + if sabnzbd.WIN_SERVICE or sabnzbd.DARWIN: + sabnzbd.TRIGGER_RESTART = True + else: + # Do the restart right now + cherrypy.engine._do_execv() + + ############################################################################## # Misc Wrappers ############################################################################## @@ -742,19 +767,17 @@ def system_standby(): def shutdown_program(): """ Stop program after halting and saving """ logging.info("Performing sabnzbd shutdown") - Thread(target=halt).start() - while __INITIALIZED__: - time.sleep(1.0) - os._exit(0) + sabnzbd.halt() + cherrypy.engine.exit() + sabnzbd.SABSTOP = True def restart_program(): """ Restart program (used by scheduler) """ - global SCHED_RESTART logging.info("Scheduled restart request") # Just set the stop flag, because stopping CherryPy from # the scheduler is not reliable - cherrypy.engine.execv = SCHED_RESTART = True + sabnzbd.TRIGGER_RESTART = True def change_queue_complete_action(action, new=True): diff --git a/sabnzbd/interface.py b/sabnzbd/interface.py index 896c0eb..35e5f6b 100644 --- a/sabnzbd/interface.py +++ b/sabnzbd/interface.py @@ -942,8 +942,8 @@ class QueuePage(object): else: yield "Initiating shutdown..." sabnzbd.halt() - cherrypy.engine.exit() yield "
SABnzbd-%s shutdown finished" % sabnzbd.__version__ + cherrypy.engine.exit() sabnzbd.SABSTOP = True @cherrypy.expose @@ -1293,9 +1293,8 @@ class ConfigPage(object): yield msg else: yield T('Initiating restart...
') - sabnzbd.halt() yield T(' 
SABnzbd shutdown finished.
Wait for about 5 second and then click the button below.

Refresh
') - cherrypy.engine.restart() + sabnzbd.trigger_restart() @cherrypy.expose def repair(self, **kwargs): @@ -1305,9 +1304,8 @@ class ConfigPage(object): else: sabnzbd.request_repair() yield T('Initiating restart...
') - sabnzbd.halt() yield T(' 
SABnzbd shutdown finished.
Wait for about 5 second and then click the button below.

Refresh
') - cherrypy.engine.restart() + sabnzbd.trigger_restart() @cherrypy.expose def delete(self, **kwargs): diff --git a/sabnzbd/osxmenu.py b/sabnzbd/osxmenu.py index 607b240..85881f7 100644 --- a/sabnzbd/osxmenu.py +++ b/sabnzbd/osxmenu.py @@ -721,8 +721,7 @@ class SABnzbdDelegate(NSObject): def restartAction_(self, sender): self.setMenuTitle("\n\n%s\n" % (T('Stopping...'))) - sabnzbd.halt() - cherrypy.engine.restart() + sabnzbd.trigger_restart() self.setMenuTitle("\n\n%s\n" % (T('Stopping...'))) def restartSafeHost_(self, sender): @@ -732,8 +731,7 @@ class SABnzbdDelegate(NSObject): sabnzbd.cfg.enable_https.set(False) sabnzbd.config.save_config() self.setMenuTitle("\n\n%s\n" % (T('Stopping...'))) - sabnzbd.halt() - cherrypy.engine.restart() + sabnzbd.trigger_restart() self.setMenuTitle("\n\n%s\n" % (T('Stopping...'))) def restartNoLogin_(self, sender): @@ -741,8 +739,7 @@ class SABnzbdDelegate(NSObject): sabnzbd.cfg.password.set('') sabnzbd.config.save_config() self.setMenuTitle("\n\n%s\n" % (T('Stopping...'))) - sabnzbd.halt() - cherrypy.engine.restart() + sabnzbd.trigger_restart() self.setMenuTitle("\n\n%s\n" % (T('Stopping...'))) def application_openFiles_(self, nsapp, filenames): diff --git a/sabnzbd/sabtray.py b/sabnzbd/sabtray.py index 982d88e..1a262db 100644 --- a/sabnzbd/sabtray.py +++ b/sabnzbd/sabtray.py @@ -131,8 +131,7 @@ class SABTrayThread(SysTrayIconThread): # menu handler def restart(self, icon): self.hover_text = self.txt_restart - sabnzbd.halt() - cherrypy.engine.restart() + sabnzbd.trigger_restart() # menu handler def rss(self, icon): @@ -145,8 +144,7 @@ class SABTrayThread(SysTrayIconThread): sabnzbd.cfg.password.set('') sabnzbd.config.save_config() self.hover_text = self.txt_restart - sabnzbd.halt() - cherrypy.engine.restart() + sabnzbd.trigger_restart() # menu handler def defhost(self, icon): @@ -154,8 +152,7 @@ class SABTrayThread(SysTrayIconThread): sabnzbd.cfg.enable_https.set(False) sabnzbd.config.save_config() self.hover_text = self.txt_restart - sabnzbd.halt() - cherrypy.engine.restart() + sabnzbd.trigger_restart() # menu handler - adapted from interface.py def shutdown(self, icon): diff --git a/sabnzbd/sabtraylinux.py b/sabnzbd/sabtraylinux.py index 3ee2626..1886384 100644 --- a/sabnzbd/sabtraylinux.py +++ b/sabnzbd/sabtraylinux.py @@ -165,8 +165,7 @@ class StatusIcon(Thread): def restart(self, icon): self.hover_text = T('Restart') - sabnzbd.halt() - cherrypy.engine.restart() + sabnzbd.trigger_restart() def shutdown(self, icon): self.hover_text = T('Shutdown')