Skip to content

Instantly share code, notes, and snippets.

@signalpillar
Last active December 23, 2015 02:39
Show Gist options
  • Save signalpillar/6568353 to your computer and use it in GitHub Desktop.
Save signalpillar/6568353 to your computer and use it in GitHub Desktop.
keep future/deffered API clean - when it comes to have list of functions to build a chain - don't. Leave this for the client code of API timer.set_callback(callback_fn) timer.remove_callback(callback_fn)
from itertools import imap
def create_future():
future = ...
# add tulip-like callback chain
fns = [first_callback_fn, second_callback_fn, third_callback_fn]
future.set_callback(tulip_chain(fns))
# in case you want to remove some of the functions in the chain
# just modify list of functions - you gain much more flexibility
# as you deal with standard python list and hundreds of functions around it
fns = fns[:-1]
future.set_callback(tulip_chain(fns))
# create twisted chain
future.set_callback(twisted_chain(fns, []))
return future
#--------------------------------
def twisted_chain(ok_fns, failure_fns):
'@types: list[callable], list[callable] -> callable'
def chain_fn(future):
fns = ()
if future.exception():
fns = failure_fns
else:
fns = ok_fns
return compose(fns)
return chain_fn
def tulip_chain(fns):
'@types: list[callable] -> callable'
callback_fn = juxt(imap(Sfn, fns))
return callback_fn
def juxt(fns):
'''
Takes a set of functions and returns a fn that is the juxtaposition
of those fns. The returned fn takes a variable number of args, and
returns a vector containing the result of applying each fn to the
args (left-to-right).
juxt(a, b, c)(x) => [a(x), b(x), c(x)]
taken from Clojure
@types: list[callable] -> callable
'''
def Sfn(fn):
'''Wraps call by try/catch block and logs error if happens
@types: callable -> callable
'''
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment