Package foolscap :: Module pb :: Class Tub
[hide private]
[frames] | no frames]

Class Tub

source code

 twisted.application.service.Service --+    
                                       |    
twisted.application.service.MultiService --+
                                           |
                                          Tub
Known Subclasses:

I am a presence in the PB universe, also known as a Tub.

I am a Service (in the twisted.application.service.Service sense), so you either need to call my startService() method before using me, or setServiceParent() me to a running service.

This is the primary entry point for all PB-using applications, both clients and servers.

I am known to the outside world by a base URL, which may include authentication information (a yURL). This is my 'TubID'.

I contain Referenceables, and manage RemoteReferences to Referenceables that live in other Tubs.

Nested Classes [hide private]
  negotiationClass
This is the first protocol to speak over the wire.
  brokerClass
I manage a connection to a remote Broker.
Instance Methods [hide private]
 
__init__(self, certData=None, certFile=None, options={}) source code
 
__repr__(self) source code
 
setupEncryptionFile(self, certFile) source code
 
setupEncryption(self, certData) source code
 
make_incarnation(self) source code
 
getIncarnationString(self) source code
 
setup(self, options) source code
 
setOption(self, name, value) source code
 
setLogGathererFURL(self, gatherer_furl) source code
 
setLogGathererFURLFile(self, gatherer_furlfile) source code
 
_maybeConnectToGatherer(self) source code
 
_log_gatherer_connected(self, rref) source code
 
getLogPort(self) source code
 
_maybeCreateLogPort(self) source code
 
setLogPortFURLFile(self, furlfile) source code
 
_maybeCreateLogPortFURLFile(self) source code
 
getLogPortFURL(self) source code
 
log(self, *args, **kwargs) source code
 
createCertificate(self) source code
 
getCertData(self) source code
 
setLocation(self, *hints)
Tell this service what its location is: a host:port description of how to reach it from the outside world.
source code
 
setLocationAutomatically(self, *extra_addresses)
Determine one of this host's publically-visible IP addresses and use it to set our location.
source code
 
listenOn(self, what, options={})
Start listening for connections.
source code
 
stopListeningOn(self, l) source code
 
getListeners(self)
Return the set of Listener objects that allow the outside world to connect to this Tub.
source code
 
clone(self)
Return a new Tub (with a different ID), listening on the same ports as this one.
source code
 
getTubID(self) source code
 
getShortTubID(self) source code
 
connectorStarted(self, c) source code
 
connectorFinished(self, c) source code
 
startService(self) source code
 
_tubsAreNotRestartable(self, *args, **kwargs) source code
 
_tubHasBeenShutDown(self, *args, **kwargs) source code
 
stopService(self) source code
 
generateSwissnumber(self, bits) source code
 
buildURL(self, name) source code
string
registerReference(self, ref, name=None, furlFile=None)
Make a Referenceable available to the outside world.
source code
 
_assignName(self, ref, preferred_name=None)
Make a Referenceable available to the outside world, but do not retain a strong reference to it.
source code
 
getReferenceForName(self, name) source code
 
getReferenceForURL(self, url) source code
 
getOrCreateURLForReference(self, ref)
Return the global URL for the reference, if there is one, or None if there is not.
source code
 
revokeReference(self, ref) source code
 
unregisterURL(self, url) source code
 
unregisterReference(self, ref) source code
 
registerNameLookupHandler(self, lookup)
Add a function to help convert names to Referenceables.
source code
 
unregisterNameLookupHandler(self, lookup) source code
 
getReference(self, sturdyOrURL)
Acquire a RemoteReference for the given SturdyRef/URL.
source code
 
connectTo(self, _sturdyOrURL, _cb, *args, **kwargs)
Establish (and maintain) a connection to a given PBURL.
source code
 
serialize(self, obj) source code
 
unserialize(self, data) source code
 
_removeReconnector(self, rc) source code
 
getBrokerForTubRef(self, tubref) source code
 
