master/buildbot/monkey.py
author Chris AtLee <catlee@mozilla.com>
Tue, 10 Jul 2012 15:44:25 -0400
branchproduction-0.8
changeset 560 bd4812420e639f5d19cebc2c1d9f50ad7fbac409
parent 194 17c53d0c29a4160d3331348660fb20327ff28609
permissions -rw-r--r--
Bug 772467: Expire old duplicate slave connections eventually. r=dustin

from twisted.python import log
def monkeypatch_twisted_cbLogin():
    """
    Work around for http://twistedmatrix.com/trac/ticket/5079, which results in
    leaking one RemoteReference every time a slave disconnects.
    """
    import twisted
    from twisted.python.versions import Version

    # This patch is known to work in versions 8.2.0 -> 11.0.0
    # If your version is outside this range, but this monkey patch still
    # applies, please update this version check!
    # If your version of twisted doesn't need this, returning early is the
    # right thing to do.
    assert Version('twisted', 8, 2, 0) <= twisted.version <= \
            Version('twisted', 12, 0, 0), \
            "monkeypatch failed version check; see note in monkey.py"

    import twisted.spread.pb
    from twisted.spread.interfaces import IJellyable
    from twisted.spread.pb import AsReferenceable

    def monkeyed_cbLogin(self, (interface, avatar, logout)):
        """
        Ensure that the avatar to be returned to the client is jellyable and
        set up disconnection notification to call the realm's logout object.
        """
        if not IJellyable.providedBy(avatar):
            avatar = AsReferenceable(avatar, "perspective")

        puid = avatar.processUniqueID()

        # only call logout once, whether the connection is dropped (disconnect)
        # or a logout occurs (cleanup), and be careful to drop the reference to
        # it in either case 
        logout = [ logout ]
        def maybeLogout():
            if not logout: return
            fn = logout[0]
            del logout[0]
            fn()
        self.broker._localCleanup[puid] = maybeLogout
        self.broker.notifyOnDisconnect(maybeLogout)

        return avatar

    twisted.spread.pb._JellyableAvatarMixin._cbLogin = monkeyed_cbLogin
    log.msg("monkeypatch_twisted_cbLogin applied")