~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/smart/medium.py

  • Committer: Andrew Bennetts
  • Date: 2008-09-24 13:46:44 UTC
  • mto: This revision was merged to the branch mainline in revision 3755.
  • Revision ID: andrew.bennetts@canonical.com-20080924134644-wu29mrcljknmpdpz
Show total HPSS calls (if any) on stderr when -Dhpss is active.

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
import socket
29
29
import sys
30
30
import urllib
 
31
import weakref
31
32
 
32
33
from bzrlib.lazy_import import lazy_import
33
34
lazy_import(globals(), """
34
35
from bzrlib import (
 
36
    debug,
35
37
    errors,
36
38
    osutils,
37
39
    symbol_versioning,
38
40
    urlutils,
39
41
    )
40
 
from bzrlib.smart import protocol
 
42
from bzrlib.smart import client, protocol
41
43
from bzrlib.transport import ssh
42
44
""")
43
45
 
468
470
        return self._medium._get_line()
469
471
 
470
472
 
 
473
_atexit_registered = False
 
474
 
 
475
 
 
476
class _HPSSCallCounter(object):
 
477
    """An object that counts the HPSS calls made to a particular medium.
 
478
 
 
479
    When the medium is garbage-collected, or failing that when atexit functions
 
480
    are run, the total number of calls made on that medium are reported to
 
481
    stderr.
 
482
 
 
483
    It only keeps a weakref to the medium, so shouldn't affect the medium's
 
484
    lifetime.
 
485
    """
 
486
 
 
487
    def __init__(self, medium):
 
488
        self.count = 0
 
489
        self._done = False
 
490
        self.medium_ref = weakref.ref(medium, self.done)
 
491
        self.medium_repr = repr(medium)
 
492
        # Register an atexit handler if one hasn't already been registered.
 
493
        # Usually the weakref callback is enough, but quite often if the
 
494
        # program aborts with an exception the medium doesn't get
 
495
        # garbage-collected, presumably because one of the traceback frames
 
496
        # still references it.
 
497
        global _atexit_registered, _atexit_counters
 
498
        if not _atexit_registered:
 
499
            import atexit
 
500
            _atexit_counters = []
 
501
            def finish_counters():
 
502
                for counter in _atexit_counters:
 
503
                    counter.done(None)
 
504
            atexit.register(finish_counters)
 
505
            _atexit_registered = True
 
506
        _atexit_counters.append(self)
 
507
 
 
508
    def increment(self, params):
 
509
        """Install this method as a _SmartClient.hooks['call'] hook."""
 
510
        if params.medium is self.medium_ref():
 
511
            self.count += 1
 
512
 
 
513
    def done(self, ref):
 
514
        """This method is called when the medium is done."""
 
515
        # TODO: remove hook
 
516
        if self._done:
 
517
            return
 
518
        self._done = True
 
519
        if self.count != 0:
 
520
            print >> sys.stderr, 'HPSS calls: %d (%s)' % (
 
521
                self.count, self.medium_repr)
 
522
        _atexit_counters.remove(self)
 
523
 
 
524
 
471
525
class SmartClientMedium(SmartMedium):
472
526
    """Smart client is a medium for sending smart protocol requests over."""
473
527
 
482
536
        # _remote_version_is_before tracks the bzr version the remote side
483
537
        # can be based on what we've seen so far.
484
538
        self._remote_version_is_before = None
 
539
        if 'hpss' in debug.debug_flags:
 
540
            counter = _HPSSCallCounter(self)
 
541
            client._SmartClient.hooks.install_named_hook('call',
 
542
                    counter.increment, 'hpss debug')
485
543
 
486
544
    def _is_remote_before(self, version_tuple):
487
545
        """Is it possible the remote side supports RPCs for a given version?
674
732
        self._write_to.close()
675
733
        self._ssh_connection.close()
676
734
        self._connected = False
 
735
        super(SmartSSHClientMedium, self).disconnect()
677
736
 
678
737
    def _ensure_connection(self):
679
738
        """Connect this medium if not already connected."""
731
790
        self._socket.close()
732
791
        self._socket = None
733
792
        self._connected = False
 
793
        super(SmartTCPClientMedium, self).disconnect()
734
794
 
735
795
    def _ensure_connection(self):
736
796
        """Connect this medium if not already connected."""