Initial commit
This commit is contained in:
30
README.md
Normal file
30
README.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# Go-Do
|
||||
Implement a simple way to "toss" a job to be run
|
||||
in parallel with your main application logic
|
||||
and when you're ready to use the results of
|
||||
that job query if it's finished.
|
||||
|
||||
Example:
|
||||
|
||||
```python
|
||||
from go_do import Do
|
||||
|
||||
## From a docker hub api bit of code.
|
||||
|
||||
def get_all(url):
|
||||
"Retrieve all paged results"
|
||||
rsp = urllib.request.urlopen(url)
|
||||
while 200 <= int(rsp.getcode()) < 300:
|
||||
data = json.loads(rsp.read())
|
||||
url = data.get("next")
|
||||
next = Do(urllib.request.urlopen, url) if url else None
|
||||
for item in data['results']:
|
||||
yield item
|
||||
if next is None:
|
||||
break
|
||||
# If the result is not ready yet, wait for it.
|
||||
rsp = next.wait_for_it()
|
||||
print("Done")
|
||||
```
|
||||
|
||||
|
||||
60
go_do.py
Normal file
60
go_do.py
Normal file
@@ -0,0 +1,60 @@
|
||||
#!python3
|
||||
"""
|
||||
go_do.py
|
||||
========
|
||||
Implement a simple parallel work class.
|
||||
"""
|
||||
# Uses low level threading.
|
||||
import sys
|
||||
import _thread as _t
|
||||
|
||||
class NotReadyError(RuntimeError):
|
||||
"Job is still running"
|
||||
|
||||
class Do:
|
||||
"""
|
||||
Easy to use multi-threading.
|
||||
"""
|
||||
_tid = None
|
||||
_running = None
|
||||
_result = None
|
||||
_exc_info = None
|
||||
|
||||
def __init__(self, func, *args, **kwarg):
|
||||
assert callable(func)
|
||||
self._running = _t.allocate_lock()
|
||||
self._tid = _t.start_new_thread(self.run, args, kwarg)
|
||||
|
||||
def run(self, func, args, kwarg):
|
||||
"Acquire locks, start thread, return thread id"
|
||||
self._running.acquire()
|
||||
try:
|
||||
self._result = func(*args, **kwarg)
|
||||
except:
|
||||
self._exc_info = sys.exc_info()
|
||||
finally:
|
||||
self._running.release()
|
||||
|
||||
def done(self):
|
||||
"Return True if the job finished running"
|
||||
return not self._running.locked()
|
||||
|
||||
def running(self):
|
||||
"Return True if the job is still running"
|
||||
return self._running.locked()
|
||||
|
||||
def wait_for_it(self, _timeout=-1):
|
||||
"Wait for the result to be available"
|
||||
if self._running.acquire(True, _timeout):
|
||||
self._running.release()
|
||||
return self._result
|
||||
raise NotReadyError("Exceeded the timeout")
|
||||
|
||||
def result(self):
|
||||
"Return the result if available, raise NotReadyError if not"
|
||||
if self._running.acquire(False):
|
||||
self._running.release()
|
||||
return self._result
|
||||
raise NotReadyError("Result is not ready yet")
|
||||
|
||||
# Fin
|
||||
Reference in New Issue
Block a user