Ejemplo n.º 1
0
    def RemoteServiceCallWithoutTheStars(self, sess, nodeID, service, method, args, keywords):
        while 1:
            try:
                if sess is None:
                    self.machoNet.LogError('Session is None during RemoteServiceCall')
                    log.LogTraceback()
                sessionVars1 = self._GetRemoteServiceCallVariables(sess)
                mask = sess.Masquerade()
                try:
                    cachable, versionCheck, throwOK, cachedResultRecord, cacheKey, cacheDetails = sm.GetService('objectCaching').PerformCachedMethodCall(None, service, method, args)
                    if cachable:
                        if not versionCheck:
                            if throwOK:
                                self.LogMethodCall(objectCaching.CacheOK(), service, method + '[Cached]', args, keywords)
                                raise objectCaching.CacheOK()
                            elif cachedResultRecord:
                                self.LogMethodCall(cachedResultRecord['lret'], service, method + '[Cached]', args, keywords)
                                return cachedResultRecord['lret']
                    if nodeID is None and macho.mode == 'client':
                        nodeID = self.services.get(service, None)
                        if nodeID is None and service in self.machoNet.serviceInfo:
                            where = self.machoNet.serviceInfo[service]
                            if where:
                                for k, v in self.machoNet.serviceInfo.iteritems():
                                    if k != service and v and (v.startswith(where) or where.startswith(v)):
                                        nodeID = self.services.get(k, None)
                                        break

                        if nodeID is None and self.services and service not in ('DB2',):
                            self.machoNet.LogInfo("I haven't got a clue where ", service, ' should run, although I could guess any of these: ', str(self.services.keys()))
                    if nodeID is None:
                        if macho.mode == 'server':
                            proxies = self.machoNet.GetConnectedProxyNodes()
                            if not proxies:
                                raise UnMachoDestination('No proxy available')
                            destination = macho.MachoAddress(nodeID=random.choice(proxies), service=service)
                        else:
                            destination = macho.MachoAddress(service=service)
                    elif isinstance(nodeID, macho.MachoAddress):
                        destination = nodeID
                    else:
                        destination = macho.MachoAddress(nodeID=nodeID, service=service)
                    if keywords:
                        kw2 = copy.copy(keywords)
                    else:
                        kw2 = {}
                    if kw2.get('machoVersion', None) is None:
                        if cachedResultRecord is not None and cachedResultRecord['version'] is not None:
                            kw2['machoVersion'] = cachedResultRecord['version']
                        else:
                            kw2['machoVersion'] = 1
                    if currentcall:
                        machoTimeout = kw2.get('machoTimeout', currentcall.packet.oob.get('machoTimeout', None))
                    else:
                        machoTimeout = kw2.get('machoTimeout', None)
                    if 'machoTimeout' in kw2:
                        del kw2['machoTimeout']
                    payload = (1,
                     method,
                     args,
                     kw2)
                    packet = macho.CallReq(destination=destination, payload=payload)
                    if machoTimeout is not None:
                        packet.oob['machoTimeout'] = machoTimeout
                    callTimer = base.CallTimer('%s::%s (ServiceCall\\Client)' % (service, method))
                    try:
                        ret = self.ForwardCallDown(packet).payload
                        self.UpdateSendServiceCallStats(service, method)
                        self.LogMethodCall(ret, service, method, args, keywords)
                    except util.UpdateMoniker as e:
                        raise 
                    except RuntimeError:
                        raise 
                    except UserError:
                        raise 
                    except ProxyRedirect:
                        raise 
                    except WrongMachoNode:
                        raise 
                    except objectCaching.CacheOK:
                        if cachedResultRecord is None:
                            raise 
                        sys.exc_clear()
                        self.LogMethodCall(cachedResultRecord['lret'], service, method, args, keywords)
                        sm.GetService('objectCaching').UpdateVersionCheckPeriod(cacheKey)
                        return cachedResultRecord['lret']
                    finally:
                        callTimer.Done()

                    if isinstance(ret, objectCaching.CachedMethodCallResult):
                        sm.GetService('objectCaching').CacheMethodCall(service, method, args, ret)
                        ret = ret.GetResult()
                    return ret
                finally:
                    mask.UnMask()
                    sessionVars2 = self._GetRemoteServiceCallVariables(sess)

            except WrongMachoNode as e:
                sys.exc_clear()
                self._HandleServiceCallWrongNode(e, service, sessionVars1, sessionVars2)
                self.services[service] = e.payload
                if nodeID == e.payload:
                    self.machoNet.LogError('Redirected to same node', nodeID)
                    raise UnMachoDestination('Failed to redirect call, because we were being redirected to the same place we were trying to call in the first place (%s)' % nodeID)
                else:
                    self.machoNet.LogInfo('Redirecting call to node ', e.payload, ' that was originally intended for node ', nodeID)
                    nodeID = e.payload
            except UserError as e:
                if e.msg in ('UnMachoDestination', 'GPSTransportClosed'):
                    self.services.clear()
                raise 
            except StandardError:
                if service in self.services:
                    otherNodeID = self.services[service]
                    for s, n in self.services.items()[:]:
                        if n and n in (otherNodeID, nodeID):
                            del self.services[s]

                raise 
