Преглед изворни кода

Code succession readability

almahmoud пре 7 година
родитељ
комит
b03789ff34

+ 36 - 21
cloudbridge/cloud/base/provider.py

@@ -80,11 +80,15 @@ class BaseConfiguration(Configuration):
         """
         """
         return self.get('cb_debug', os.environ.get('CB_DEBUG', False))
         return self.get('cb_debug', os.environ.get('CB_DEBUG', False))
 
 
+
 class EventDispatcher(object):
 class EventDispatcher(object):
     def __init__(self):
     def __init__(self):
         self.__events = {}
         self.__events = {}
 
 
-    def subscribe(self, event_name, priority, callback, result_callback=None):
+    def get_handlers(self, event_name):
+        return self.__events.get(event_name)
+
+    def subscribe(self, event_name, priority, callback, result_callback=False):
         """
         """
         Subscribe a handler by event name to the dispatcher.
         Subscribe a handler by event name to the dispatcher.
 
 
@@ -98,24 +102,32 @@ class EventDispatcher(object):
         :type callback: function
         :type callback: function
         :param callback: The callback function that should be called with
         :param callback: The callback function that should be called with
         the parameters given at when the even is emitted.
         the parameters given at when the even is emitted.
-        :type result_callback: function
-        :param result_callback: The callback function that should be called
-        after the first callback function, using the return value of that
-        previous function as an argument. This function should accept a
-        `callback_result` parameter in addition to the parameters of the event.
-        :return:  The last return value that is not None from the callback
-        functions. i.e. It will return the `callback` function return value,
-        unless the `result_callback` function has a return value.
+        :type result_callback: bool
+        :param result_callback: Whether the callback function should be using
+        the last return value from previous functions as an argument. This
+        function should accept a `callback_result` parameter in addition to
+        the parameters of the event.
         """
         """
         if result_callback:
         if result_callback:
-            handler = EventHandler(HandlerType.INTERCEPTION, callback, result_callback)
+            handler = EventHandler(HandlerType.RESULT_SUBSCRIPTION, callback)
         else:
         else:
             handler = EventHandler(HandlerType.SUBSCRIPTION, callback)
             handler = EventHandler(HandlerType.SUBSCRIPTION, callback)
         if not self.__events.get(event_name):
         if not self.__events.get(event_name):
             self.__events[event_name] = list()
             self.__events[event_name] = list()
         self.__events[event_name].append((priority, handler))
         self.__events[event_name].append((priority, handler))
 
 
-    def emit(self, event_name, **kwargs):
+    def interceptable_call(self, event_name, priority, callback, **kwargs):
+        handler = EventHandler(HandlerType.SUBSCRIPTION, callback)
+        if not self.__events.get(event_name):
+            self.__events[event_name] = list()
+        self.__events[event_name].append((priority, handler))
+        try:
+            ret_obj = self._emit(event_name, **kwargs)
+        finally:
+            self.__events[event_name].remove((priority, handler))
+        return ret_obj
+
+    def _emit(self, event_name, **kwargs):
 
 
         def priority_sort(handler_list):
         def priority_sort(handler_list):
             handler_list.sort(key=lambda x: x[0])
             handler_list.sort(key=lambda x: x[0])
@@ -128,9 +140,15 @@ class EventDispatcher(object):
 
 
         result = None
         result = None
         for (priority, handler) in priority_sort(self.__events[event_name]):
         for (priority, handler) in priority_sort(self.__events[event_name]):
-            new_result = handler.invoke(kwargs)
-            if new_result:
-                result = new_result
+            if handler.handler_type == HandlerType.RESULT_SUBSCRIPTION:
+                kwargs['callback_result'] = result
+                new_result = handler.invoke(kwargs)
+                if new_result:
+                    result = new_result
+            else:
+                new_result = handler.invoke(kwargs)
+                if new_result:
+                    result = new_result
         return result
         return result
 
 
 
 
@@ -139,16 +157,13 @@ class EventHandler(object):
         self.handler_type = handler_type
         self.handler_type = handler_type
         self.callback = callback
         self.callback = callback
         self.result_callback = result_callback
         self.result_callback = result_callback
+        self._next_handler = None
 
 
     def invoke(self, args):
     def invoke(self, args):
-        if self.handler_type == HandlerType.SUBSCRIPTION:
+        if self.handler_type in [HandlerType.SUBSCRIPTION,
+                                 HandlerType.RESULT_SUBSCRIPTION]:
             return self.callback(**args)
             return self.callback(**args)
