Пример #1
0
 def _convention_leader_checks(self):
     return foldl(lambda x, y: x + y,
                  [self._missed_checkin_remote_cleanup(R)
                   for R in [ member
                              for member in self._conventionMembers.values()
                              if member.registryValid.expired() ]],
                  [])
Пример #2
0
 def _convention_leader_checks(self, ct):
     return foldl(lambda x, y: x + y, [
         self._missed_checkin_remote_cleanup(R) for R in [
             member for member in self._conventionMembers.values()
             if member.registryValid.view(ct).expired()
         ]
     ], [])
Пример #3
0
 def check_convention(self):
     rmsgs = []
     if self._has_been_activated:
         rmsgs = foldl(lambda x, y: x + y,
                       [self._check_preregistered_ping(member)
                        for member in self._conventionMembers.values()],
                       self._convention_leader_checks()
                       if self.isConventionLeader() or
                       not self.conventionLeaderAddr else
                       self._convention_member_checks())
     if self._conventionRegistration.expired():
         self._conventionRegistration = ExpirationTimer(CONVENTION_REREGISTRATION_PERIOD)
     return rmsgs
Пример #4
0
 def check_convention(self):
     ct = currentTime()
     rmsgs = []
     if self._has_been_activated:
         rmsgs = foldl(lambda x, y: x + y,
                       [self._check_preregistered_ping(ct, member)
                        for member in self._conventionMembers.values()],
                       self._convention_leader_checks(ct)
                       if self.isConventionLeader() or
                       not self.conventionLeaderAddr else
                       self._convention_member_checks(ct))
     if self._conventionRegistration.view(ct).expired():
         self._conventionRegistration = ExpirationTimer(CONVENTION_REREGISTRATION_PERIOD)
     return rmsgs
Пример #5
0
    def forward_pending_to_remote_system(self, childClass, envelope,
                                         sourceHash, acceptsCaps):
        alreadyTried = getattr(envelope.message, 'alreadyTried', [])
        ct = currentTime()
        if self.myAddress not in alreadyTried:
            # Don't send request back to this actor system: it cannot
            # handle it
            alreadyTried.append(self.myAddress)

        remoteCandidates = [
            K for K in self._conventionMembers.values()
            if not K.registryValid.view(ct).expired()
            and K.remoteAddress != envelope.sender  # source Admin
            and K.remoteAddress not in alreadyTried
            and acceptsCaps(K.remoteCapabilities)
        ]

        if not remoteCandidates:
            if self.isConventionLeader() or not self.conventionLeaderAddr:
                raise NoCompatibleSystemForActor(
                    childClass, 'No known ActorSystems can handle a %s for %s',
                    childClass, envelope.message.forActor)
            # Let the Convention Leader try to find an appropriate ActorSystem
            bestC = self.conventionLeaderAddr
        else:
            # distribute equally amongst candidates
            C = [(K.remoteAddress, len(K.hasRemoteActors))
                 for K in remoteCandidates]
            bestC = foldl(
                lambda best, possible: best
                if best[1] <= possible[1] else possible, C)[0]
            thesplog('Requesting creation of %s%s on remote admin %s',
                     envelope.message.actorClassName,
                     ' (%s)' % sourceHash if sourceHash else '', bestC)
        if bestC in alreadyTried:
            return []  # Have to give up, no-one can handle this

        # Don't send request to this remote again, it has already
        # been tried.  This would also be indicated by that system
        # performing the add of self.myAddress as below, but if
        # there is disagreement between the local and remote
        # addresses, this addition will prevent continual
        # bounceback.
        alreadyTried.append(bestC)
        envelope.message.alreadyTried = alreadyTried
        return [TransmitIntent(bestC, envelope.message)]
Пример #6
0
    def forward_pending_to_remote_system(self, childClass, envelope, sourceHash, acceptsCaps):
        alreadyTried = getattr(envelope.message, 'alreadyTried', [])

        remoteCandidates = [
            K
            for K in self._conventionMembers.values()
            if not K.registryValid.expired()
            and K.remoteAddress != envelope.sender # source Admin
            and K.remoteAddress not in alreadyTried
            and acceptsCaps(K.remoteCapabilities)]

        if not remoteCandidates:
            if self.isConventionLeader() or not self.conventionLeaderAddr:
                raise NoCompatibleSystemForActor(
                    childClass,
                    'No known ActorSystems can handle a %s for %s',
                    childClass, envelope.message.forActor)
            # Let the Convention Leader try to find an appropriate ActorSystem
            bestC = self.conventionLeaderAddr
        else:
            # distribute equally amongst candidates
            C = [(K.remoteAddress, len(K.hasRemoteActors))
                 for K in remoteCandidates]
            bestC = foldl(lambda best,possible:
                          best if best[1] <= possible[1] else possible,
                          C)[0]
            thesplog('Requesting creation of %s%s on remote admin %s',
                     envelope.message.actorClassName,
                     ' (%s)'%sourceHash if sourceHash else '',
                     bestC)
        if bestC not in alreadyTried:
            # Don't send request to this remote again, it has already
            # been tried.  This would also be indicated by that system
            # performing the add of self.myAddress as below, but if
            # there is disagreement between the local and remote
            # addresses, this addition will prevent continual
            # bounceback.
            alreadyTried.append(bestC)
        if self.myAddress not in alreadyTried:
            # Don't send request back to this actor system: it cannot
            # handle it
            alreadyTried.append(self.myAddress)
        envelope.message.alreadyTried = alreadyTried
        return [TransmitIntent(bestC, envelope.message)]
 def childResetFileNumList(self):
     return foldl(lambda a, b: a+[b._reader.fileno(), b._writer.fileno()],
                  [self._parentQ] +
                  list(self._queues.values()), [])
 def protectedFileNumList(self):
     return foldl(lambda a, b: a+[b._reader.fileno(), b._writer.fileno()],
                  [self._myInputQ, self._parentQ, self._adminQ] +
                  list(self._queues.values()), [])
 def childResetFileNumList(self):
     return foldl(lambda a, b: a+[b._reader.fileno(), b._writer.fileno()],
                  [self._parentQ] +
                  list(self._queues.values()), [])
 def protectedFileNumList(self):
     return foldl(lambda a, b: a+[b._reader.fileno(), b._writer.fileno()],
                  [self._myInputQ, self._parentQ, self._adminQ] +
                  list(self._queues.values()), [])
Пример #11
0
 def h_PendingActor(self, envelope):
     sourceHash = envelope.message.sourceHash
     childRequirements = envelope.message.targetActorReq
     thesplog('Pending Actor request for %s%s reqs %s from %s',
              envelope.message.actorClassName,
              ' (%s)' % sourceHash if sourceHash else '', childRequirements,
              envelope.sender)
     # If this request was forwarded by a remote Admin and the
     # sourceHash is not known locally, request it from the sending
     # remote Admin
     if sourceHash and \
        sourceHash not in self._sources and \
        self._sentByRemoteAdmin(envelope) and \
        self._acceptsRemoteLoadedSourcesFrom(envelope):
         requestedAlready = self._pendingSources.get(sourceHash, False)
         self._pendingSources.setdefault(sourceHash, []).append(envelope)
         if not requestedAlready:
             self._hysteresisSender.sendWithHysteresis(
                 TransmitIntent(envelope.sender,
                                SourceHashTransferRequest(sourceHash)))
             return False  # sent with hysteresis, so break out to local _run
         return True
     # If the requested ActorClass is compatible with this
     # ActorSystem, attempt to start it, otherwise forward the
     # request to any known compatible ActorSystem.
     try:
         childClass = actualActorClass(
             envelope.message.actorClassName,
             partial(loadModuleFromHashSource, sourceHash, self._sources)
             if sourceHash else None)
         acceptsCaps = lambda caps: checkActorCapabilities(
             childClass, caps, childRequirements)
         if not acceptsCaps(self.capabilities):
             if envelope.message.forActor is None:
                 # Request from external; use sender address
                 envelope.message.forActor = envelope.sender
             remoteCandidates = [
                 K for K in self._conventionMembers
                 if not self._conventionMembers[K].registryValid.expired()
                 and self._conventionMembers[K].remoteAddress !=
                 envelope.sender  # source Admin
                 and self._conventionMembers[K].remoteAddress not in
                 getattr(envelope.message, 'alreadyTried', []) and
                 acceptsCaps(self._conventionMembers[K].remoteCapabilities)
             ]
             if not remoteCandidates:
                 if self.isConventionLeader():
                     thesplog(
                         'No known ActorSystems can handle a %s for %s',
                         childClass,
                         envelope.message.forActor,
                         level=logging.WARNING,
                         primary=True)
                     self._sendPendingActorResponse(
                         envelope,
                         None,
                         errorCode=PendingActorResponse.
                         ERROR_No_Compatible_ActorSystem)
                     return True
                 # Let the Convention Leader try to find an appropriate ActorSystem
                 bestC = self._conventionAddress
             else:
                 # distribute equally amongst candidates
                 C = [(self._conventionMembers[K].remoteAddress,
                       len(self._conventionMembers[K].hasRemoteActors))
                      for K in remoteCandidates]
                 bestC = foldl(
                     lambda best, possible: best
                     if best[1] <= possible[1] else possible, C)[0]
                 thesplog('Requesting creation of %s%s on remote admin %s',
                          envelope.message.actorClassName,
                          ' (%s)' % sourceHash if sourceHash else '', bestC)
             envelope.message.alreadyTried.append(self.myAddress)
             self._send_intent(TransmitIntent(bestC, envelope.message))
             return True
     except InvalidActorSourceHash:
         self._sendPendingActorResponse(
             envelope,
             None,
             errorCode=PendingActorResponse.ERROR_Invalid_SourceHash)
         return True
     except InvalidActorSpecification:
         self._sendPendingActorResponse(
             envelope,
             None,
             errorCode=PendingActorResponse.ERROR_Invalid_ActorClass)
         return True
     except ImportError as ex:
         self._sendPendingActorResponse(
             envelope,
             None,
             errorCode=PendingActorResponse.ERROR_Import,
             errorStr=str(ex))
         return True
     except AttributeError as ex:
         # Usually when the module has no attribute FooActor
         self._sendPendingActorResponse(
             envelope,
             None,
             errorCode=PendingActorResponse.ERROR_Invalid_ActorClass,
             errorStr=str(ex))
         return True
     except Exception as ex:
         import traceback
         thesplog('Exception "%s" handling PendingActor: %s', ex,
                  traceback.format_exc())
         self._sendPendingActorResponse(
             envelope,
             None,
             errorCode=PendingActorResponse.ERROR_Invalid_ActorClass,
             errorStr=str(ex))
         return True
     return super(ConventioneerAdmin, self).h_PendingActor(envelope)
