degal/task.py
author Tero Marttila <terom@fixme.fi>
Thu, 11 Jun 2009 21:26:05 +0300
branchthreaded-tasks
changeset 89 4b254a90d6d0
parent 88 b1b0939517e7
permissions -rw-r--r--
add task_threads config setting
88
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
"""
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     2
    Parallel execution of work, using threads.
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     3
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
    The work to be done is submit'd in the form of Tasks (which may or may not be `threadable`) to a TaskManager,
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
    which then takes care of actually executing the tasks, either directly, or by queueing them up in a TaskQueue for 
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     6
    execution by a TaskThread.
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     7
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     8
    Example:
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     9
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
    for retval in tasks.execute(threadable_task(foo_func, item) for item in items) :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    11
        print retval
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    12
"""
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    13
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    14
from __future__ import with_statement
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    15
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    16
import threading, Queue
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    17
import contextlib
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    18
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    19
class Task (object) :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    20
    """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    21
        A task describes some work to do
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    22
    """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    23
    
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    24
    # this task can be executed in a Python thread of its own
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    25
    threadable = False
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    26
    
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    27
    def __init__ (self, func, *args, **kwargs) :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    28
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    29
            Set this Task up to execute the given function/arguments
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    30
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    31
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    32
        self.func = func
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    33
        self.args = args
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    34
        self.kwargs = kwargs
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    35
        self.retval = self.exc_obj = None
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    36
    
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    37
    def _execute (self) :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    38
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    39
            Low-level task execution function. Calls `execute` and stores the result/error
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    40
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    41
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    42
        try :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    43
            # attempt to store normal retval
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    44
            self.retval = self.execute()
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    45
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    46
        except Exception, exc_obj :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    47
            # trap all errors
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    48
            self.exc_obj = exc_obj
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    49
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    50
    def execute (self) :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    51
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    52
            Execute the task and return any results.
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    53
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    54
            If the task is threadable, then this method must not access any external state!
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    55
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    56
            By default, this will execute and return the function given to __init__
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    57
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    58
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    59
        return self.func(*self.args, **self.kwargs)
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    60
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    61
class ThreadableTask (Task) :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    62
    """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    63
        A task that is marked as threadable by default
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    64
    """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    65
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    66
    threadable = True
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    67
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    68
class TaskQueue (object) :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    69
    """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    70
        A threadsafe queue of waiting tasks, keeping track of executing tasks.
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    71
    """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    72
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    73
    def __init__ (self) :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    74
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    75
            Setup
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    76
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    77
        
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    78
        # queue of incoming, to-be-executed tasks
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    79
        self.in_queue = Queue.Queue()
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    80
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    81
        # queue of outgoing, was-executed tasks
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    82
        self.out_queue = Queue.Queue();
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    83
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    84
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    85
    @contextlib.contextmanager
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    86
    def get_task (self) :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    87
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    88
            Intended to be used as the target of a 'with' statement to get a task from the queue and execute it.
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    89
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    90
        
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    91
        # XXX: shutdown signal?
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    92
        task = self.in_queue.get()
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    93
        
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    94
        try :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    95
            # process it
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    96
            yield task
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    97
        
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    98
        finally :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    99
            # mark it as complete
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   100
            self.in_queue.task_done()
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   101
    
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   102
    def execute_task (self, task) :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   103
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   104
            Execute the given task, and put the result in our output queue
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   105
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   106
        
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   107
        # internal execute method
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   108
        task._execute()
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   109
        
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   110
        # return value
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   111
        self.out_queue.put(task)
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   112
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   113
    def put_task (self, task) :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   114
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   115
            Add a task on to the queue.
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   116
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   117
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   118
        self.in_queue.put(task)
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   119
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   120
    def get_result (self) :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   121
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   122
            Wait for a single result from this queue.
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   123
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   124
            XXX: nothing to garuntee that this won't block
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   125
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   126
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   127
        return self.out_queue.get()
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   128
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   129
class TaskThread (threading.Thread) :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   130
    """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   131
        A Thread that executes Tasks
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   132
    """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   133
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   134
    def __init__ (self, queue) :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   135
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   136
            Setup thread and start waiting for requests
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   137
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   138
        
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   139
        super(TaskThread, self).__init__()
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   140
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   141
        self.queue = queue
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   142
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   143
        # run
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   144
        self.start()
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   145
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   146
    def run (self) :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   147
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   148
            Thread main
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   149
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   150
        
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   151
        # XXX: provide shutdown method
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   152
        while True :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   153
            # get a task to execute
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   154
            with self.queue.get_task() as task :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   155
                # execute it
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   156
                self.queue.execute_task(task)
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   157
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   158
class TaskManager (object) :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   159
    """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   160
        Provides the machinery to take tasks and execute them
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   161
    """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   162
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   163
    def __init__ (self, config) :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   164
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   165
            Initialize with given config
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   166
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   167
        
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   168
        # setup queue
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   169
        self.queue = TaskQueue()
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   170
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   171
        # setup task threads
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   172
        self.threads = [TaskThread(self.queue) for count in xrange(config.task_threads)]
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   173
    
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   174
    def submit (self, task) :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   175
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   176
            Submit given task for execution.
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   177
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   178
            This garuntees that the task will eventually be returned via our queue.
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   179
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   180
        
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   181
        if self.threads and task.threadable :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   182
            # schedule for later execution by a thread
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   183
            self.queue.put_task(task)
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   184
        
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   185
        else :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   186
            # execute directly
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   187
            self.queue.execute_task(task)
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   188
    
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   189
    def consume (self) :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   190
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   191
            Consume a single result from the task queue, either returning the return value, or raising the task's error.
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   192
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   193
        
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   194
        # get one task
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   195
        task = self.queue.get_result()
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   196
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   197
        if task.exc_obj :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   198
            # XXX: is this threadsafe?
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   199
            raise task.exc_obj
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   200
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   201
        else :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   202
            # successful execution
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   203
            return task.retval
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   204
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   205
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   206
    def execute (self, tasks) :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   207
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   208
            Schedule a series of tasks for execution, and yield the return values as they become available.
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   209
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   210
            If a task raises an error, it will be re-raised.
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   211
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   212
            Waits for all the tasks to execute.
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   213
        """
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   214
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   215
        # number of tasks submitted; how many results we expect
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   216
        task_count = len(tasks)
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   217
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   218
        # submit them
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   219
        for task in tasks :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   220
            self.submit(task)
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   221
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   222
        # yield results
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   223
        for count in xrange(task_count) :
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   224
            yield self.consume()
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   225
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   226
# pretty aliases
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   227
task = Task
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   228
threadable_task = ThreadableTask
b1b0939517e7 initial implementation of threaded rendering of a folder's images
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   229