Exemplo n.º 1
0
    def _hook_launch(self, kwargs, d):
        """Snoop launch commands to keep track of the current task."""
        self.task = kwargs['task']
        self.launcher = kwargs.pop('launcher')
        self.logRelay = LogRelay(self.launcher.bus.sendToTarget, self.task)

        # Fail tasks that exited cleanly but didn't report success.
        def cb_checkResult(result):
            if not self.task.status.final:
                raise InternalWorkerError("Task failed to send a finalized "
                        "status before terminating.")
            return result
        d.addCallback(cb_checkResult)

        # Turn process termination events into relevant exceptions.
        def eb_filterErrors(reason):
            if reason.check(ierror.ProcessTerminated, ierror.ProcessDone):
                log.error("Worker exited prematurely with status %s",
                        reason.value.status)
                raise InternalWorkerError("The worker executing the task "
                        "has exited abnormally.")
            return reason
        d.addErrback(eb_filterErrors)

        # Report errors back to the dispatcher. Using a function here because
        # self.task will get replaced.
        def eb_failTask(reason):
            self.launcher.failTask(reason, self.task)
        d.addErrback(eb_failTask)

        # Clear saved task and launcher fields after the task is done.
        def bb_clearTask(result):
            self.logRelay.close()
            self.task = self.launcher = self.logRelay = None
        d.addBoth(bb_clearTask)

        d.addErrback(logger.logFailure)
Exemplo n.º 2
0
class WorkerParent(WorkerProtocol):
    """Communicate messages from the launcher to the executor."""

    def __init__(self):
        self.ctr = 0
        self.pending = {}
        self.task = None
        self.launcher = None
        self.logRelay = None

    def callRemote(self, command, **kwargs):
        ctr = self.ctr
        self.ctr += 1
        d = self.pending[ctr] = defer.Deferred()
        if command == 'launch':
            self._hook_launch(kwargs, d)
        self.sendCommand(ctr, command, **kwargs)
        return d

    def connectionLost(self, reason):
        """Child process went away, fail all pending calls."""
        for d in self.pending.values():
            d.errback(reason)

    def cmd_ack(self, ctr, **result):
        if not result:
            result = None
        d = self.pending.pop(ctr)
        d.callback(result)

    def _hook_launch(self, kwargs, d):
        """Snoop launch commands to keep track of the current task."""
        self.task = kwargs['task']
        self.launcher = kwargs.pop('launcher')
        self.logRelay = LogRelay(self.launcher.bus.sendToTarget, self.task)

        # Fail tasks that exited cleanly but didn't report success.
        def cb_checkResult(result):
            if not self.task.status.final:
                raise InternalWorkerError("Task failed to send a finalized "
                        "status before terminating.")
            return result
        d.addCallback(cb_checkResult)

        # Turn process termination events into relevant exceptions.
        def eb_filterErrors(reason):
            if reason.check(ierror.ProcessTerminated, ierror.ProcessDone):
                log.error("Worker exited prematurely with status %s",
                        reason.value.status)
                raise InternalWorkerError("The worker executing the task "
                        "has exited abnormally.")
            return reason
        d.addErrback(eb_filterErrors)

        # Report errors back to the dispatcher. Using a function here because
        # self.task will get replaced.
        def eb_failTask(reason):
            self.launcher.failTask(reason, self.task)
        d.addErrback(eb_failTask)

        # Clear saved task and launcher fields after the task is done.
        def bb_clearTask(result):
            self.logRelay.close()
            self.task = self.launcher = self.logRelay = None
        d.addBoth(bb_clearTask)

        d.addErrback(logger.logFailure)


    def cmd_status_update(self, ctr, task):
        """Propagate status updates back to the dispatcher."""
        if task.task_uuid != self.task.task_uuid:
            log.warning("Dropping worker status report for wrong task.")
            return
        self.task = task
        self.launcher.forwardTaskStatus(task)

    def cmd_push_logs(self, ctr, records):
        if not self.task:
            return
        self.launcher.forwardTaskLogs(self.task, records)