##// END OF EJS Templates
wireproto: support disabling bundle1 only if repo is generaldelta...
wireproto: support disabling bundle1 only if repo is generaldelta I recently implemented the server.bundle1* options to control whether bundle1 exchange is allowed. After thinking about Mozilla's strategy for handling generaldelta rollout a bit more, I think server operators need an additional lever: disable bundle1 if and only if the repo is generaldelta. bundle1 exchange for non-generaldelta repos will not have the potential for CPU explosion that generaldelta repos do. Therefore, it makes sense for server operators to continue to allow bundle1 exchange for non-generaldelta repos without having to set a per-repo hgrc option to change the policy depending on whether the repo is generaldelta. This patch introduces a new set of options to control bundle1 behavior for generaldelta repos. These options enable server operators to limit bundle1 restrictions to the class of repos that can be performance issues. It also allows server operators to tie bundle1 access to store format. In many server environments (including Mozilla's), legacy repos will not be generaldelta and new repos will or might be. New repos often aren't bound by legacy access requirements, so setting a global policy that disallows access to new/generaldelta repos via bundle1 could be a reasonable policy in many server environments. This patch makes this policy very easy to implement (modify global hgrc, add options to existing generaldelta repos to grandfather them in).

File last commit:

r27618:5a988b3c default
r27633:37d7cf56 default
Show More
lsprofcalltree.py
86 lines | 2.7 KiB | text/x-python | PythonLexer
"""
lsprofcalltree.py - lsprof output which is readable by kcachegrind
Authors:
* David Allouche <david <at> allouche.net>
* Jp Calderone & Itamar Shtull-Trauring
* Johan Dahlin
This software may be used and distributed according to the terms
of the GNU General Public License, incorporated herein by reference.
"""
from __future__ import absolute_import, print_function
def label(code):
if isinstance(code, str):
return '~' + code # built-in functions ('~' sorts at the end)
else:
return '%s %s:%d' % (code.co_name,
code.co_filename,
code.co_firstlineno)
class KCacheGrind(object):
def __init__(self, profiler):
self.data = profiler.getstats()
self.out_file = None
def output(self, out_file):
self.out_file = out_file
print('events: Ticks', file=out_file)
self._print_summary()
for entry in self.data:
self._entry(entry)
def _print_summary(self):
max_cost = 0
for entry in self.data:
totaltime = int(entry.totaltime * 1000)
max_cost = max(max_cost, totaltime)
print('summary: %d' % max_cost, file=self.out_file)
def _entry(self, entry):
out_file = self.out_file
code = entry.code
if isinstance(code, str):
print('fi=~', file=out_file)
else:
print('fi=%s' % code.co_filename, file=out_file)
print('fn=%s' % label(code), file=out_file)
inlinetime = int(entry.inlinetime * 1000)
if isinstance(code, str):
print('0 ', inlinetime, file=out_file)
else:
print('%d %d' % (code.co_firstlineno, inlinetime), file=out_file)
# recursive calls are counted in entry.calls
if entry.calls:
calls = entry.calls
else:
calls = []
if isinstance(code, str):
lineno = 0
else:
lineno = code.co_firstlineno
for subentry in calls:
self._subentry(lineno, subentry)
print(file=out_file)
def _subentry(self, lineno, subentry):
out_file = self.out_file
code = subentry.code
print('cfn=%s' % label(code), file=out_file)
if isinstance(code, str):
print('cfi=~', file=out_file)
print('calls=%d 0' % subentry.callcount, file=out_file)
else:
print('cfi=%s' % code.co_filename, file=out_file)
print('calls=%d %d' % (
subentry.callcount, code.co_firstlineno), file=out_file)
totaltime = int(subentry.totaltime * 1000)
print('%d %d' % (lineno, totaltime), file=out_file)