Files @ b61824e61e68
Branch filter:

Location: kallithea/rhodecode/lib/profiler.py

Marcin Kuzminski
Don't cache dulwich Repos, in pararell multithreaded evniroment dulwich pack file openers
can break badly. We need to create Repo() objects always for each call, even when it's
taken from cache.
Fixed issue with dulwich filedescriptor leak ref #573
from __future__ import with_statement

import gc
import objgraph
import cProfile
import pstats
import cgi
import pprint
import threading

from StringIO import StringIO


class ProfilingMiddleware(object):
    def __init__(self, app):
        self.lock = threading.Lock()
        self.app = app

    def __call__(self, environ, start_response):
        with self.lock:
            profiler = cProfile.Profile()

            def run_app(*a, **kw):
                self.response = self.app(environ, start_response)

            profiler.runcall(run_app, environ, start_response)

            profiler.snapshot_stats()

            stats = pstats.Stats(profiler)
            stats.sort_stats('calls') #cummulative

            # Redirect output
            out = StringIO()
            stats.stream = out

            stats.print_stats()

            resp = ''.join(self.response)

            # Lets at least only put this on html-like responses.
            if resp.strip().startswith('<'):
                ## The profiling info is just appended to the response.
                ##  Browsers don't mind this.
                resp += ('<pre style="text-align:left; '
                         'border-top: 4px dashed red; padding: 1em;">')
                resp += cgi.escape(out.getvalue(), True)

                ct = objgraph.show_most_common_types()
                print ct

                resp += ct if ct else '---'

                output = StringIO()
                pprint.pprint(environ, output, depth=3)

                resp += cgi.escape(output.getvalue(), True)
                resp += '</pre>'

            return resp