-        if self.handler_type == HandlerType.INTERCEPTION:
-            result = self.callback(**args)
-            new_result = self.result_callback(result=result, **args)
-            if new_result:
-                result = new_result
-            return result
+
 
 
 
 
 class BaseCloudProvider(CloudProvider):
 class BaseCloudProvider(CloudProvider):

+ 81 - 61
cloudbridge/cloud/base/services.py

@@ -108,28 +108,25 @@ class BaseBucketService(
     def __init__(self, provider):
     def __init__(self, provider):
         super(BaseBucketService, self).__init__(provider)
         super(BaseBucketService, self).__init__(provider)
         self._service_event_name = "provider.storage.buckets"
         self._service_event_name = "provider.storage.buckets"
-        self._init_get()
-        self._init_find()
-        self._init_list()
-        self._init_create()
 
 
     def get_event_name(self, func_name):
     def get_event_name(self, func_name):
         return ".".join((self._service_event_name, func_name))
         return ".".join((self._service_event_name, func_name))
 
 
-    def _get_pre_log(self, bucket_id):
-        log.debug("Getting {} bucket with the id: {}".format(
-            self.provider.name, bucket_id))
-
-    def _get_post_log(self, result, bucket_id):
-        log.debug("Returned bucket object: {}".format(result))
-
     def _init_get(self):
     def _init_get(self):
         event_name = self.get_event_name("get")
         event_name = self.get_event_name("get")
+
+        def _get_pre_log(bucket_id):
+            log.debug("Getting {} bucket with the id: {}".format(
+                self.provider.name, bucket_id))
+
+        def _get_post_log(callback_result, bucket_id):
+            log.debug("Returned bucket object: {}".format(callback_result))
+
         self.provider.events.subscribe(event_name, 20000,
         self.provider.events.subscribe(event_name, 20000,
-                                       self._get_pre_log)
-        self.provider.events.subscribe(event_name, 20500,
-                                       self._get,
-                                       self._get_post_log)
+                                       _get_pre_log)
+        self.provider.events.subscribe(event_name, 21000,
+                                       _get_post_log,
+                                       result_callback=True)
 
 
     def get(self, bucket_id):
     def get(self, bucket_id):
         """
         """
@@ -137,22 +134,28 @@ class BaseBucketService(
         does not exist.
         does not exist.
         """
         """
         event_name = self.get_event_name("get")
         event_name = self.get_event_name("get")
-        return self.provider.events.emit(event_name, bucket_id=bucket_id)
-
-    def _find_pre_log(self, **kwargs):
-        log.debug("Finding {} buckets with the following arguments: {}"
-                  .format(self.provider.name, kwargs))
-
-    def _find_post_log(self, result, **kwargs):
-        log.debug("Returned bucket objects: {}".format(result))
+        if not self.provider.events.get_handlers(event_name):
+            self._init_get()
+        return self.provider.events.interceptable_call(event_name,
+                                                       priority=20500,
+                                                       callback=self._get,
+                                                       bucket_id=bucket_id)
 
 
     def _init_find(self):
     def _init_find(self):
         event_name = self.get_event_name("find")
         event_name = self.get_event_name("find")
+
+        def _find_pre_log(**kwargs):
+            log.debug("Finding {} buckets with the following arguments: {}"
+                      .format(self.provider.name, kwargs))
+
+        def _find_post_log(callback_result, **kwargs):
+            log.debug("Returned bucket objects: {}".format(callback_result))
+
         self.provider.events.subscribe(event_name, 20000,
         self.provider.events.subscribe(event_name, 20000,
-                                       self._find_pre_log)
-        self.provider.events.subscribe(event_name, 20500,
-                                       self._find,
-                                       self._find_post_log)
+                                       _find_pre_log)
+        self.provider.events.subscribe(event_name, 21000,
+                                       _find_post_log,
+                                       result_callback=True)
 
 
     # Generic find will be used for providers where we have not implemented
     # Generic find will be used for providers where we have not implemented
     # provider-specific querying for find method
     # provider-specific querying for find method
@@ -175,62 +178,79 @@ class BaseBucketService(
         Returns a list of buckets filtered by the given keyword arguments.
         Returns a list of buckets filtered by the given keyword arguments.
         """
         """
         event_name = self.get_event_name("find")
         event_name = self.get_event_name("find")
-        return self.provider.events.emit(event_name, **kwargs)
-
-    def _list_pre_log(self, limit, marker):
-        message = "Listing {} buckets".format(self.provider.name)
-        if limit:
-            message += " with limit: {}".format(limit)
-        if marker:
-            message += " with marker: {}".format(marker)
-        log.debug(message)
-
-    def _list_post_log(self, result, limit, marker):
-        log.debug("Returned bucket objects: {}".format(result))
+        if not self.provider.events.get_handlers(event_name):
+            self._init_find()
+        return self.provider.events.interceptable_call(event_name,
+                                                       priority=20500,
+                                                       callback=self._find,
+                                                       **kwargs)
 
 
     def _init_list(self):
     def _init_list(self):
         event_name = self.get_event_name("list")
         event_name = self.get_event_name("list")
+
+        def _list_pre_log(limit, marker):
+            message = "Listing {} buckets".format(self.provider.name)
+            if limit:
+                message += " with limit: {}".format(limit)
+            if marker:
+                message += " with marker: {}".format(marker)
+            log.debug(message)
+
+        def _list_post_log(callback_result, limit, marker):
+            log.debug("Returned bucket objects: {}".format(callback_result))
+
         self.provider.events.subscribe(event_name, 20000,
         self.provider.events.subscribe(event_name, 20000,
-                                       self._list_pre_log)
-        self.provider.events.subscribe(event_name, 20500,
-                                       self._list,
-                                       self._list_post_log)
+                                       _list_pre_log)
+        self.provider.events.subscribe(event_name, 21000,
+                                       _list_post_log,
+                                       result_callback=True)
 
 
     def list(self, limit=None, marker=None):
     def list(self, limit=None, marker=None):
         """
         """
         List all buckets.
         List all buckets.
         """
         """
         event_name = self.get_event_name("list")
         event_name = self.get_event_name("list")
-        return self.provider.events.emit(event_name, limit=limit,
-                                         marker=marker)
-
-    def _create_pre_log(self, name, location):
-        message = "Creating {} bucket with name {}".format(
-            self.provider.name, name)
-        if location:
-            message += " in location: {}".format(location)
-        log.debug(message)
-
-    def _create_post_log(self, result, name, location):
-        log.debug("Returned bucket object: {}".format(result))
+        if not self.provider.events.get_handlers(event_name):
+            self._init_list()
+        return self.provider.events.interceptable_call(event_name,
+                                                       priority=20500,
+                                                       callback=self._list,
+                                                       limit=limit,
+                                                       marker=marker)
 
 
     def _init_create(self):
     def _init_create(self):
         event_name = self.get_event_name("create")
         event_name = self.get_event_name("create")
+
+        def _create_pre_log(name, location):
+            message = "Creating {} bucket with name '{}'".format(
+                self.provider.name, name)
+            if location:
+                message += " in location: {}".format(location)
+            log.debug(message)
+
+        def _create_post_log(callback_result, name, location):
+            log.debug("Returned bucket object: {}".format(callback_result))
+
         self.provider.events.subscribe(event_name, 20000,
         self.provider.events.subscribe(event_name, 20000,
-                                       self._create_pre_log)
-        self.provider.events.subscribe(event_name, 20500,
-                                       self._create,
-                                       self._create_post_log)
+                                       _create_pre_log)
+        self.provider.events.subscribe(event_name, 21000,
+                                       _create_post_log,
+                                       result_callback=True)
 
 
     def create(self, name, location=None):
     def create(self, name, location=None):
         """
         """
         Create a new bucket.
         Create a new bucket.
         """
         """
         event_name = self.get_event_name("create")
         event_name = self.get_event_name("create")
+        if not self.provider.events.get_handlers(event_name):
+            self._init_create()
         BaseBucket.assert_valid_resource_name(name)
         BaseBucket.assert_valid_resource_name(name)
         location = location or self.provider.region_name
         location = location or self.provider.region_name
-        return self.provider.events.emit(event_name, name=name,
-                                         location=location)
+        return self.provider.events.interceptable_call(event_name,
+                                                       priority=20500,
+                                                       callback=self._create,
+                                                       name=name,
+                                                       location=location)
 
 
 
 
 class BaseComputeService(ComputeService, BaseCloudService):
 class BaseComputeService(ComputeService, BaseCloudService):

+ 1 - 1
cloudbridge/cloud/interfaces/provider.py

@@ -253,4 +253,4 @@ class HandlerType(Enum):
     Handler Types.
     Handler Types.
     """
     """
     SUBSCRIPTION = 'subscription'
     SUBSCRIPTION = 'subscription'
-    INTERCEPTION = 'interception'
+    RESULT_SUBSCRIPTION = 'result_subscription'