Reload Application on SIGHUP¶
A common convention in the Linux world is to handle a SIGHUP
signal, by
reloading the current runtime within the same process ID (pid
). The
following example demonstrates how you might achieve that:
import signal
from time import sleep
from cement.core.foundation import CementApp
from cement.core.controller import CementBaseController, expose
from cement.core.exc import CaughtSignal
class MyController(CementBaseController):
class Meta:
label = 'base'
@expose(hide=True)
def default(self):
print('Inside MyController.default()')
### inner loop where the application logic happens
while True:
print('Inside Inner Loop')
sleep(5)
class MyApp(CementApp):
class Meta:
label = 'myapp'
base_controller = MyController
with MyApp() as app:
### outer loop where signals are handles, and application reload
### happens
keep_alive = True
while keep_alive is True:
try:
app.run()
except CaughtSignal as e:
app.log.warning(e.msg)
if e.signum in [signal.SIGHUP]:
app.log.warning('Reloading MyApp')
app.reload()
keep_alive = True
else:
app.exit_code = 1
keep_alive = False
Running the application shows the inner loop in action:
$ python myapp.py
Inside MyController.default()
Inside Inner Loop
Inside Inner Loop
Inside Inner Loop
Inside Inner Loop
Inside Inner Loop
Inside Inner Loop
Inside Inner Loop
If we grab the PID in another terminal, and send it a SIGHUP signal we can see it reload:
$ ps auxw | grep [m]yapp
derks 1317 0.0 0.1 2425792 12988 s001 S+ 10:03PM 0:00.11 python myapp.py
In the original terminal (running our app) we see that the app reloads and the inner loop continues:
Caught signal 1
WARNING: Reloading myapp
Inside MyController.default()
Inside Inner Loop
Inside Inner Loop
However, the PID remains the same:
$ ps auxw | grep [m]yapp
derks 1317 0.0 0.1 2425792 13012 s001 S+ 10:03PM 0:00.11 python myapp.py
If you’d like to see even more detail on what Cement is doing during the
reload try adding --debug
.