~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/smart/medium.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-10-01 06:49:10 UTC
  • mfrom: (3731.2.7 hpss-call-count)
  • Revision ID: pqm@pqm.ubuntu.com-20081001064910-typ6d7diwd53z6iv
Extend -Dhpss flag to report HPSS call count on stderr. (Andrew
        Bennetts)

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
 
32
32
from bzrlib.lazy_import import lazy_import
33
33
lazy_import(globals(), """
 
34
import atexit
 
35
import weakref
34
36
from bzrlib import (
 
37
    debug,
35
38
    errors,
36
39
    osutils,
37
40
    symbol_versioning,
 
41
    trace,
38
42
    urlutils,
39
43
    )
40
 
from bzrlib.smart import protocol
 
44
from bzrlib.smart import client, protocol
41
45
from bzrlib.transport import ssh
42
46
""")
43
47
 
468
472
        return self._medium._get_line()
469
473
 
470
474
 
 
475
class _DebugCounter(object):
 
476
    """An object that counts the HPSS calls made to each client medium.
 
477
 
 
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
 
480
    trace.note.
 
481
    """
 
482
 
 
483
    def __init__(self):
 
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)
 
488
 
 
489
    def track(self, medium):
 
490
        """Start tracking calls made to a medium.
 
491
 
 
492
        This only keeps a weakref to the medium, so shouldn't affect the
 
493
        medium's lifetime.
 
494
        """
 
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)
 
503
 
 
504
    def increment_call_count(self, params):
 
505
        # Increment the count in the WeakKeyDictionary
 
506
        value = self.counts[params.medium]
 
507
        value[0] += 1
 
508
 
 
509
    def done(self, ref):
 
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.
 
515
        value[0] = 0
 
516
        if count != 0:
 
517
            trace.note('HPSS calls: %d %s', count, medium_repr)
 
518
        
 
519
    def flush_all(self):
 
520
        for ref in list(self.counts.keys()):
 
521
            self.done(ref)
 
522
 
 
523
_debug_counter = None
 
524
  
 
525
  
471
526
class SmartClientMedium(SmartMedium):
472
527
    """Smart client is a medium for sending smart protocol requests over."""
473
528
 
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)
485
546
 
486
547
    def _is_remote_before(self, version_tuple):
487
548
        """Is it possible the remote side supports RPCs for a given version?