Skip to content

Commit

Permalink
Merge pull request #249 from Pylons/fix/avoid-touching-session
Browse files Browse the repository at this point in the history
avoid touching the session except when the user already touched it
  • Loading branch information
mmerickel committed Apr 21, 2016
2 parents 7ff9f53 + e5a9678 commit 2c7996c
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 32 deletions.
6 changes: 6 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ unreleased
3. Mako reformatted into "defs" for simpler reorganization in the future
See https://github.com/Pylons/pyramid_debugtoolbar/pull/241

- Fix to prevent the toolbar from loading the session until it is actually
accessed by the user. This avoids unnecessary parsing of the session object
as well as waiting to parse it until later in the request which may meet
more expectations of the session factory.
See https://github.com/Pylons/pyramid_debugtoolbar/pull/249

2.4.2 (2015-10-28)
------------------

Expand Down
88 changes: 56 additions & 32 deletions pyramid_debugtoolbar/panels/request_vars.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,30 @@
# extractable_request_attributes allow us to programmatically pull data
# the format is ( attr_, is_dict)
extractable_request_attributes = (
('accept_charset', None),
('accept_encoding', None),
('accept_language', None),
('application_url', None),
('authenticated_userid', None),
('authorization', None),
('cache_control', None),
('context', None),
('effective_principals', None),
('exc_info', None),
('exception', None),
('locale_name', None),
('matchdict', None),
('accept_charset', False),
('accept_encoding', False),
('accept_language', False),
('application_url', False),
('authenticated_userid', False),
('authorization', False),
('cache_control', False),
('context', False),
('effective_principals', False),
('exc_info', False),
('exception', False),
('locale_name', False),
('matchdict', False),
('matched_route', True),
('path', None),
# ('registry', None), # see "Note1"
('root', None),
('subpath', None),
('traversed', None),
('unauthenticated_userid', None),
('url', None),
('view_name', None),
('virtual_root_path', None),
('virtual_root', None),
('path', False),
# ('registry', False), # see "Note1"
('root', False),
('subpath', False),
('traversed', False),
('unauthenticated_userid', False),
('url', False),
('view_name', False),
('virtual_root_path', False),
('virtual_root', False),
)
# Note1: accessed as a 'string', `registry` be the python package name;
# accessed as a dict, will be the contents of the registry
Expand Down Expand Up @@ -78,27 +78,51 @@ class RequestVarsDebugPanel(DebugPanel):
def __init__(self, request):
self.request = request
self.data = data = {}
attr_dict = request.__dict__.copy()
attrs = request.__dict__.copy()
# environ is displayed separately
del attr_dict['environ']
if 'response' in attr_dict:
attr_dict['response'] = repr(attr_dict['response'])
del attrs['environ']

if 'response' in attrs:
attrs['response'] = repr(attrs['response'])

if 'session' in attrs:
self.process_session_attr(self, attrs['session'])
del attrs['session']
else:
# only process the session if it's accessed
callback_on_load(request, 'session', self.process_session_attr)

data.update({
'get': [(k, request.GET.getall(k)) for k in request.GET],
'post': [(k, saferepr(v)) for k, v in request.POST.items()],
'cookies': [(k, request.cookies.get(k)) for k in request.cookies],
'attrs': dictrepr(attr_dict),
'environ': dictrepr(request.environ),
'extracted_attributes': {},
'attrs': dictrepr(attrs),
'session': None,
})

def process_session_attr(self, session):
self.data.update({
'session': dictrepr(session),
})
if hasattr(request, 'session'):
data.update({
'session': dictrepr(request.session),
})
return session

def process_response(self, response):
extracted_attributes = extract_request_attributes(self.request)
self.data['extracted_attributes'] = extracted_attributes

# stop hanging onto the request after the response is processed
del self.request

def callback_on_load(obj, name, cb):
""" Callback when a property is accessed.
This currently only works for reified properties that are called once.
"""
orig_property = getattr(obj.__class__, name)
def wrapper(self):
val = orig_property.__get__(obj)
return cb(val)
obj.set_property(wrapper, name=name, reify=True)
2 changes: 2 additions & 0 deletions pyramid_debugtoolbar/panels/templates/request_vars.dbtmako
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,8 @@
% endfor
</tbody>
</table>
% elif session is None:
<p>Session was not accessed</p>
% else:
<p>No session data</p>
% endif
Expand Down

0 comments on commit 2c7996c

Please sign in to comment.