Skip to content

Instantly share code, notes, and snippets.

@joe-sullivan
Last active December 5, 2017 15:24
Show Gist options
  • Save joe-sullivan/7b301ae0c05887e9c3bdcdf7c8c14620 to your computer and use it in GitHub Desktop.
Save joe-sullivan/7b301ae0c05887e9c3bdcdf7c8c14620 to your computer and use it in GitHub Desktop.
Easily create asynchronous functions in python using a decorator
import sys
if sys.version[0] == '2':
from Queue import Queue
else:
from queue import Queue
from threading import Thread
class asynchronous(object):
def __init__(self, func):
self.func = func
def threaded(*args, **kwargs):
self.queue.put(self.func(*args, **kwargs))
self.threaded = threaded
def __call__(self, *args, **kwargs):
return self.func(*args, **kwargs)
def start(self, *args, **kwargs):
self.queue = Queue()
thread = Thread(target=self.threaded, args=args, kwargs=kwargs);
thread.start();
return asynchronous.Result(self.queue, thread)
class NotYetDoneException(Exception):
def __init__(self, message):
self.message = message
class Result(object):
def __init__(self, queue, thread):
self.queue = queue
self.thread = thread
def is_done(self):
return not self.thread.is_alive()
def get_result(self):
if not self.is_done():
raise asynchronous.NotYetDoneException('the call has not yet completed its task')
if not hasattr(self, 'result'):
self.result = self.queue.get()
return self.result
def ensure_finish(self):
self.thread.join()
if __name__ == '__main__':
# sample usage
import time
@asynchronous
def long_process(num):
print('Start: %d' % num)
time.sleep(2)
print('End: %d' % num)
return num * num
results = [long_process.start(i) for i in range(3)]
for result in results:
result.ensure_finish()
if result.is_done():
print("result {0}".format(result.get_result()))
result = long_process.start(13)
# result.ensure_finish()
try:
print("result2 {0}".format(result.get_result()))
except asynchronous.NotYetDoneException as ex:
print(ex.message)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment