Application Cleanup¶
The concept of ‘cleanup’ after application run time is nothing new. What happens during ‘cleanup’ all depends on the application. This might mean closing and deleting temporary files, removing session data, or deleting a PID (Process ID) file.
To allow for application cleanup not only within your program, but also
external plugins and extensions, there is the app.close()
function that
must be called after app.run()
regardless of any exceptions or runtime
errors.
For example:
from cement.core.foundation import CementApp
app = CementApp('helloworld')
app.setup()
app.run()
app.close()
Calling app.close()
ensures that the pre_close
and post_close
framework hooks are run, allowing extensions/plugins/etc to cleanup after the
program runs.
Note that when using the Python with
operator, the setup()
and
close()
methods are automatically called. For example, the following is
exactly the same as the above example:
from cement.core.foundation import CementApp
with CementApp('helloworld') as app:
app.run()
Exit Status and Error Codes¶
You can optionally set the status code that your application exists with via
the meta options cement.foundation.CementApp.Meta.exit_on_close
.
app = CementApp('helloworld', exit_on_close=True)
app.setup()
app.run()
app.close(27)
Or Alternatively:
class MyApp(CementApp):
class Meta:
label = 'helloworld'
exit_on_close = True
with MyApp() as app:
app.run()
app.exit_code = 123
Note the use of the exit_on_close
meta option. Cement will not call
sys.exit()
unless CementApp.Meta.exit_on_close == True
. You will find
that calling sys.exit()
in testing is very problematic, therefore you will
likely want to enable exit_on_close
in production, but not for testing as
in this example:
class MyApp(CementApp):
class Meta:
label = 'helloworld'
exit_on_close = True
class MyAppForTesting(MyApp):
class Meta:
exit_on_close = False
# ...
Also note that the default exit code is 0
, however any uncaught
exceptions will cause the application to exit with a code of 1
(error).
Running Cleanup Code¶
Any extension, or plugin, or even the application itself that has ‘cleanup’
code should do so within the pre_close
or post_close
hooks to ensure
that it gets run. For example:
from cement.core import hook
def my_cleanup(app):
# do something when app.close() is called
pass
hook.register('pre_close', my_cleanup)