4 from Queue import Queue
6 def ThreadedMethod(callable, results, errors):
8 A function decorator that returns a running thread. The thread
9 runs the specified callable and stores the result in the specified
12 def wrapper(args, kwds):
13 class ThreadInstance(threading.Thread):
16 results.put(callable(*args, **kwds))
18 errors.put(traceback.format_exc())
20 thread = ThreadInstance()
29 ThreadManager executes a callable in a thread and stores the result
30 in a thread safe queue.
36 def run (self, method, *args, **kwds):
38 Execute a callable in a separate thread.
40 method = ThreadedMethod(method, self.results, self.errors)
41 thread = method(args, kwds)
42 self.threads.append(thread)
48 Wait for all threads to complete
50 for thread in self.threads:
53 def get_results(self, lenient=True):
55 Return a list of all the results so far. Blocks until
56 all threads are finished.
57 If lienent is set to false the error queue will be checked before
58 the response is returned. If there are errors in the queue an SFA Fault will
64 errors = self.get_errors()
66 raise Exception(errors[0])
68 while not self.results.empty():
69 results.append(self.results.get())
74 Return a list of all errors. Blocks untill all threads are finished
78 while not self.errors.empty():
79 errors.append(self.errors.get())
82 def get_return_value(self):
84 Get the value that should be returuned to the client. If there are errors then the
85 first error is returned. If there are no errors, then the first result is returned
89 if __name__ == '__main__':
91 def f(name, n, sleep=1):
93 for i in range(n, n+5):
94 print "%s: %s" % (name, i)
98 def e(name, n, sleep=1):
100 for i in range(n, n+3) + ['n', 'b']:
101 print "%s: 1 + %s:" % (name, i)
106 threads = ThreadManager()
107 threads.run(f, "Thread1", 10, 2)
108 threads.run(f, "Thread2", -10, 1)
109 threads.run(e, "Thread3", 19, 1)
111 #results = threads.get_results()
112 #errors = threads.get_errors()
113 #print "Results:", results
114 #print "Errors:", errors
115 results_xlenient = threads.get_results(lenient=False)