def setMind(self, mind): """ Tell the avatar that the given mind has been attached. This gives the avatar a way to call remotely to the client that requested this avatar. It is best to call setMind() from within the avatar's __init__ method. Some old code still does this via a callLater, however. @type mind: L{twisted.spread.pb.RemoteReference} """ self.mind = mind def nullMind(x): self.debug('%r: disconnected from %r' % (self, self.mind)) self.mind = None self.mind.notifyOnDisconnect(nullMind) transport = self.mind.broker.transport tarzan = transport.getHost() jane = transport.getPeer() if tarzan and jane: self.debug( "PB client connection seen by me is from me %s to %s" % ( addressGetHost(tarzan), addressGetHost(jane))) self.log('Client attached is mind %s', mind)
def setMind(self, mind): """ Tell the avatar that the given mind has been attached. This gives the avatar a way to call remotely to the client that requested this avatar. It is best to call setMind() from within the avatar's __init__ method. Some old code still does this via a callLater, however. @type mind: L{twisted.spread.pb.RemoteReference} """ self.mind = mind def nullMind(x): self.debug('%r: disconnected from %r' % (self, self.mind)) self.mind = None self.mind.notifyOnDisconnect(nullMind) transport = self.mind.broker.transport tarzan = transport.getHost() jane = transport.getPeer() if tarzan and jane: self.debug("PB client connection seen by me is from me %s to %s" % (addressGetHost(tarzan), addressGetHost(jane))) self.log('Client attached is mind %s', mind)
class BaseMedium(fpb.Referenceable): """ I am a base interface for PB clients interfacing with PB server-side avatars. Used by admin/worker/component to talk to manager's vishnu, and by job to talk to worker's brain. @ivar remote: a remote reference to the server-side object on which perspective_(methodName) methods can be called @type remote: L{twisted.spread.pb.RemoteReference} @type bundleLoader: L{flumotion.common.bundleclient.BundleLoader} """ # subclasses will need to set this to the specific medium type # tho... implements(interfaces.IMedium) logCategory = "basemedium" remoteLogName = "baseavatar" remote = None bundleLoader = None def setRemoteReference(self, remoteReference): """ Set the given remoteReference as the reference to the server-side avatar. @param remoteReference: L{twisted.spread.pb.RemoteReference} """ self.debug('%r.setRemoteReference: %r' % (self, remoteReference)) self.remote = remoteReference def nullRemote(x): self.debug('%r: disconnected from %r' % (self, self.remote)) self.remote = None self.remote.notifyOnDisconnect(nullRemote) self.bundleLoader = bundleclient.BundleLoader(self.callRemote) # figure out connection addresses if it's an internet address tarzan = None jane = None try: transport = remoteReference.broker.transport tarzan = transport.getHost() jane = transport.getPeer() except Exception, e: self.debug("could not get connection info, reason %r" % e) if tarzan and jane: self.debug("connection is from me on %s to remote on %s" % (netutils.addressGetHost(tarzan), netutils.addressGetHost(jane)))
def requestAvatar(self, avatarId, keycard, mind, *ifaces): def got_avatar(avatar): if avatar.avatarId in heaven.avatars: raise errors.AlreadyConnectedError(avatar.avatarId) heaven.avatars[avatar.avatarId] = avatar self._avatarKeycards[avatar.avatarId] = keycard # OK so this is byzantine, but test_manager_manager actually # uses these kwargs to set its own info. so don't change # these args or their order or you will break your test # suite. def cleanup(avatarId=avatar.avatarId, avatar=avatar, mind=mind): self.info('lost connection to client %r', avatar) del heaven.avatars[avatar.avatarId] avatar.onShutdown() # avoid leaking the keycard keycard = self._avatarKeycards.pop(avatarId) if self._bouncer: try: self._bouncer.removeKeycard(keycard) except KeyError: self.warning("bouncer forgot about keycard %r", keycard) return (pb.IPerspective, avatar, cleanup) def got_error(failure): # If we failed for some reason, we want to drop the connection. # However, we want the failure to get to the client, so we don't # call loseConnection() immediately - we return the failure first. # loseConnection() will then not drop the connection until it has # finished sending the current data to the client. reactor.callLater(0, mind.broker.transport.loseConnection) return failure if pb.IPerspective not in ifaces: raise errors.NoPerspectiveError(avatarId) if len(ifaces) != 2: # IPerspective and the specific avatar interface. raise errors.NoPerspectiveError(avatarId) iface = [x for x in ifaces if x != pb.IPerspective][0] if iface not in self._interfaceHeavens: self.warning('unknown interface %r', iface) raise errors.NoPerspectiveError(avatarId) heaven = self._interfaceHeavens[iface] klass = heaven.avatarClass host = addressGetHost(mind.broker.transport.getPeer()) d = self._computeIdentity(keycard, host) d.addCallback(lambda identity: \ klass.makeAvatar(heaven, avatarId, identity, mind)) d.addCallbacks(got_avatar, got_error) return d
def testGetHost(self): self.failUnlessEqual(addressGetHost(self.address), 'localhost')