[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [XEND] Move decorate() to XendAPI.__new__ and have a static flag to
# HG changeset patch # User Alastair Tse <atse@xxxxxxxxxxxxx> # Date 1169654230 0 # Node ID da23e1b616b0a2abe46290c3ed8e18e8c95a25ab # Parent f9eceb9c52d727dc49cd03c92668dcdc62459a19 [XEND] Move decorate() to XendAPI.__new__ and have a static flag to ensure it only runs at instantiation time, and only once per Xend instance. Otherwise, decorate() runs on every invocation of /usr/sbin/xend, even if it is xend stop. Signed-off-by: Alastair Tse <atse@xxxxxxxxxxxxx> --- tools/python/xen/xend/XendAPI.py | 207 +++++++++++++++++++++------------------ 1 files changed, 115 insertions(+), 92 deletions(-) diff -r f9eceb9c52d7 -r da23e1b616b0 tools/python/xen/xend/XendAPI.py --- a/tools/python/xen/xend/XendAPI.py Wed Jan 24 15:52:26 2007 +0000 +++ b/tools/python/xen/xend/XendAPI.py Wed Jan 24 15:57:10 2007 +0000 @@ -20,6 +20,7 @@ import string import string import sys import traceback +import threading from xen.xend import XendDomain, XendDomainInfo, XendNode from xen.xend import XendLogging, XendTaskManager @@ -283,7 +284,7 @@ def do_vm_func(fn_name, vm_ref, *args, * exn.actual]) -class XendAPI: +class XendAPI(object): """Implementation of the Xen-API in Xend. Expects to be used via XMLRPCServer. @@ -296,6 +297,119 @@ class XendAPI: All XMLRPC accessible methods require an 'api' attribute and is set to the XMLRPC function name which the method implements. """ + + __decorated__ = False + __init_lock__ = threading.Lock() + + def __new__(cls, *args, **kwds): + """ Override __new__ to decorate the class only once. + + Lock to make sure the classes are not decorated twice. + """ + cls.__init_lock__.acquire() + try: + if not cls.__decorated__: + cls._decorate() + cls.__decorated__ = True + + return object.__new__(cls, *args, **kwds) + finally: + cls.__init_lock__.release() + + def _decorate(cls): + """ Decorate all the object methods to have validators + and appropriate function attributes. + + This should only be executed once for the duration of the + server. + """ + global_validators = [session_required, catch_typeerror] + classes = { + 'session' : None, + 'host' : valid_host, + 'host_cpu': valid_host_cpu, + 'network' : valid_network, + 'VM' : valid_vm, + 'VBD' : valid_vbd, + 'VIF' : valid_vif, + 'VDI' : valid_vdi, + 'VTPM' : valid_vtpm, + 'SR' : valid_sr, + 'PIF' : valid_pif, + 'task' : valid_task, + } + + # Cheat methods + # ------------- + # Methods that have a trivial implementation for all classes. + # 1. get_by_uuid == getting by ref, so just return uuid for + # all get_by_uuid() methods. + + for api_cls in classes.keys(): + get_by_uuid = '%s_get_by_uuid' % api_cls + get_uuid = '%s_get_uuid' % api_cls + def _get_by_uuid(_1, _2, ref): + return xen_api_success(ref) + + def _get_uuid(_1, _2, ref): + return xen_api_success(ref) + + setattr(cls, get_by_uuid, _get_by_uuid) + setattr(cls, get_uuid, _get_uuid) + + # Wrapping validators around XMLRPC calls + # --------------------------------------- + + for api_cls, validator in classes.items(): + def doit(n, takes_instance, async_support = False, + return_type = None): + n_ = n.replace('.', '_') + try: + f = getattr(cls, n_) + argcounts[n] = f.func_code.co_argcount - 1 + + validators = takes_instance and validator and \ + [validator] or [] + + validators += global_validators + for v in validators: + f = v(f) + f.api = n + f.async = async_support + if return_type: + f.return_type = return_type + + setattr(cls, n_, f) + except AttributeError: + log.warn("API call: %s not found" % n) + + + ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, []) + rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, []) + methods = getattr(cls, '%s_methods' % api_cls, []) + funcs = getattr(cls, '%s_funcs' % api_cls, []) + + # wrap validators around readable class attributes + for attr_name in ro_attrs + rw_attrs + cls.Base_attr_ro: + doit('%s.get_%s' % (api_cls, attr_name), True, + async_support = False) + + # wrap validators around writable class attrributes + for attr_name in rw_attrs + cls.Base_attr_rw: + doit('%s.set_%s' % (api_cls, attr_name), True, + async_support = False) + + # wrap validators around methods + for method_name, return_type in methods + cls.Base_methods: + doit('%s.%s' % (api_cls, method_name), True, + async_support = True) + + # wrap validators around class functions + for func_name, return_type in funcs + cls.Base_funcs: + doit('%s.%s' % (api_cls, func_name), False, async_support = True, + return_type = return_type) + + _decorate = classmethod(_decorate) def __init__(self, auth): self.auth = auth @@ -1813,97 +1927,6 @@ class XendAPIAsyncProxy: synchronous_method_name) return xen_api_success(task_uuid) -def _decorate(): - """Initialise Xen API wrapper by making sure all functions - have the correct validation decorators such as L{valid_host} - and L{session_required}. - """ - - global_validators = [session_required, catch_typeerror] - classes = { - 'session' : None, - 'host' : valid_host, - 'host_cpu': valid_host_cpu, - 'network' : valid_network, - 'VM' : valid_vm, - 'VBD' : valid_vbd, - 'VIF' : valid_vif, - 'VDI' : valid_vdi, - 'VTPM' : valid_vtpm, - 'SR' : valid_sr, - 'PIF' : valid_pif, - 'task' : valid_task, - } - - # Cheat methods - # ------------- - # Methods that have a trivial implementation for all classes. - # 1. get_by_uuid == getting by ref, so just return uuid for - # all get_by_uuid() methods. - - for cls in classes.keys(): - get_by_uuid = '%s_get_by_uuid' % cls - get_uuid = '%s_get_uuid' % cls - def _get_by_uuid(_1, _2, ref): - return xen_api_success(ref) - - def _get_uuid(_1, _2, ref): - return xen_api_success(ref) - - setattr(XendAPI, get_by_uuid, _get_by_uuid) - setattr(XendAPI, get_uuid, _get_uuid) - - # Wrapping validators around XMLRPC calls - # --------------------------------------- - - for cls, validator in classes.items(): - def doit(n, takes_instance, async_support = False, return_type = None): - n_ = n.replace('.', '_') - try: - f = getattr(XendAPI, n_) - argcounts[n] = f.func_code.co_argcount - 1 - - validators = takes_instance and validator and [validator] \ - or [] - validators += global_validators - for v in validators: - f = v(f) - f.api = n - f.async = async_support - if return_type: - f.return_type = return_type - - setattr(XendAPI, n_, f) - except AttributeError: - log.warn("API call: %s not found" % n) - - - ro_attrs = getattr(XendAPI, '%s_attr_ro' % cls, []) - rw_attrs = getattr(XendAPI, '%s_attr_rw' % cls, []) - methods = getattr(XendAPI, '%s_methods' % cls, []) - funcs = getattr(XendAPI, '%s_funcs' % cls, []) - - # wrap validators around readable class attributes - for attr_name in ro_attrs + rw_attrs + XendAPI.Base_attr_ro: - doit('%s.get_%s' % (cls, attr_name), True, async_support = False) - - # wrap validators around writable class attrributes - for attr_name in rw_attrs + XendAPI.Base_attr_rw: - doit('%s.set_%s' % (cls, attr_name), True, async_support = False) - - # wrap validators around methods - for method_name, return_type in methods + XendAPI.Base_methods: - doit('%s.%s' % (cls, method_name), True, async_support = True) - - # wrap validators around class functions - for func_name, return_type in funcs + XendAPI.Base_funcs: - doit('%s.%s' % (cls, func_name), False, async_support = True, - return_type = return_type) - - -_decorate() - - # # Auto generate some stubs based on XendAPI introspection # _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |