task.py
author Fabien Ninoles <fabien@tzone.org>
Sun, 21 Mar 2010 21:47:48 -0400
changeset 5 eb1133af54ed
permissions -rw-r--r--
Seperate task and scheduler.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
     1
import threading # Only used in SetupEvent
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
     2
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
     3
class _Callback(object):
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
     4
    def __init__(self, callback, errorback, threaded = False):
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
     5
        self.callback = callback
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
     6
        self.errorback = errorback
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
     7
        self.next = None
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
     8
        self.threaded = threaded
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
     9
    def Chain(self, next):
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    10
        # Can only be called once
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    11
        assert(self.next is None)
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    12
        self.next = next
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    13
        return next
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    14
    def Next(self):
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    15
        return self.next
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    16
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    17
##
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    18
# A task, representing a series of linked pairs of callback and error
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    19
# handler Concept is similar to twisted, but you need to put all your
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    20
# callback on the task before giving it to the Scheduler.  For this
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    21
# reason, you shouldnt call the callback/errorback method yourself (or
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    22
# at least, don't put it back in the scheduler after that).
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    23
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    24
class Task(object):
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    25
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    26
    @staticmethod
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    27
    def DefaultCallback(result):
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    28
        return result
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    29
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    30
    @staticmethod
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    31
    def DefaultErrorback(error):
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    32
        return error
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    33
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    34
    def __init__(self, func = None, *args, **kwargs):
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    35
        super(Task, self).__init__()
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    36
        self.head = None
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    37
        self.tail = None
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    38
        if func:
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    39
            def callback(result):
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    40
                return func(*args, **kwargs)
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    41
            self.AddCallback(callback)
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    42
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    43
    def _AddCallback(self, callback):
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    44
        if self.head is None:
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    45
            self.head = self.tail = callback
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    46
        else:
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    47
            self.tail = self.tail.Chain(callback)
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    48
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    49
    def _GetNext(self):
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    50
        head = self.head
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    51
        if head:
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    52
            self.head = head.Next()
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    53
        return head
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    54
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    55
    def AddCallback(self, callback, errorback = None, threaded = False):
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    56
        if errorback == None:
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    57
            errorback = self.DefaultErrorback
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    58
        cb = _Callback(callback, errorback, threaded)
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    59
        self._AddCallback(cb)
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    60
        # permit chained calls
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    61
        return self
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    62
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    63
    def AddThreadedCallback(self, callback, errorback = None):
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    64
        return self.AddCallback(callback, errorback, True)
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    65
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    66
    def ChainTask(self, task):
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    67
        self.tail.Chain(task.head)
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    68
        self.tail = task.tail
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    69
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    70
    def GrabResult(self, data = None):
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    71
        if data is None:
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    72
            data = {}
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    73
        def SetResult(result):
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    74
            data["result"] = result
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    75
            return result
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    76
        def SetError(error):
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    77
            data["error"] = error
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    78
        self.AddCallback(SetResult, SetError)
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    79
        return data
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    80
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    81
    def SetupEvent(self, event = None, data = None):
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    82
        if not event:
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    83
            event = threading.Event()
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    84
        def SetEvent(dummy):
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    85
            event.set()
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    86
        self.AddCallback(SetEvent, SetEvent)
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    87
        return event
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    88
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    89
##
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    90
# Helper class
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    91
class ThreadedTask(Task):
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    92
    def __init__(self, func, *args, **kwargs):
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    93
        super(ThreadedTask, self).__init__(func, *args, **kwargs)
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    94
        self.head.threaded = True
eb1133af54ed Seperate task and scheduler.
Fabien Ninoles <fabien@tzone.org>
parents:
diff changeset
    95