Index: third_party/twisted_8_1/twisted/internet/protocol.py |
diff --git a/third_party/twisted_8_1/twisted/internet/protocol.py b/third_party/twisted_8_1/twisted/internet/protocol.py |
deleted file mode 100644 |
index 7bc2925bd07c818941d7fe0e8dbf1ff58b64c8f9..0000000000000000000000000000000000000000 |
--- a/third_party/twisted_8_1/twisted/internet/protocol.py |
+++ /dev/null |
@@ -1,674 +0,0 @@ |
-# -*- test-case-name: twisted.test.test_factories -*- |
-# |
-# Copyright (c) 2001-2008 Twisted Matrix Laboratories. |
-# See LICENSE for details. |
- |
- |
-""" |
-Standard implementations of Twisted protocol-related interfaces. |
- |
-Start here if you are looking to write a new protocol implementation for |
-Twisted. The Protocol class contains some introductory material. |
- |
-Maintainer: U{Itamar Shtull-Trauring<mailto:twisted@itamarst.org>} |
-""" |
- |
-import random |
-from zope.interface import implements |
- |
-# Twisted Imports |
-from twisted.python import log, failure, components |
-from twisted.internet import interfaces, error, defer |
- |
- |
-class Factory: |
- """This is a factory which produces protocols. |
- |
- By default, buildProtocol will create a protocol of the class given in |
- self.protocol. |
- """ |
- |
- implements(interfaces.IProtocolFactory) |
- |
- # put a subclass of Protocol here: |
- protocol = None |
- |
- numPorts = 0 |
- noisy = True |
- |
- def doStart(self): |
- """Make sure startFactory is called. |
- |
- Users should not call this function themselves! |
- """ |
- if not self.numPorts: |
- if self.noisy: |
- log.msg("Starting factory %r" % self) |
- self.startFactory() |
- self.numPorts = self.numPorts + 1 |
- |
- def doStop(self): |
- """Make sure stopFactory is called. |
- |
- Users should not call this function themselves! |
- """ |
- if self.numPorts == 0: |
- # this shouldn't happen, but does sometimes and this is better |
- # than blowing up in assert as we did previously. |
- return |
- self.numPorts = self.numPorts - 1 |
- if not self.numPorts: |
- if self.noisy: |
- log.msg("Stopping factory %r" % self) |
- self.stopFactory() |
- |
- def startFactory(self): |
- """This will be called before I begin listening on a Port or Connector. |
- |
- It will only be called once, even if the factory is connected |
- to multiple ports. |
- |
- This can be used to perform 'unserialization' tasks that |
- are best put off until things are actually running, such |
- as connecting to a database, opening files, etcetera. |
- """ |
- |
- def stopFactory(self): |
- """This will be called before I stop listening on all Ports/Connectors. |
- |
- This can be overridden to perform 'shutdown' tasks such as disconnecting |
- database connections, closing files, etc. |
- |
- It will be called, for example, before an application shuts down, |
- if it was connected to a port. User code should not call this function |
- directly. |
- """ |
- |
- def buildProtocol(self, addr): |
- """Create an instance of a subclass of Protocol. |
- |
- The returned instance will handle input on an incoming server |
- connection, and an attribute \"factory\" pointing to the creating |
- factory. |
- |
- Override this method to alter how Protocol instances get created. |
- |
- @param addr: an object implementing L{twisted.internet.interfaces.IAddress} |
- """ |
- p = self.protocol() |
- p.factory = self |
- return p |
- |
- |
-class ClientFactory(Factory): |
- """A Protocol factory for clients. |
- |
- This can be used together with the various connectXXX methods in |
- reactors. |
- """ |
- |
- def startedConnecting(self, connector): |
- """Called when a connection has been started. |
- |
- You can call connector.stopConnecting() to stop the connection attempt. |
- |
- @param connector: a Connector object. |
- """ |
- |
- def clientConnectionFailed(self, connector, reason): |
- """Called when a connection has failed to connect. |
- |
- It may be useful to call connector.connect() - this will reconnect. |
- |
- @type reason: L{twisted.python.failure.Failure} |
- """ |
- |
- def clientConnectionLost(self, connector, reason): |
- """Called when an established connection is lost. |
- |
- It may be useful to call connector.connect() - this will reconnect. |
- |
- @type reason: L{twisted.python.failure.Failure} |
- """ |
- |
- |
-class _InstanceFactory(ClientFactory): |
- """Factory used by ClientCreator.""" |
- |
- noisy = False |
- |
- def __init__(self, reactor, instance, deferred): |
- self.reactor = reactor |
- self.instance = instance |
- self.deferred = deferred |
- |
- def __repr__(self): |
- return "<ClientCreator factory: %r>" % (self.instance, ) |
- |
- def buildProtocol(self, addr): |
- self.reactor.callLater(0, self.deferred.callback, self.instance) |
- del self.deferred |
- return self.instance |
- |
- def clientConnectionFailed(self, connector, reason): |
- self.reactor.callLater(0, self.deferred.errback, reason) |
- del self.deferred |
- |
- |
-class ClientCreator: |
- """Client connections that do not require a factory. |
- |
- The various connect* methods create a protocol instance using the given |
- protocol class and arguments, and connect it, returning a Deferred of the |
- resulting protocol instance. |
- |
- Useful for cases when we don't really need a factory. Mainly this |
- is when there is no shared state between protocol instances, and no need |
- to reconnect. |
- """ |
- |
- def __init__(self, reactor, protocolClass, *args, **kwargs): |
- self.reactor = reactor |
- self.protocolClass = protocolClass |
- self.args = args |
- self.kwargs = kwargs |
- |
- def connectTCP(self, host, port, timeout=30, bindAddress=None): |
- """Connect to remote host, return Deferred of resulting protocol instance.""" |
- d = defer.Deferred() |
- f = _InstanceFactory(self.reactor, self.protocolClass(*self.args, **self.kwargs), d) |
- self.reactor.connectTCP(host, port, f, timeout=timeout, bindAddress=bindAddress) |
- return d |
- |
- def connectUNIX(self, address, timeout = 30, checkPID=0): |
- """Connect to Unix socket, return Deferred of resulting protocol instance.""" |
- d = defer.Deferred() |
- f = _InstanceFactory(self.reactor, self.protocolClass(*self.args, **self.kwargs), d) |
- self.reactor.connectUNIX(address, f, timeout = timeout, checkPID=checkPID) |
- return d |
- |
- def connectSSL(self, host, port, contextFactory, timeout=30, bindAddress=None): |
- """Connect to SSL server, return Deferred of resulting protocol instance.""" |
- d = defer.Deferred() |
- f = _InstanceFactory(self.reactor, self.protocolClass(*self.args, **self.kwargs), d) |
- self.reactor.connectSSL(host, port, f, contextFactory, timeout=timeout, bindAddress=bindAddress) |
- return d |
- |
- |
-class ReconnectingClientFactory(ClientFactory): |
- """My clients auto-reconnect with an exponential back-off. |
- |
- Note that clients should call my resetDelay method after they have |
- connected successfully. |
- |
- @ivar maxDelay: Maximum number of seconds between connection attempts. |
- @ivar initialDelay: Delay for the first reconnection attempt. |
- @ivar factor: a multiplicitive factor by which the delay grows |
- @ivar jitter: percentage of randomness to introduce into the delay length |
- to prevent stampeding. |
- """ |
- maxDelay = 3600 |
- initialDelay = 1.0 |
- # Note: These highly sensitive factors have been precisely measured by |
- # the National Institute of Science and Technology. Take extreme care |
- # in altering them, or you may damage your Internet! |
- factor = 2.7182818284590451 # (math.e) |
- # Phi = 1.6180339887498948 # (Phi is acceptable for use as a |
- # factor if e is too large for your application.) |
- jitter = 0.11962656492 # molar Planck constant times c, Jule meter/mole |
- |
- delay = initialDelay |
- retries = 0 |
- maxRetries = None |
- _callID = None |
- connector = None |
- |
- continueTrying = 1 |
- |
- def clientConnectionFailed(self, connector, reason): |
- if self.continueTrying: |
- self.connector = connector |
- self.retry() |
- |
- def clientConnectionLost(self, connector, unused_reason): |
- if self.continueTrying: |
- self.connector = connector |
- self.retry() |
- |
- def retry(self, connector=None): |
- """Have this connector connect again, after a suitable delay. |
- """ |
- if not self.continueTrying: |
- if self.noisy: |
- log.msg("Abandoning %s on explicit request" % (connector,)) |
- return |
- |
- if connector is None: |
- if self.connector is None: |
- raise ValueError("no connector to retry") |
- else: |
- connector = self.connector |
- |
- self.retries += 1 |
- if self.maxRetries is not None and (self.retries > self.maxRetries): |
- if self.noisy: |
- log.msg("Abandoning %s after %d retries." % |
- (connector, self.retries)) |
- return |
- |
- self.delay = min(self.delay * self.factor, self.maxDelay) |
- if self.jitter: |
- self.delay = random.normalvariate(self.delay, |
- self.delay * self.jitter) |
- |
- if self.noisy: |
- log.msg("%s will retry in %d seconds" % (connector, self.delay,)) |
- from twisted.internet import reactor |
- |
- def reconnector(): |
- self._callID = None |
- connector.connect() |
- self._callID = reactor.callLater(self.delay, reconnector) |
- |
- def stopTrying(self): |
- """I put a stop to any attempt to reconnect in progress. |
- """ |
- # ??? Is this function really stopFactory? |
- if self._callID: |
- self._callID.cancel() |
- self._callID = None |
- if self.connector: |
- # Hopefully this doesn't just make clientConnectionFailed |
- # retry again. |
- try: |
- self.connector.stopConnecting() |
- except error.NotConnectingError: |
- pass |
- self.continueTrying = 0 |
- |
- def resetDelay(self): |
- """Call me after a successful connection to reset. |
- |
- I reset the delay and the retry counter. |
- """ |
- self.delay = self.initialDelay |
- self.retries = 0 |
- self._callID = None |
- self.continueTrying = 1 |
- |
- |
- def __getstate__(self): |
- """ |
- Remove all of the state which is mutated by connection attempts and |
- failures, returning just the state which describes how reconnections |
- should be attempted. This will make the unserialized instance |
- behave just as this one did when it was first instantiated. |
- """ |
- state = self.__dict__.copy() |
- for key in ['connector', 'retries', 'delay', |
- 'continueTrying', '_callID']: |
- if key in state: |
- del state[key] |
- return state |
- |
- |
- |
-class ServerFactory(Factory): |
- """Subclass this to indicate that your protocol.Factory is only usable for servers. |
- """ |
- |
- |
-class BaseProtocol: |
- """This is the abstract superclass of all protocols. |
- |
- If you are going to write a new protocol for Twisted, start here. The |
- docstrings of this class explain how you can get started. Any protocol |
- implementation, either client or server, should be a subclass of me. |
- |
- My API is quite simple. Implement dataReceived(data) to handle both |
- event-based and synchronous input; output can be sent through the |
- 'transport' attribute, which is to be an instance that implements |
- L{twisted.internet.interfaces.ITransport}. |
- |
- Some subclasses exist already to help you write common types of protocols: |
- see the L{twisted.protocols.basic} module for a few of them. |
- """ |
- |
- connected = 0 |
- transport = None |
- |
- def makeConnection(self, transport): |
- """Make a connection to a transport and a server. |
- |
- This sets the 'transport' attribute of this Protocol, and calls the |
- connectionMade() callback. |
- """ |
- self.connected = 1 |
- self.transport = transport |
- self.connectionMade() |
- |
- def connectionMade(self): |
- """Called when a connection is made. |
- |
- This may be considered the initializer of the protocol, because |
- it is called when the connection is completed. For clients, |
- this is called once the connection to the server has been |
- established; for servers, this is called after an accept() call |
- stops blocking and a socket has been received. If you need to |
- send any greeting or initial message, do it here. |
- """ |
- |
-connectionDone=failure.Failure(error.ConnectionDone()) |
-connectionDone.cleanFailure() |
- |
- |
-class Protocol(BaseProtocol): |
- |
- implements(interfaces.IProtocol) |
- |
- def dataReceived(self, data): |
- """Called whenever data is received. |
- |
- Use this method to translate to a higher-level message. Usually, some |
- callback will be made upon the receipt of each complete protocol |
- message. |
- |
- @param data: a string of indeterminate length. Please keep in mind |
- that you will probably need to buffer some data, as partial |
- (or multiple) protocol messages may be received! I recommend |
- that unit tests for protocols call through to this method with |
- differing chunk sizes, down to one byte at a time. |
- """ |
- |
- def connectionLost(self, reason=connectionDone): |
- """Called when the connection is shut down. |
- |
- Clear any circular references here, and any external references |
- to this Protocol. The connection has been closed. |
- |
- @type reason: L{twisted.python.failure.Failure} |
- """ |
- |
- |
-class ProtocolToConsumerAdapter(components.Adapter): |
- implements(interfaces.IConsumer) |
- |
- def write(self, data): |
- self.original.dataReceived(data) |
- |
- def registerProducer(self, producer, streaming): |
- pass |
- |
- def unregisterProducer(self): |
- pass |
- |
-components.registerAdapter(ProtocolToConsumerAdapter, interfaces.IProtocol, |
- interfaces.IConsumer) |
- |
-class ConsumerToProtocolAdapter(components.Adapter): |
- implements(interfaces.IProtocol) |
- |
- def dataReceived(self, data): |
- self.original.write(data) |
- |
- def connectionLost(self, reason): |
- pass |
- |
- def makeConnection(self, transport): |
- pass |
- |
- def connectionMade(self): |
- pass |
- |
-components.registerAdapter(ConsumerToProtocolAdapter, interfaces.IConsumer, |
- interfaces.IProtocol) |
- |
-class ProcessProtocol(BaseProtocol): |
- """ |
- Base process protocol implementation which does simple dispatching for |
- stdin, stdout, and stderr file descriptors. |
- """ |
- implements(interfaces.IProcessProtocol) |
- |
- def childDataReceived(self, childFD, data): |
- if childFD == 1: |
- self.outReceived(data) |
- elif childFD == 2: |
- self.errReceived(data) |
- |
- |
- def outReceived(self, data): |
- """ |
- Some data was received from stdout. |
- """ |
- |
- |
- def errReceived(self, data): |
- """ |
- Some data was received from stderr. |
- """ |
- |
- |
- def childConnectionLost(self, childFD): |
- if childFD == 0: |
- self.inConnectionLost() |
- elif childFD == 1: |
- self.outConnectionLost() |
- elif childFD == 2: |
- self.errConnectionLost() |
- |
- |
- def inConnectionLost(self): |
- """ |
- This will be called when stdin is closed. |
- """ |
- |
- |
- def outConnectionLost(self): |
- """ |
- This will be called when stdout is closed. |
- """ |
- |
- |
- def errConnectionLost(self): |
- """ |
- This will be called when stderr is closed. |
- """ |
- |
- |
- def processEnded(self, reason): |
- """ |
- This will be called when the subprocess is finished. |
- |
- @type reason: L{twisted.python.failure.Failure} |
- """ |
- |
- |
-class AbstractDatagramProtocol: |
- """ |
- Abstract protocol for datagram-oriented transports, e.g. IP, ICMP, ARP, UDP. |
- """ |
- |
- transport = None |
- numPorts = 0 |
- noisy = True |
- |
- def __getstate__(self): |
- d = self.__dict__.copy() |
- d['transport'] = None |
- return d |
- |
- def doStart(self): |
- """Make sure startProtocol is called. |
- |
- This will be called by makeConnection(), users should not call it. |
- """ |
- if not self.numPorts: |
- if self.noisy: |
- log.msg("Starting protocol %s" % self) |
- self.startProtocol() |
- self.numPorts = self.numPorts + 1 |
- |
- def doStop(self): |
- """Make sure stopProtocol is called. |
- |
- This will be called by the port, users should not call it. |
- """ |
- assert self.numPorts > 0 |
- self.numPorts = self.numPorts - 1 |
- self.transport = None |
- if not self.numPorts: |
- if self.noisy: |
- log.msg("Stopping protocol %s" % self) |
- self.stopProtocol() |
- |
- def startProtocol(self): |
- """Called when a transport is connected to this protocol. |
- |
- Will only be called once, even if multiple ports are connected. |
- """ |
- |
- def stopProtocol(self): |
- """Called when the transport is disconnected. |
- |
- Will only be called once, after all ports are disconnected. |
- """ |
- |
- def makeConnection(self, transport): |
- """Make a connection to a transport and a server. |
- |
- This sets the 'transport' attribute of this DatagramProtocol, and calls the |
- doStart() callback. |
- """ |
- assert self.transport == None |
- self.transport = transport |
- self.doStart() |
- |
- def datagramReceived(self, datagram, addr): |
- """Called when a datagram is received. |
- |
- @param datagram: the string received from the transport. |
- @param addr: tuple of source of datagram. |
- """ |
- |
- |
-class DatagramProtocol(AbstractDatagramProtocol): |
- """ |
- Protocol for datagram-oriented transport, e.g. UDP. |
- |
- @type transport: C{NoneType} or |
- L{IUDPTransport<twisted.internet.interfaces.IUDPTransport>} provider |
- @ivar transport: The transport with which this protocol is associated, |
- if it is associated with one. |
- """ |
- |
- def connectionRefused(self): |
- """Called due to error from write in connected mode. |
- |
- Note this is a result of ICMP message generated by *previous* |
- write. |
- """ |
- |
- |
-class ConnectedDatagramProtocol(DatagramProtocol): |
- """Protocol for connected datagram-oriented transport. |
- |
- No longer necessary for UDP. |
- """ |
- |
- def datagramReceived(self, datagram): |
- """Called when a datagram is received. |
- |
- @param datagram: the string received from the transport. |
- """ |
- |
- def connectionFailed(self, failure): |
- """Called if connecting failed. |
- |
- Usually this will be due to a DNS lookup failure. |
- """ |
- |
- |
- |
-class FileWrapper: |
- """A wrapper around a file-like object to make it behave as a Transport. |
- |
- This doesn't actually stream the file to the attached protocol, |
- and is thus useful mainly as a utility for debugging protocols. |
- """ |
- |
- implements(interfaces.ITransport) |
- |
- closed = 0 |
- disconnecting = 0 |
- producer = None |
- streamingProducer = 0 |
- |
- def __init__(self, file): |
- self.file = file |
- |
- def write(self, data): |
- try: |
- self.file.write(data) |
- except: |
- self.handleException() |
- # self._checkProducer() |
- |
- def _checkProducer(self): |
- # Cheating; this is called at "idle" times to allow producers to be |
- # found and dealt with |
- if self.producer: |
- self.producer.resumeProducing() |
- |
- def registerProducer(self, producer, streaming): |
- """From abstract.FileDescriptor |
- """ |
- self.producer = producer |
- self.streamingProducer = streaming |
- if not streaming: |
- producer.resumeProducing() |
- |
- def unregisterProducer(self): |
- self.producer = None |
- |
- def stopConsuming(self): |
- self.unregisterProducer() |
- self.loseConnection() |
- |
- def writeSequence(self, iovec): |
- self.write("".join(iovec)) |
- |
- def loseConnection(self): |
- self.closed = 1 |
- try: |
- self.file.close() |
- except (IOError, OSError): |
- self.handleException() |
- |
- def getPeer(self): |
- # XXX: According to ITransport, this should return an IAddress! |
- return 'file', 'file' |
- |
- def getHost(self): |
- # XXX: According to ITransport, this should return an IAddress! |
- return 'file' |
- |
- def handleException(self): |
- pass |
- |
- def resumeProducing(self): |
- # Never sends data anyways |
- pass |
- |
- def pauseProducing(self): |
- # Never sends data anyways |
- pass |
- |
- def stopProducing(self): |
- self.loseConnection() |
- |
- |
-__all__ = ["Factory", "ClientFactory", "ReconnectingClientFactory", "connectionDone", |
- "Protocol", "ProcessProtocol", "FileWrapper", "ServerFactory", |
- "AbstractDatagramProtocol", "DatagramProtocol", "ConnectedDatagramProtocol", |
- "ClientCreator"] |