WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [XEND] Move decorate() to XendAPI.__new__

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [XEND] Move decorate() to XendAPI.__new__ and have a static flag to
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 25 Jan 2007 08:55:32 -0800
Delivery-date: Thu, 25 Jan 2007 09:50:56 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [XEND] Move decorate() to XendAPI.__new__ and have a static flag to, Xen patchbot-unstable <=