iro/controller/task.py
author Sandro Knauß <knauss@netzguerilla.net>
Sun, 25 Mar 2012 20:14:35 +0200
branchdevel
changeset 253 e8d56537c9cc
parent 243 b348d8f15b0a
child 264 584b9c97ecfd
permissions -rw-r--r--
start documenting with reST syntax.

from functools import partial

from twisted.python import log
from twisted.internet.defer import inlineCallbacks, returnValue, maybeDeferred, Deferred

from ..error import NoRouteForTask, RejectRecipient

from ..model.offer import offers
from ..model.job import exJobs

from .pool  import taskPool

class Task:
    '''one single part of a job.
    a task is one message to one recipient
    '''
    def __init__(self, recipient, job):
        self.recipient = recipient
        self.job = job
        self.status = None
        self.error = False

    def setStatus(self,status):
        self.status = status
        return status

    def setError(self, error):
        self.status = error
        self.error = True
        return error

    def start(self):
        self.d = Deferred()
        self.d.addCallback(self.setStatus)
        self.d.addCallback(partial(self.job.setStatus,self))
        self.d.addErrback(self.setError)
        self.d.addErrback(partial(self.job.setError,self))
        taskPool.run(self._run)
        return self.d

    def _run(self):
        os= iter(self.job.offers)
        def n():
            try:
                offer = os.next()
                d = maybeDeferred(offers[offer],self.recipient,self.job.message)
                d.addCallback(self.d.callback)
                d.addErrback(addErr,offer)
                d.addErrback(self.d.errback)
                return d
            except StopIteration:
                self.d.errback(NoRouteForTask())

        def addErr(failure, offer):
            if not isinstance(failure.value, RejectRecipient):  
                log.err(_why="Job(%s): Send to '%s' failed via '%s'"%(self.job.dbjob, self.recipient, offer),_stuff=failure)
            n()
        
        n()


@inlineCallbacks
def createJob(user,recipients, msg, offers, info=None):
    job = yield exJobs.create(user, recipients, msg, offers, info)
    for r in recipients:
        task = Task(r,job)
        job.addTask(task)
        task.start()
    returnValue(job)