Ticket #1442: endpoints-1442-methodwrapper.diff

File endpoints-1442-methodwrapper.diff, 3.0 KB (added by rwall, 10 years ago)

I noticed that at the moment, the logs are prefixed with _WrapperFactory, _WrapperProtocol. This is an experiment to wrap just the connectionMade method rather than entire protocol. With this, the logs are prefixed correctly once the connection is made. Not sure if it's a good idea though.

  • twisted/internet/endpoints.py

     
    11# -*- test-case-name: twisted.test.test_endpoints -*-
    2 
     2import new
    33from zope.interface import implements, providedBy, directlyProvides
    44
    55from twisted.internet import interfaces
    66from twisted.internet import defer, protocol
    77from twisted.internet.protocol import ClientFactory, Protocol
    88
    9 class _WrappingProtocol(Protocol):
    10     """I wrap another protocol in order to notify my user when a connection has
    11     been made.
    12     """
    13     def __init__(self, factory, wrappedProtocol):
    14         self.factory = factory
    15         self.wrappedProtocol = wrappedProtocol
    16        
    17     def connectionMade(self):
    18         """XXX: As soon as I am connected, I connect my wrappedProtocol, giving
    19         it my transport. Is it okay for a transport to be associated with more
    20         than one protocol? Transport calls dataReceived on me and I in turn call
    21         dataReceived on my wrappedProtocol. The wrappedProtocol may call
    22         transport.write or transport.loseConnection etc
    23         """
    24        
    25         self.wrappedProtocol.makeConnection(self.transport)
    26         self.factory.deferred.callback(self.wrappedProtocol)
    27        
    28     def dataReceived(self, data):
    29         return self.wrappedProtocol.dataReceived(data)
    309
    31     def connectionLost(self, reason):
    32         return self.wrappedProtocol.connectionLost(reason)
    33        
    34 class _WrappingFactory(ClientFactory):
    35     protocol = _WrappingProtocol
     10class CallbackWhenFirstCalledMethodWrapper(object):
     11    def __init__(self, wrapped, onCalled):
     12        self.wrapped = wrapped
     13        self.onCalled = onCalled
     14   
     15    def __call__(self, otherSelf, *args, **kwargs):
     16        self.onCalled.callback(otherSelf)
     17        boundMethodName = self.wrapped.__name__
     18        setattr(otherSelf, boundMethodName, self.wrapped)
     19        del self.wrapped
     20        return getattr(otherSelf, boundMethodName)(*args, **kwargs)
    3621
     22
     23class _WrappingFactory(ClientFactory):
    3724    def __init__(self, wrappedFactory):
    3825        self.wrappedFactory = wrappedFactory
    3926        self.deferred = defer.Deferred()
     
    4431        except:
    4532            self.deferred.errback()
    4633        else:
    47             return self.protocol(self, proto)
     34            wrapper = CallbackWhenFirstCalledMethodWrapper(proto.connectionMade,
     35                                                           self.deferred)
     36            proto.connectionMade = new.instancemethod(wrapper, proto,
     37                                                      proto.__class__)
     38            return proto
    4839
    4940    def clientConnectionFailed(self, connector, reason):
    5041        self.deferred.errback(reason)
     
    9889            listenArgs["contextFactory"] = self.sslContextFactory
    9990        return defer.execute(listenMethod, self.port, wf, **listenArgs)
    10091
     92
    10193class UNIXEndpoint(object):
    10294    implements(interfaces.IClientEndpoint, interfaces.IServerEndpoint)
    10395