Last active
August 29, 2015 14:01
-
-
Save dstuebe/07cb01b13e4f46071565 to your computer and use it in GitHub Desktop.
Chaining coroutines for number crunching workflows...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
TARGETS = 'targets' | |
class AnalysisWindowComplete(Exception): | |
""" | |
Used in coroutine control flow, this is not an error condition. | |
""" | |
def coroutine(func): | |
""" | |
Decorator function for coroutines to automatically call next so that they are in | |
a ready state when they are called. (from dabeaz) | |
""" | |
def start(*args, **kwargs): | |
g = func(*args, **kwargs) | |
g.next() | |
return g | |
return start | |
@coroutine | |
def myprinter(name): | |
while True: | |
p = (yield) | |
print "printer %s says: %s" % (name, p) | |
@coroutine | |
def average(targets): | |
result = 0.0 | |
try: | |
while True: | |
cnt = 0 | |
try: | |
while True: | |
val = (yield) | |
result += val | |
cnt += 1 | |
except AnalysisWindowComplete as wc: | |
print 'In finalize with:', wc | |
result = result/cnt | |
for target in targets: | |
target.send(result) | |
result = 0.0 | |
except (ValueError, IndexError) as e: | |
raise | |
def get_targets(co): | |
try: | |
return co.gi_frame.f_locals[TARGETS] | |
except KeyError as ke: | |
print 'foo bar muck up...' | |
def set_targets(co, targets): | |
t = get_targets(co) | |
while len(t) > 0: | |
t.pop() | |
for target in targets: | |
t.append(target) | |
avg_co = average([myprinter('Initial...'),] ) | |
avg_co.send(5.) | |
avg_co.send(5.) | |
avg_co.send(5.) | |
avg_co.send(4.) | |
avg_co.throw(AnalysisWindowComplete,'foo') | |
# Now continue using the same coroutine workflow for next analysis | |
avg_co.send(6) | |
avg_co.send(6) | |
avg_co.send(7) | |
# change where things go... | |
set_targets(avg_co,(myprinter('barbaz'),myprinter('boo')) ) | |
avg_co.throw(AnalysisWindowComplete,'goo') | |
# but if you want to chain these - you spend a lot of time calling throw and creating exceptions! | |
# maybe try a class decorator to memoize __init__ for the exception? | |
# maybe try an allocation pool? | |
# or just make sure your program spends way more time in the main part of the workflow that uses send... | |
# If you are using this to throw all the time your doing it wrong. | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment