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
[email protected]
https://www.redhat.com/mailman/listinfo/func-list