Ejemplo n.º 2
0
    def ObjectCallWithoutTheStars(self, oob, persistantObjectID, blocking, sess, destination, objectID, method, args, keywords):
        cachable, versionCheck, throwOK, cachedResultRecord, cacheKey, cacheDetails = sm.GetService('objectCaching').PerformCachedMethodCall(None, persistantObjectID, method, args)
        if cachable:
            if not versionCheck:
                if throwOK:
                    sm.GetService('objectCaching').LogInfo('Local cache hit with throw for remote object ', persistantObjectID, '::', method, '(', args, ')')
                    raise objectCaching.CacheOK()
                elif cachedResultRecord:
                    sm.GetService('objectCaching').LogInfo('Local cache hit for remote object ', persistantObjectID, '::', method, '(', args, ')')
                    return cachedResultRecord['lret']
        if keywords:
            kw2 = copy.copy(keywords)
        else:
            kw2 = {}
        if kw2.get('machoVersion', None) is None:
            if cachedResultRecord is not None and cachedResultRecord['version'] is not None:
                kw2['machoVersion'] = cachedResultRecord['version']
            else:
                kw2['machoVersion'] = 1
        if currentcall:
            machoTimeout = kw2.get('machoTimeout', currentcall.packet.oob.get('machoTimeout', None))
        else:
            machoTimeout = kw2.get('machoTimeout', None)
        if 'machoTimeout' in kw2:
            del kw2['machoTimeout']
        payload = (1, self.ToPickle((objectID,
          method,
          args,
          kw2)))
        if blocking == 1:
            packet = macho.CallReq(destination=destination, payload=payload)
            if oob:
                packet.oob = oob
            if machoTimeout is not None:
                packet.oob['machoTimeout'] = machoTimeout
            if self.added_objects:
                if 'OID+' in packet.oob:
                    packet.oob['OID+'].update(self.added_objects)
                else:
                    packet.oob['OID+'] = self.added_objects
            try:
                callTimer = base.CallTimer('Remote Object Call::%s (ObjectCall\\Client)' % (method,))
                try:
                    retval = self.ForwardCallDown(packet)
                finally:
                    callTimer.Done()

                retval = self.FromPickle(retval.payload, packet.destination)
            except objectCaching.CacheOK:
                if cachedResultRecord is None:
                    raise 
                sys.exc_clear()
                sm.GetService('objectCaching').LogInfo('Version matches for remote object ', persistantObjectID, '::', method, '(', args, ')')
                sm.GetService('objectCaching').UpdateVersionCheckPeriod(cacheKey)
                return cachedResultRecord['lret']

            if isinstance(retval, objectCaching.CachedMethodCallResult):
                sm.GetService('objectCaching').CacheMethodCall(persistantObjectID, method, args, retval)
                retval = retval.GetResult()
            return retval
        else:
            packet = macho.Notification(destination=destination, payload=payload)
            if oob:
                packet.oob = oob
            if machoTimeout is not None:
                packet.oob['machoTimeout'] = machoTimeout
            if self.added_objects:
                if 'OID+' in packet.oob:
                    packet.oob['OID+'].update(self.added_objects)
                else:
                    packet.oob['OID+'] = self.added_objects
            self.ForwardNotifyDown(packet)
            return MachoBoobyTrap()