1 from __future__ import print_function
6 from Queue import Queue
7 from sfa.util.sfalogging import logger
10 def ThreadedMethod(callable, results, errors):
12 A function decorator that returns a running thread. The thread
13 runs the specified callable and stores the result in the specified
16 def wrapper(args, kwds):
17 class ThreadInstance(threading.Thread):
21 results.put(callable(*args, **kwds))
22 except Exception as e:
23 logger.log_exc('MultiClient: Error in thread: ')
24 errors.put(traceback.format_exc())
26 thread = ThreadInstance()
34 MultiClient allows to issue several SFA calls in parallel in different threads
35 and stores the results in a thread safe queue.
39 self.results = Queue()
43 def run(self, method, *args, **kwds):
45 Execute a callable in a separate thread.
47 method = ThreadedMethod(method, self.results, self.errors)
48 thread = method(args, kwds)
49 self.threads.append(thread)
55 Wait for all threads to complete
57 for thread in self.threads:
60 def get_results(self, lenient=True):
62 Return a list of all the results so far. Blocks until
63 all threads are finished.
64 If lenient is set to false the error queue will be checked before
65 the response is returned. If there are errors in the queue an SFA Fault will
71 errors = self.get_errors()
73 raise Exception(errors[0])
75 while not self.results.empty():
76 results.append(self.results.get())
81 Return a list of all errors. Blocks untill all threads are finished
85 while not self.errors.empty():
86 errors.append(self.errors.get())
89 def get_return_value(self):
91 Get the value that should be returuned to the client. If there are errors then the
92 first error is returned. If there are no errors, then the first result is returned
96 if __name__ == '__main__':
98 def f(name, n, sleep=1):
100 for i in range(n, n + 5):
101 print("%s: %s" % (name, i))
106 def e(name, n, sleep=1):
108 for i in range(n, n + 3) + ['n', 'b']:
109 print("%s: 1 + %s:" % (name, i))
114 threads = MultiClient()
115 threads.run(f, "Thread1", 10, 2)
116 threads.run(f, "Thread2", -10, 1)
117 threads.run(e, "Thread3", 19, 1)
119 #results = threads.get_results()
120 #errors = threads.get_errors()
121 # print "Results:", results
122 # print "Errors:", errors
123 results_xlenient = threads.get_results(lenient=False)