Context objects now use a contextmanager (and update gmg shell to use it)

This means that we have a really convenient way to make sure that you
have a context/request that threads its way through the application,
where everything needed gets "shut down" appropriately by the end.

You always get a context object via a context manager!  And by the time
you're done with it, things should be cleaned up.
This commit is contained in:
Christopher Allan Webber 2014-11-30 16:14:05 -06:00
parent 9d82dff6fb
commit a4768df0ca
2 changed files with 24 additions and 17 deletions

View File

@ -16,6 +16,7 @@
import os import os
import logging import logging
from contextlib import contextmanager
from mediagoblin.routing import get_url_map from mediagoblin.routing import get_url_map
from mediagoblin.tools.routing import endpoint_to_controller from mediagoblin.tools.routing import endpoint_to_controller
@ -172,6 +173,7 @@ class MediaGoblinApp(object):
self.meddleware = [common.import_component(m)(self) self.meddleware = [common.import_component(m)(self)
for m in meddleware.ENABLED_MEDDLEWARE] for m in meddleware.ENABLED_MEDDLEWARE]
@contextmanager
def gen_context(self, ctx=None): def gen_context(self, ctx=None):
""" """
Attach contextual information to request, or generate a context object Attach contextual information to request, or generate a context object
@ -180,6 +182,13 @@ class MediaGoblinApp(object):
information (current translation, etc) are attached to this information (current translation, etc) are attached to this
object. object.
""" """
if DISABLE_GLOBALS:
with self.db_manager.session_scope() as db:
yield self._gen_context(db, ctx)
else:
yield self._gen_context(self.db, ctx)
def _gen_context(self, db, ctx):
# Set up context # Set up context
# -------------- # --------------
@ -194,8 +203,7 @@ class MediaGoblinApp(object):
# Also attach a few utilities from request.app for convenience? # Also attach a few utilities from request.app for convenience?
ctx.app = self ctx.app = self
if not DISABLE_GLOBALS: ctx.db = db
ctx.db = self.db
ctx.staticdirect = self.staticdirector ctx.staticdirect = self.staticdirector
@ -264,8 +272,10 @@ class MediaGoblinApp(object):
environ.pop('HTTPS') environ.pop('HTTPS')
## Attach utilities to the request object ## Attach utilities to the request object
request = self.gen_context(request) with self.gen_context(request) as request:
return self._finish_call_backend(request, environ, start_response)
def _finish_call_backend(self, request, environ, start_response):
# Log user out if authentication_disabled # Log user out if authentication_disabled
no_auth_logout(request) no_auth_logout(request)
@ -305,10 +315,6 @@ class MediaGoblinApp(object):
# get the Http response from the controller # get the Http response from the controller
try: try:
if DISABLE_GLOBALS:
with self.db_manager.session_scope() as request.db:
response = controller(request)
else:
response = controller(request) response = controller(request)
except HTTPException as e: except HTTPException as e:
response = render_http_exception( response = render_http_exception(

View File

@ -35,7 +35,8 @@ if DISABLE_GLOBALS:
"----------------------\n" "----------------------\n"
"Available vars:\n" "Available vars:\n"
" - app: instantiated mediagoblin application\n" " - app: instantiated mediagoblin application\n"
" - db: database session\n") " - db: database session\n"
" - ctx: context object\n")
else: else:
SHELL_BANNER = ( SHELL_BANNER = (
"GNU MediaGoblin shell!\n" "GNU MediaGoblin shell!\n"
@ -43,7 +44,8 @@ else:
"Available vars:\n" "Available vars:\n"
" - app: instantiated mediagoblin application\n" " - app: instantiated mediagoblin application\n"
" - mg_globals: mediagoblin.globals\n" " - mg_globals: mediagoblin.globals\n"
" - db: database instance\n") " - db: database instance\n"
" - ctx: context object\n")
def py_shell(**user_namespace): def py_shell(**user_namespace):
""" """
@ -75,11 +77,12 @@ def shell(args):
""" """
app = commands_util.setup_app(args) app = commands_util.setup_app(args)
def run_shell(db): def run_shell(db, ctx):
user_namespace = { user_namespace = {
'mg_globals': mg_globals, 'mg_globals': mg_globals,
'app': app, 'app': app,
'db': db} 'db': db,
"ctx": ctx}
if args.ipython: if args.ipython:
ipython_shell(**user_namespace) ipython_shell(**user_namespace)
@ -88,8 +91,6 @@ def shell(args):
if not ipython_shell(**user_namespace): if not ipython_shell(**user_namespace):
py_shell(**user_namespace) py_shell(**user_namespace)
if DISABLE_GLOBALS: with app.gen_context() as ctx:
with app.db_manager.session_scope() as db: db = ctx.db
run_shell(db) run_shell(db, ctx)
else:
run_shell(mg_globals.database)