Ejemplo n.º 1
0
 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()
Ejemplo n.º 2
0
    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()
Ejemplo n.º 3
0
    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))