Author: tmckay Date: 2011-08-03 18:17:08 +0000 (Wed, 03 Aug 2011) New Revision: 4904
Modified: trunk/cumin/python/cumin/task.py trunk/sage/python/sage/util.py trunk/sage/python/sage/wallaby/wallabyoperations.py Log: Make callback functions in TaskInvocation and CallSync take variable arguments to support both callback(status, result) and callback(result) formats. Add call_async() general wrapper to sage.util.
Modified: trunk/cumin/python/cumin/task.py =================================================================== --- trunk/cumin/python/cumin/task.py 2011-08-02 20:22:05 UTC (rev 4903) +++ trunk/cumin/python/cumin/task.py 2011-08-03 18:17:08 UTC (rev 4904) @@ -172,15 +172,39 @@ log.info("Ended %s", self.task)
def make_callback(self): - def completion(status_code, output_args): + def completion(*args): + # Callback argument formats come in two basic flavors in Cumin + # depending on the semantics of the async op: + # callback(status, result) + # callback(result) where type(result) == Exception indicates + # a failure status. + # Allow this general mechanism to handle both types. + + output_args = None + if len(args) == 0: + # We have to test this case now since we've made args + # variable length. Just call it OK + status_code = self.OK + + elif len(args) == 1: + # Status is ok if status_code is not an exception and result + # goes in output_args + status_code = args[0] + if not isinstance(status_code, Exception): + output_args = status_code + status_code = self.OK + + else: + status_code, output_args = args[0:2] + # Make results recorded directly through the callback # match what is done when TaskInvocation values are # set by an ObjectTask or Task on failure # (see Task.invoke() and Task.exception() above) # Previously the different mechanisms produced different results. - if status_code not in (0, "OK"): + if isinstance(status_code, Exception): self.status = self.FAILED - self.exception = Exception(status_code) + self.exception = status_code else: self.status_code = status_code self.output_args = output_args
Modified: trunk/sage/python/sage/util.py =================================================================== --- trunk/sage/python/sage/util.py 2011-08-02 20:22:05 UTC (rev 4903) +++ trunk/sage/python/sage/util.py 2011-08-03 18:17:08 UTC (rev 4904) @@ -24,9 +24,9 @@ General callback object for asynchronous operations. The 'get_completion' method will return a function that can be used as a callback when an asynchronous operation completes. - To change the signature of the callback function, derive from + To change the signature or function of the callback, derive from this class and override 'get_completion', changing the definition - of the 'completion' function. + of the 'completion'. The 'done' method can be polled to determine if the operation has completed. ''' def __init__(self, log=None, default=None): @@ -40,8 +40,29 @@ # obj.get_completion is called and 'completion' is returned. # This allows the code invoking the callback to call a simple # function without an object reference (the reference is hidden - # inside the bound function). - def completion(status, data): + # inside the bound function). Formally known as a "closure" + + def completion(*args): + # Callback argument formats come in two basic flavors in Cumin + # depending on the semantics of the async op: + # callback(status, result) + # callback(result) where type(result) == Exception indicates + # a failure status + # Allow this general mechanism to handle both types. + + data = None + if len(args) == 0: + # Just call it successful with no data + status = 0 + + elif len(args) == 1: + status = args[0] + if not isinstance(status, Exception): + data = status + status = 0 + else: + staus, data = args[0:2] + self.status = status if (status == 0) or (status == "OK"): self.data = data @@ -127,6 +148,19 @@ if self.callback is not None: self.callback(result)
+def call_async(callback, call, *args, **kwargs): + ''' + Use CallThread to execute call(*args, **kwargs). + + If callback is not None, the thread will call + callback(result) after call() completes. + ''' + assert callable(call) + assert callback is None or callable(callback) + + t = CallThread(call, callback, *args, **kwargs) + t.start() + class ObjectPool(object): ''' Simple threadsafe pool class that holds up to max_size objects.
Modified: trunk/sage/python/sage/wallaby/wallabyoperations.py =================================================================== --- trunk/sage/python/sage/wallaby/wallabyoperations.py 2011-08-02 20:22:05 UTC (rev 4903) +++ trunk/sage/python/sage/wallaby/wallabyoperations.py 2011-08-03 18:17:08 UTC (rev 4904) @@ -415,7 +415,7 @@ return False return True
- def edit_tags(self, node, tags): + def edit_tags(self, node, *tags): ''' Replace existing tags on a node with the specified tags.
cumin-developers@lists.fedorahosted.org