def __ResolveImpl(self, justQuery, sess=None): if '__semaphoreR__' not in self.__dict__: self.__semaphoreR__ = uthread.Semaphore( ('moniker::Resolve', self.__serviceName, self.__bindParams)) self.__semaphoreR__.acquire() try: if self.__nodeID is not None: return self.__nodeID if macho.mode == 'client' or base.IsInClientContext(): self.__nodeID = sm.services['machoNet'].GuessNodeIDFromAddress( self.__serviceName, self.__bindParams) if self.__nodeID is not None: return self.__nodeID if not self.__nodeID: self.__nodeID = sm.services['machoNet']._addressCache.Get( self.__serviceName, self.__bindParams) if self.__nodeID is not None: return self.__nodeID if sess is None: if session and session.role == ROLE_SERVICE: sess = session.GetActualSession() else: sess = base.GetServiceSession('util.Moniker') else: sess = sess.GetActualSession() if justQuery == 2: service = sm.services.get(self.__serviceName, None) if service is None: return elif macho.mode == 'client' or base.IsInClientContext(): service = sess.ConnectToRemoteService(self.__serviceName) else: service = sess.ConnectToAnyService(self.__serviceName) self.__nodeID = service.MachoResolveObject(self.__bindParams, justQuery) if self.__nodeID is None and not justQuery: raise RuntimeError( 'Resolution failure: ResolveObject returned None') if macho.mode == 'client' or base.IsInClientContext(): sm.services['machoNet'].SetNodeOfAddress( self.__serviceName, self.__bindParams, self.__nodeID) return self.__nodeID finally: self.__semaphoreR__.release()
def Bind(self, sess = None, call = None): """ Binds the moniker, performing the first call as well if the params are specified, using the given session. If no session is specified, a service session is used. """ localKeywords = ('machoTimeout', 'noCallThrottling') done = {} while 1: try: if self.__bindParams is None: raise RuntimeError("Thou shall not use None as a Moniker's __bindParams") if '__semaphoreB__' not in self.__dict__: self.__semaphoreB__ = uthread.Semaphore(('moniker::Bind', self.__serviceName, self.__bindParams)) self.__semaphoreB__.acquire() try: if not self.boundObject: if self.__nodeID is None: self.__ResolveImpl(0, sess) if sess is None: if session and base.IsInClientContext(): sess = session elif session and session.role == ROLE_SERVICE: sess = session.GetActualSession() else: sess = base.GetServiceSession('util.Moniker') else: sess = sess.GetActualSession() if self.__nodeID == sm.GetService('machoNet').GetNodeID(): service = sess.ConnectToService(self.__serviceName) self.boundObject = service.MachoGetObjectBoundToSession(self.__bindParams, sess) else: remotesvc = sess.ConnectToRemoteService(self.__serviceName, self.__nodeID) self.__PerformSessionCheck() if call is not None and call[2]: c2 = {k:v for k, v in call[2].iteritems() if k not in localKeywords} call = (call[0], call[1], c2) self.boundObject, retval = remotesvc.MachoBindObject(self.__bindParams, call) self.boundObject.persistantObjectID = (self.__serviceName, self.__bindParams) return retval finally: done[self.__serviceName, self.__bindParams] = 1 self.__semaphoreB__.release() if call is not None: return self.MonikeredCall(call, sess) return except UpdateMoniker as e: if (e.serviceName, e.bindParams) in done: log.LogException() raise RuntimeError('UpdateMoniker referred us to the same location twice', (e.serviceName, e.bindParams)) else: self.__bindParams = e.bindParams self.__serviceName = e.serviceName self.__nodeID = e.nodeID self.Unbind() sys.exc_clear()
def Write(self, message, jitSession=1): if macho.mode == 'proxy' and jitSession: if message.source.addressType == const.ADDRESS_TYPE_CLIENT: self._JitSessionToOtherSide(message.source.clientID) elif base.IsInClientContext() and session and hasattr( session, 'clientID'): clientID = session.clientID self._JitSessionToOtherSide(clientID) message.contextKey = clientID ls = GetLocalStorage() message.applicationID = ls.get('applicationID', None) message.languageID = ls.get('languageID', None) if hasattr(self, 'userID'): message.userID = self.userID if message.source.addressType == const.ADDRESS_TYPE_ANY and not message.command % 2: message.source.nodeID = self.machoNet.nodeID message.source.addressType = const.ADDRESS_TYPE_NODE message.Changed() elif message.source.addressType == const.ADDRESS_TYPE_NODE and message.source.nodeID is None: message.source.nodeID = self.machoNet.nodeID message.Changed() thePickle = message.GetPickle() if message.command != const.cluster.MACHONETMSG_TYPE_MOVEMENTNOTIFICATION or MACHONET_LOGMOVEMENT: self.LogInfo('Write: ', message) if self.transportName != 'tcp:packet:machoNet' and message.compressedPart * 100 / len( thePickle ) < self.compressionPercentageThreshold and len( thePickle ) - message.compressedPart > self.compressionThreshold and not MACHONET_COMPRESSION_DISABLED: before = len(thePickle) try: with bluepy.Timer('machoNet::MachoTransport::Write::Compress'): compressed = zlib.compress(thePickle, 1) except zlib.error as e: raise RuntimeError('Compression Failure: ' + strx(e)) after = len(compressed) if after > before: self.LogInfo('Compress would have exploded data from ', before, ' to ', after, ' bytes. Sending uncompressed.') elif (before - after) * 100 / before <= 5: self.LogInfo( "Compress didn't help one bit. Would have compressed data from ", before, ' to ', after, " bytes, which is insignificant. Sending uncompressed, rather than wasting the recipient's CPU power for nothing." ) else: thePickle = compressed self.machoNet.compressedBytes.Add(before - after) if self.transportName == 'tcp:packet:client' and macho.mode == 'proxy': for objectID, refID in message.oob.get('OID+', {}).iteritems(): s = self.sessions.get(self.clientID, None) if s is not None: s.RegisterMachoObject(objectID, None, refID) if self.largePacketLogSpamThreshold != None and len( thePickle) > self.largePacketLogSpamThreshold: log.LogTraceback( extraText= 'Packet larger than the %d byte largePacketLogSpamTreshhold being written out to wire (%d > %d)' % (self.largePacketLogSpamThreshold, len(thePickle), self.largePacketLogSpamThreshold)) if len(thePickle) > self.dropPacketThreshold: if self.transportName == 'tcp:packet:client' or macho.mode == 'server' and ( message.destination.addressType == const.ADDRESS_TYPE_CLIENT or message.destination.addressType == const.ADDRESS_TYPE_BROADCAST and message.destination.idtype not in ('nodeID', '+nodeID')): self.machoNet.LogError( 'Attempted to send a deadly (len=', len(thePickle), ') packet to client(s), PACKET DROPPED') self.machoNet.LogError('Packet =', repr(message)[:1024]) self.machoNet.LogError('Pickle starts with =', repr(thePickle)[:1024]) return self.transport.Write(thePickle) self.machoNet.dataSent.Add(len(thePickle))