_createLoopbackBroker(self, tubref) source code
 
connectionFailed(self, tubref, why) source code
 
brokerAttached(self, tubref, broker, isClient) source code
 
brokerDetached(self, broker, why) source code
 
debug_listBrokers(self) source code

Inherited from twisted.application.service.MultiService: __iter__, addService, getServiceNamed, privilegedStartService, removeService

Inherited from twisted.application.service.Service: __getstate__, __providedBy__, disownServiceParent, setName, setServiceParent

Class Variables [hide private]
  unsafeTracebacks = True
  logLocalFailures = False
  logRemoteFailures = False
  debugBanana = False
  NAMEBITS = 160
  TUBIDBITS = 16
  encrypted = True
  keepaliveTimeout = 240
  disconnectTimeout = None
  __implemented__ = <implementedBy foolscap.pb.Tub>
  __provides__ = <zope.interface.declarations.ClassProvides obje...

Inherited from twisted.application.service.Service: name, parent, running

Instance Variables [hide private]
string tubID = None
a global identifier for this Tub, possibly including authentication information, hash of SSL certificate
  brokers
maps TubIDs to Broker instances
  listeners
maps strport to TCPServer service
  nameToReference
maps name to Referenceable
  referenceToName
maps Referenceable to a name
Method Details [hide private]

__init__(self, certData=None, certFile=None, options={})
(Constructor)

source code 
Parameters:
  • certData - if provided, use it as a certificate rather than generating a new one. This is a PEM-encoded private/public keypair, as returned by Tub.getCertData()
  • certFile - if provided, the Tub will store its certificate in this file. If the file does not exist when the Tub is created, the Tub will generate a new certificate and store it here. If the file does exist, the certificate will be loaded from this file.

    The simplest way to use the Tub is to choose a long-term location for the certificate, use certFile= to tell the Tub about it, and then let the Tub manage its own certificate.

    You may provide certData, or certFile, (or neither), but not both.

  • options - a dictionary of options that can influence connection connection negotiation. Currently defined keys are:
    • debug_slow: if True, wait half a second between each negotiation response
Overrides: twisted.application.service.MultiService.__init__

setLocation(self, *hints)

source code 

Tell this service what its location is: a host:port description of how to reach it from the outside world. You need to use this because the Tub can't do it without help. If you do a s.listenOn('tcp:1234'), and the host is known as foo.example.com, then it would be appropriate to do:

   s.setLocation('foo.example.com:1234')

You must set the location before you can register any references.

Encrypted Tubs can have multiple location hints, just provide multiple arguments. Unauthenticated Tubs can only have one location.

setLocationAutomatically(self, *extra_addresses)

source code 

Determine one of this host's publically-visible IP addresses and use it to set our location. This uses whatever source address would be used to get to a well-known public host (A.ROOT-SERVERS.NET), which is effectively the interface on which a default route lives. This is neither very pretty (IP address instead of hostname) nor guaranteed to work (it may very well be a 192.168 'private' address), but for publically-visible hosts this will probably produce a useable FURL.

This method returns a Deferred that will fire once the location is actually established. Calls to registerReference() must be put off until the location has been set. And of course, you must call listenOn() before calling autoSetLocation().

listenOn(self, what, options={})

source code 

Start listening for connections.

Parameters:
  • what (string or Listener instance) - a twisted.application.strports -style description, or a Listener instance returned by a previous call to listenOn.
  • options - a dictionary of options that can influence connection negotiation before the target Tub has been determined
Returns:
The Listener object that was created. This can be used to stop listening later on, to have another Tub listen on the same port, and to figure out which port was allocated when you used a strports specification of 'tcp:0'.

startService(self)

source code 
Overrides: twisted.application.service.Service.startService

stopService(self)

source code 
Overrides: twisted.application.service.Service.stopService

registerReference(self, ref, name=None, furlFile=None)

source code 

