[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.