32
32
from bzrlib.lazy_import import lazy_import
33
33
lazy_import(globals(), """
34
36
from bzrlib import (
40
from bzrlib.smart import protocol
44
from bzrlib.smart import client, protocol
41
45
from bzrlib.transport import ssh
468
472
return self._medium._get_line()
475
class _DebugCounter(object):
476
"""An object that counts the HPSS calls made to each client medium.
478
When a medium is garbage-collected, or failing that when atexit functions
479
are run, the total number of calls made on that medium are reported via
484
self.counts = weakref.WeakKeyDictionary()
485
client._SmartClient.hooks.install_named_hook(
486
'call', self.increment_call_count, 'hpss call counter')
487
atexit.register(self.flush_all)
489
def track(self, medium):
490
"""Start tracking calls made to a medium.
492
This only keeps a weakref to the medium, so shouldn't affect the
495
medium_repr = repr(medium)
496
# Add this medium to the WeakKeyDictionary
497
self.counts[medium] = [0, medium_repr]
498
# Weakref callbacks are fired in reverse order of their association
499
# with the referenced object. So we add a weakref *after* adding to
500
# the WeakKeyDict so that we can report the value from it before the
501
# entry is removed by the WeakKeyDict's own callback.
502
ref = weakref.ref(medium, self.done)
504
def increment_call_count(self, params):
505
# Increment the count in the WeakKeyDictionary
506
value = self.counts[params.medium]
510
value = self.counts[ref]
511
count, medium_repr = value
512
# In case this callback is invoked for the same ref twice (by the
513
# weakref callback and by the atexit function), set the call count back
514
# to 0 so this item won't be reported twice.
517
trace.note('HPSS calls: %d %s', count, medium_repr)
520
for ref in list(self.counts.keys()):
523
_debug_counter = None
471
526
class SmartClientMedium(SmartMedium):
472
527
"""Smart client is a medium for sending smart protocol requests over."""
482
537
# _remote_version_is_before tracks the bzr version the remote side
483
538
# can be based on what we've seen so far.
484
539
self._remote_version_is_before = None
540
# Install debug hook function if debug flag is set.
541
if 'hpss' in debug.debug_flags:
542
global _debug_counter
543
if _debug_counter is None:
544
_debug_counter = _DebugCounter()
545
_debug_counter.track(self)
486
547
def _is_remote_before(self, version_tuple):
487
548
"""Is it possible the remote side supports RPCs for a given version?