Make a Referenceable available to the outside world. A URL is returned which can be used to access this object. This registration will remain in effect (and the Tub will retain a reference to the object to keep it meaningful) until explicitly unregistered, or the Tub is shut down.

Parameters:
  • name (string (optional)) - if provided, the object will be registered with this name. If not, a random (unguessable) string will be used.
  • furlFile - if provided, get the name from this file (if it exists), and write the new FURL to this file. If 'name=' is also provided, it is used for the name, but the FURL is still written to this file.
Returns: string
the URL which points to this object. This URL can be passed to Tub.getReference() in any Tub on any host which can reach this one.

_assignName(self, ref, preferred_name=None)

source code 

Make a Referenceable available to the outside world, but do not retain a strong reference to it. If we must create a new name, use preferred_name. If that is None, use a random unguessable name.

registerNameLookupHandler(self, lookup)

source code 

Add a function to help convert names to Referenceables.

When remote systems pass a FURL to their Tub.getReference(), our Tub will be asked to locate a Referenceable for the name inside that furl. The normal mechanism for this is to look at the table maintained by registerReference() and unregisterReference(). If the name does not exist in that table, other 'lookup handler' functions are given a chance. Each lookup handler is asked in turn, and the first which returns a non-None value wins.

This may be useful for cases where the furl represents an object that lives on disk, or is generated on demand: rather than creating all possible Referenceables at startup, the lookup handler can create or retrieve the objects only when someone asks for them.

Note that constructing the FURLs of these objects may be non-trivial. It is safe to create an object, use tub.registerReference in one invocation of a program to obtain (and publish) the furl, parse the furl to extract the name, save the contents of the object on disk, then in a later invocation of the program use a lookup handler to retrieve the object from disk. This approach means the objects that are created in a given invocation stick around (inside tub.strongReferences) for the rest of that invocation. An alternatve approach is to create the object but *not* use tub.registerReference, but in that case you have to construct the FURL yourself, and the Tub does not currently provide any support for doing this robustly.

Parameters:
  • lookup - a callable which accepts a name (as a string) and returns either a Referenceable or None. Note that these strings should not contain a slash, a question mark, or an ampersand, as these are reserved in the FURL for later expansion (to add parameters beyond the object name)

getReference(self, sturdyOrURL)

source code 

Acquire a RemoteReference for the given SturdyRef/URL.

The Tub must be running (i.e. Tub.startService()) when this is invoked. Future releases may relax this requirement.

Returns:
a Deferred that fires with the RemoteReference

connectTo(self, _sturdyOrURL, _cb, *args, **kwargs)

source code 

Establish (and maintain) a connection to a given PBURL.

I establish a connection to the PBURL and run a callback to inform the caller about the newly-available RemoteReference. If the connection is lost, I schedule a reconnection attempt for the near future. If that one fails, I keep trying at longer and longer intervals (exponential backoff).

I accept a callback which will be fired each time a connection attempt succeeds. This callback is run with the new RemoteReference and any additional args/kwargs provided to me. The callback should then use rref.notifyOnDisconnect() to get a message when the connection goes away. At some point after it goes away, the Reconnector will reconnect.

The Tub must be running (i.e. Tub.startService()) when this is invoked. Future releases may relax this requirement.

I return a Reconnector object. When you no longer want to maintain this connection, call the stopConnecting() method on the Reconnector. I promise to not invoke your callback after you've called stopConnecting(), even if there was already a connection attempt in progress. If you had an active connection before calling stopConnecting(), you will still have access to it, until it breaks on its own. (I will not attempt to break existing connections, I will merely stop trying to create new ones). All my Reconnector objects will be shut down when the Tub is stopped.

Usage:

def _got_ref(rref, arg1, arg2):
    rref.callRemote('hello again')
    # etc
rc = tub.connectTo(_got_ref, 'arg1', 'arg2')
...
rc.stopConnecting() # later

Class Variable Details [hide private]

__provides__

Value:
<zope.interface.declarations.ClassProvides object at 0x873572c>