Пример #12
0
 def h_PendingActor(self, envelope):
     sourceHash = envelope.message.sourceHash
     childRequirements = envelope.message.targetActorReq
     # If this request was forwarded by a remote Admin and the
     # sourceHash is not known locally, request it from the sending
     # remote Admin
     if sourceHash and \
        sourceHash not in self._sources and \
        self._sentByRemoteAdmin(envelope) and \
        self._acceptsRemoteLoadedSourcesFrom(envelope):
         requestedAlready = self._pendingSources.get(sourceHash, False)
         self._pendingSources.setdefault(sourceHash, []).append(envelope)
         if not requestedAlready:
             self._hysteresisSender.sendWithHysteresis(
                 TransmitIntent(envelope.sender,
                                SourceHashTransferRequest(sourceHash)))
             return False  # sent with hysteresis, so break out to local _run
         return True
     # If the requested ActorClass is compatible with this
     # ActorSystem, attempt to start it, otherwise forward the
     # request to any known compatible ActorSystem.
     try:
         childClass = actualActorClass(envelope.message.actorClassName,
                                       partial(loadModuleFromHashSource,
                                               sourceHash,
                                               self._sources)
                                       if sourceHash else None)
         acceptsCaps = lambda caps: checkActorCapabilities(childClass, caps,
                                                           childRequirements)
         if not acceptsCaps(self.capabilities):
             if envelope.message.forActor is None:
                 # Request from external; use sender address
                 envelope.message.forActor = envelope.sender
             remoteCandidates = [
                 K
                 for K in self._conventionMembers
                 if not self._conventionMembers[K].registryValid.expired()
                 and self._conventionMembers[K].remoteAddress != envelope.sender # source Admin
                 and acceptsCaps(self._conventionMembers[K].remoteCapabilities)]
             if not remoteCandidates:
                 if self.isConventionLeader():
                     thesplog('No known ActorSystems can handle a %s for %s',
                              childClass, envelope.message.forActor,
                              level=logging.WARNING, primary=True)
                     self._sendPendingActorResponse(envelope, None,
                                                    errorCode = PendingActorResponse.ERROR_No_Compatible_ActorSystem)
                     return True
                 # Let the Convention Leader try to find an appropriate ActorSystem
                 bestC = self._conventionAddress
             else:
                 # distribute equally amongst candidates
                 C = [(self._conventionMembers[K].remoteAddress,
                       len(self._conventionMembers[K].hasRemoteActors))
                      for K in remoteCandidates]
                 bestC = foldl(lambda best,possible:
                               best if best[1] <= possible[1] else possible,
                               C)[0]
             self._send_intent(TransmitIntent(bestC, envelope.message))
             return True
     except InvalidActorSourceHash:
         self._sendPendingActorResponse(envelope, None,
                                        errorCode = PendingActorResponse.ERROR_Invalid_SourceHash)
         return True
     except InvalidActorSpecification:
         self._sendPendingActorResponse(envelope, None,
                                        errorCode = PendingActorResponse.ERROR_Invalid_ActorClass)
         return True
     except ImportError:
         self._sendPendingActorResponse(envelope, None,
                                        errorCode = PendingActorResponse.ERROR_Import)
         return True
     return super(ConventioneerAdmin, self).h_PendingActor(envelope)