Skip to content

Commit d5670ec

Browse files
committed
Shut down on SIGTERM and SIGHUB
This allows saving the sessions when terminating.
1 parent 10fed09 commit d5670ec

File tree

2 files changed

+33
-18
lines changed

2 files changed

+33
-18
lines changed

webware/Application.py

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import atexit
1717
import os
18+
import signal
1819
import sys
1920

2021
from time import time, localtime
@@ -239,8 +240,13 @@ def __init__(self, path=None, settings=None, development=None):
239240
self._plugInLoader = None
240241
self.loadPlugIns()
241242

242-
self._wasShutDown = False
243+
self._needsShutDown = [True]
243244
atexit.register(self.shutDown)
245+
signal.signal(signal.SIGTERM, self.sigTerm)
246+
try:
247+
signal.signal(signal.SIGHUP, self.sigTerm)
248+
except AttributeError:
249+
pass # SIGHUP does not exist on Windows
244250

245251
def initErrorPage(self):
246252
"""Initialize the error page related attributes."""
@@ -368,22 +374,25 @@ def shutDown(self):
368374
369375
Called when the interpreter is terminated.
370376
"""
371-
if not self._wasShutDown:
372-
print("Application is shutting down...")
373-
atexit.unregister(self.shutDown)
374-
if self._sessions:
375-
self._sessions.storeAllSessions()
376-
tm = self.taskManager()
377-
if tm:
378-
tm.stop()
379-
# Call all registered shutdown handlers
380-
shutDownHandlers = self._shutDownHandlers
381-
while shutDownHandlers:
382-
try:
383-
shutDownHandlers.pop(0)()
384-
except Exception:
385-
pass
386-
print("Application has been successfully shutdown.")
377+
try: # atomic safety check
378+
self._needsShutDown.pop()
379+
except IndexError: # shut down already initiated
380+
return
381+
print("Application is shutting down...")
382+
atexit.unregister(self.shutDown)
383+
if self._sessions:
384+
self._sessions.storeAllSessions()
385+
tm = self.taskManager()
386+
if tm:
387+
tm.stop()
388+
# Call all registered shutdown handlers
389+
shutDownHandlers = self._shutDownHandlers
390+
while shutDownHandlers:
391+
try:
392+
shutDownHandlers.pop(0)()
393+
except Exception:
394+
pass
395+
print("Application has been successfully shut down.")
387396

388397
def addShutDownHandler(self, func):
389398
"""Add a shutdown handler.
@@ -394,6 +403,12 @@ def addShutDownHandler(self, func):
394403
"""
395404
self._shutDownHandlers.append(func)
396405

406+
def sigTerm(self, _signum, _frame):
407+
"""Signal handler for terminating the process."""
408+
print("\nApplication has been signaled to terminate.")
409+
self.shutDown()
410+
sys.exit()
411+
397412
# endregion Init
398413

399414
# region Config

webware/Tests/TestEndToEnd/AppTest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def tearDownClass(cls):
6868
chdir(cls.currentDir)
6969
if cls.catchOutput and output != (
7070
'Application is shutting down...\n'
71-
'Application has been successfully shutdown.'):
71+
'Application has been successfully shut down.'):
7272
raise AssertionError(
7373
'Application was not properly shut down. Output was:\n'
7474
+ output)

0 commit comments

Comments
 (0)