Hi all, I have implemented support for asynchronous calls in func (see attached patch). It's rather quick and dirty but it does work (tested with inventory methods taking about 30 seconds), running the methods in parallel. Please consider for inclusion in mainline. Patch based on func-0.24-1.el5. Best regards, Grzegorz Nosek BTW, func.client.overlord.Overlord(noglobs=True, async=True) is broken (does not actually run any method calls)
diff --git a/inventory.py b/inventory.py index 9bac2ed..e1f3c92 100644 --- a/inventory.py +++ b/inventory.py @@ -23,6 +23,7 @@ import xmlrpclib from func.minion import sub_process import func.overlord.client as func_client import func.utils as utils +import func.jobthing as jobthing DEFAULT_TREE = "/var/lib/func/inventory/" @@ -65,6 +66,9 @@ class FuncInventory(object): p.add_option("-j", "--json", dest="json", help="output data using JSON", action="store_true") + p.add_option("-a", "--async", dest="async", + help="use asynchronous calls for long-running methods", + action="store_true") (options, args) = p.parse_args(args) @@ -81,6 +85,10 @@ class FuncInventory(object): # call all remote info methods and handle them if options.verbose: print "- scanning ..." + + # for async mode + jobs = {} + # for (host, modules) in host_modules.iteritems(): for (host, methods) in host_methods.iteritems(): @@ -105,12 +113,45 @@ class FuncInventory(object): if not "all" in filtered_function_list and not method_name in filtered_function_list: continue - - overlord = func_client.Overlord(host,noglobs=True) # ,noglobs=True) - results = getattr(getattr(overlord,module_name),method_name)() + if self.options.verbose: print "-- %s: running: %s %s" % (host, module_name, method_name) - self.save_results(options, host, module_name, method_name, results) + + if options.async: + job_name = (host, module_name, method_name) + overlord = func_client.Overlord(host,noglobs=False,async=True) + job_id = getattr(getattr(overlord,module_name),method_name)() + jobs[job_name] = (overlord, job_id) + else: + overlord = func_client.Overlord(host,noglobs=True) + results = getattr(getattr(overlord,module_name),method_name)() + self.save_results(options, host, module_name, method_name, results) + + if options.async: + results = {} + while jobs: + for job_name in jobs.keys(): + job = jobs[job_name] + (host, module_name, method_name) = job_name + (overlord, job_id) = job + + status = overlord.job_status(job_id) + (code, results) = status + if self.options.verbose: + print "-- %s %s %s: job id %s status %d" % (host, module_name, method_name, job_id, code) + if code == jobthing.JOB_ID_RUNNING: + continue + elif code == jobthing.JOB_ID_PARTIAL: + continue + elif code == jobthing.JOB_ID_FINISHED: + results = results[host] + else: + results = "Job lost in space" + self.save_results(options, host, module_name, method_name, results) + del jobs[job_name] + if jobs: + time.sleep(1) + self.git_update(options) return 1
_______________________________________________ Func-list mailing list Func-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/func-list