##// END OF EJS Templates
profiling: allow CGI and FastCGI to be profiled
Bryan O'Sullivan -
r5995:b913d3aa default
parent child Browse files
Show More
@@ -23,6 +23,7 b' cgitb.enable()'
23
23
24 from mercurial.hgweb.hgwebdir_mod import hgwebdir
24 from mercurial.hgweb.hgwebdir_mod import hgwebdir
25 from mercurial.hgweb.request import wsgiapplication
25 from mercurial.hgweb.request import wsgiapplication
26 from mercurial import dispatch, ui
26 from flup.server.fcgi import WSGIServer
27 from flup.server.fcgi import WSGIServer
27
28
28 # The config file looks like this. You can have paths to individual
29 # The config file looks like this. You can have paths to individual
@@ -44,7 +45,8 b' from flup.server.fcgi import WSGIServer'
44 # Alternatively you can pass a list of ('virtual/path', '/real/path') tuples
45 # Alternatively you can pass a list of ('virtual/path', '/real/path') tuples
45 # or use a dictionary with entries like 'virtual/path': '/real/path'
46 # or use a dictionary with entries like 'virtual/path': '/real/path'
46
47
47 def make_web_app():
48 def web_app(ui):
48 return hgwebdir("hgweb.config")
49 return lambda: hgwebdir("hgweb.config", ui)
49
50
50 WSGIServer(wsgiapplication(make_web_app)).run()
51 u = ui.ui(report_untrusted=False, interactive=False)
52 dispatch.profiled(u, lambda: WSGIServer(wsgiapplication(web_app(u))).run())
@@ -403,6 +403,17 b' paths::'
403 Optional. Directory or URL to use when pushing if no destination
403 Optional. Directory or URL to use when pushing if no destination
404 is specified.
404 is specified.
405
405
406 profile::
407 Configuration of profiling options, for in-depth performance
408 analysis. Mostly useful to developers.
409 enable;;
410 Enable a particular profiling mode. Useful for profiling
411 server-side processes. "lsprof" enables modern profiling.
412 "hotshot" is deprecated, and produces less reliable results.
413 Default is no profiling.
414 output;;
415 The name of a file to write profiling data to. Default is stderr.
416
406 server::
417 server::
407 Controls generic server settings.
418 Controls generic server settings.
408 uncompressed;;
419 uncompressed;;
@@ -22,7 +22,9 b' cgitb.enable()'
22 #os.environ["HGENCODING"] = "UTF-8"
22 #os.environ["HGENCODING"] = "UTF-8"
23
23
24 from mercurial.hgweb.hgweb_mod import hgweb
24 from mercurial.hgweb.hgweb_mod import hgweb
25 from mercurial import dispatch, ui
25 import mercurial.hgweb.wsgicgi as wsgicgi
26 import mercurial.hgweb.wsgicgi as wsgicgi
26
27
27 application = hgweb("/path/to/repo", "repository name")
28 u = ui.ui(report_untrusted=False, interactive=False)
28 wsgicgi.launch(application)
29 dispatch.profiled(u, lambda: wsgicgi.launch(hgweb("/path/to/repo",
30 "repository name", u)))
@@ -22,6 +22,7 b' cgitb.enable()'
22 #os.environ["HGENCODING"] = "UTF-8"
22 #os.environ["HGENCODING"] = "UTF-8"
23
23
24 from mercurial.hgweb.hgwebdir_mod import hgwebdir
24 from mercurial.hgweb.hgwebdir_mod import hgwebdir
25 from mercurial import dispatch, ui
25 import mercurial.hgweb.wsgicgi as wsgicgi
26 import mercurial.hgweb.wsgicgi as wsgicgi
26
27
27 # The config file looks like this. You can have paths to individual
28 # The config file looks like this. You can have paths to individual
@@ -43,5 +44,5 b' import mercurial.hgweb.wsgicgi as wsgicg'
43 # Alternatively you can pass a list of ('virtual/path', '/real/path') tuples
44 # Alternatively you can pass a list of ('virtual/path', '/real/path') tuples
44 # or use a dictionary with entries like 'virtual/path': '/real/path'
45 # or use a dictionary with entries like 'virtual/path': '/real/path'
45
46
46 application = hgwebdir('hgweb.config')
47 u = ui.ui(report_untrusted=False, interactive=False)
47 wsgicgi.launch(application)
48 dispatch.profiled(u, lambda: wsgicgi.launch(hgwebdir('hgweb.config', u)))
@@ -373,8 +373,17 b' def _runcommand(ui, options, cmd, cmdfun'
373 if len(tb) != 2: # no
373 if len(tb) != 2: # no
374 raise
374 raise
375 raise ParseError(cmd, _("invalid arguments"))
375 raise ParseError(cmd, _("invalid arguments"))
376 return profiled(ui, checkargs, options)
376
377
377 if options['profile']:
378 def profiled(ui, func, options={}):
379 def profile_fp():
380 outfile = ui.config('profile', 'output', untrusted=True)
381 if outfile:
382 return open(outfile, 'w')
383 else:
384 return sys.stderr
385
386 if options.get('profile') or ui.config('profile', 'enable') == 'hotshot':
378 import hotshot, hotshot.stats
387 import hotshot, hotshot.stats
379 prof = hotshot.Profile("hg.prof")
388 prof = hotshot.Profile("hg.prof")
380 try:
389 try:
@@ -390,10 +399,11 b' def _runcommand(ui, options, cmd, cmdfun'
390 finally:
399 finally:
391 prof.close()
400 prof.close()
392 stats = hotshot.stats.load("hg.prof")
401 stats = hotshot.stats.load("hg.prof")
402 stats.stream = profile_fp()
393 stats.strip_dirs()
403 stats.strip_dirs()
394 stats.sort_stats('time', 'calls')
404 stats.sort_stats('time', 'calls')
395 stats.print_stats(40)
405 stats.print_stats(40)
396 elif options['lsprof']:
406 elif options.get('lsprof') or ui.config('profile', 'enable') == 'lsprof':
397 try:
407 try:
398 from mercurial import lsprof
408 from mercurial import lsprof
399 except ImportError:
409 except ImportError:
@@ -403,11 +413,11 b' def _runcommand(ui, options, cmd, cmdfun'
403 p = lsprof.Profiler()
413 p = lsprof.Profiler()
404 p.enable(subcalls=True)
414 p.enable(subcalls=True)
405 try:
415 try:
406 return checkargs()
416 return func()
407 finally:
417 finally:
408 p.disable()
418 p.disable()
409 stats = lsprof.Stats(p.getstats())
419 stats = lsprof.Stats(p.getstats())
410 stats.sort()
420 stats.sort()
411 stats.pprint(top=10, file=sys.stderr, climit=5)
421 stats.pprint(top=10, file=profile_fp(), climit=5)
412 else:
422 else:
413 return checkargs()
423 return func()
@@ -79,9 +79,10 b' def revnavgen(pos, pagelen, limit, nodef'
79 return nav
79 return nav
80
80
81 class hgweb(object):
81 class hgweb(object):
82 def __init__(self, repo, name=None):
82 def __init__(self, repo, name=None, parentui=None):
83 if isinstance(repo, str):
83 if isinstance(repo, str):
84 parentui = ui.ui(report_untrusted=False, interactive=False)
84 parentui = (parentui or
85 ui.ui(report_untrusted=False, interactive=False))
85 self.repo = hg.repository(parentui, repo)
86 self.repo = hg.repository(parentui, repo)
86 else:
87 else:
87 self.repo = repo
88 self.repo = repo
General Comments 0
You need to be logged in to leave comments. Login now