Example #1
0
 def _acquire_method_lock(self, method, this):
     method_id = id(method)
     if method.is_static:
         this_id = id(method.declaring_type)
     else:
         this_id = this.object_id
     thread_id = helpers.get_current_thread_id()
     while True:
         event, event_owner = self._locks.get((method_id, this_id),
                                              (None, None))
         if event:
             if event_owner == thread_id:
                 event = None
                 break
             else:
                 event.wait()
         else:
             event = eventlet.event.Event()
             self._locks[(method_id, this_id)] = (event, thread_id)
             break
     try:
         yield
     finally:
         if event is not None:
             del self._locks[(method_id, this_id)]
             event.send()
Example #2
0
 def _acquire_method_lock(self, method, this):
     method_id = id(method)
     if method.is_static:
         this_id = id(method.declaring_type)
     else:
         this_id = this.object_id
     thread_id = helpers.get_current_thread_id()
     while True:
         event, event_owner = self._locks.get(
             (method_id, this_id), (None, None))
         if event:
             if event_owner == thread_id:
                 event = None
                 break
             else:
                 event.wait()
         else:
             event = eventlet.event.Event()
             self._locks[(method_id, this_id)] = (event, thread_id)
             break
     try:
         yield
     finally:
         if event is not None:
             del self._locks[(method_id, this_id)]
             event.send()
Example #3
0
    def _invoke_method_implementation(self, method, this, murano_class,
                                      context, params):
        body = method.body
        if not body:
            return None

        current_thread = eventlet.greenthread.getcurrent()
        if not hasattr(current_thread, '_murano_dsl_thread_marker'):
            thread_marker = current_thread._murano_dsl_thread_marker = \
                uuid.uuid4().hex
        else:
            thread_marker = current_thread._murano_dsl_thread_marker

        method_id = id(body)
        this_id = this.object_id

        event, marker = self._locks.get((method_id, this_id), (None, None))
        if event:
            if marker == thread_marker:
                return self._invoke_method_implementation_gt(
                    body, this, params, murano_class, context)
            event.wait()

        event = eventlet.event.Event()
        self._locks[(method_id, this_id)] = (event, thread_marker)
        gt = eventlet.spawn(self._invoke_method_implementation_gt, body, this,
                            params, murano_class, context, thread_marker)
        result = gt.wait()
        del self._locks[(method_id, this_id)]
        event.send()
        return result
Example #4
0
 def _acquire_method_lock(self, func, this):
     method_id = id(func)
     if isinstance(this, dsl_types.MuranoClass):
         this_id = id(this)
     else:
         this_id = this.object_id
     thread_id = helpers.get_current_thread_id()
     while True:
         event, event_owner = self._locks.get(
             (method_id, this_id), (None, None))
         if event:
             if event_owner == thread_id:
                 event = None
                 break
             else:
                 event.wait()
         else:
             event = eventlet.event.Event()
             self._locks[(method_id, this_id)] = (event, thread_id)
             break
     try:
         yield
     finally:
         if event is not None:
             del self._locks[(method_id, this_id)]
             event.send()
Example #5
0
    def _invoke_method_implementation(self, method, this, murano_class, context, params):
        body = method.body
        if not body:
            return None

        current_thread = eventlet.greenthread.getcurrent()
        if not hasattr(current_thread, "_murano_dsl_thread_marker"):
            thread_marker = current_thread._murano_dsl_thread_marker = uuid.uuid4().hex
        else:
            thread_marker = current_thread._murano_dsl_thread_marker

        method_id = id(body)
        this_id = this.object_id

        event, marker = self._locks.get((method_id, this_id), (None, None))
        if event:
            if marker == thread_marker:
                return self._invoke_method_implementation_gt(body, this, params, murano_class, context)
            event.wait()

        event = eventlet.event.Event()
        self._locks[(method_id, this_id)] = (event, thread_marker)
        gt = eventlet.spawn(
            self._invoke_method_implementation_gt, body, this, params, murano_class, context, thread_marker
        )
        result = gt.wait()
        del self._locks[(method_id, this_id)]
        event.send()
        return result
Example #6
0
    def _invoke_method_implementation(self, method, this, context, params):
        body = method.body
        if not body:
            return None

        murano_class = method.murano_class
        current_thread = eventlet.greenthread.getcurrent()
        if not hasattr(current_thread, '_muranopl_thread_marker'):
            thread_marker = current_thread._muranopl_thread_marker = \
                uuid.uuid4().hex
        else:
            thread_marker = current_thread._muranopl_thread_marker

        method_id = id(body)
        this_id = this.object_id

        while True:
            event, marker = self._locks.get((method_id, this_id), (None, None))
            if event:
                if marker == thread_marker:
                    return self._invoke_method_implementation_gt(
                        body, this, params, murano_class, context)
                event.wait()
            else:
                break

        event = eventlet.event.Event()
        self._locks[(method_id, this_id)] = (event, thread_marker)
        # noinspection PyProtectedMember
        method_info = '{0}.{1} ({2})'.format(murano_class.name, method._name,
                                             hash((method_id, this_id)))
        # Prepare caller information
        caller_ctx = helpers.get_caller_context(context)
        if caller_ctx:
            caller_info = trace.compose_stack_frame(caller_ctx)
            LOG.debug('{0}: Begin execution: {1} called from {2}'.format(
                thread_marker, method_info, trace.format_frame(caller_info)))
        else:
            LOG.debug('{0}: Begin execution: {1}'.format(
                thread_marker, method_info))

        try:
            gt = eventlet.spawn(self._invoke_method_implementation_gt, body,
                                this, params, murano_class, context,
                                thread_marker)
            result = gt.wait()
        except Exception as e:
            LOG.debug("{0}: End execution: {1} with exception {2}".format(
                thread_marker, method_info, e))
            raise
        else:
            LOG.debug("{0}: End execution: {1}".format(thread_marker,
                                                       method_info))
        finally:
            del self._locks[(method_id, this_id)]
            event.send()

        return result
Example #7
0
    def _invoke_method_implementation(self, method, this, context, params):
        body = method.body
        if not body:
            return None

        murano_class = method.murano_class
        current_thread = eventlet.greenthread.getcurrent()
        if not hasattr(current_thread, '_muranopl_thread_marker'):
            thread_marker = current_thread._muranopl_thread_marker = \
                uuid.uuid4().hex
        else:
            thread_marker = current_thread._muranopl_thread_marker

        method_id = id(body)
        this_id = this.object_id

        while True:
            event, marker = self._locks.get((method_id, this_id), (None, None))
            if event:
                if marker == thread_marker:
                    return self._invoke_method_implementation_gt(
                        body, this, params, murano_class, context)
                event.wait()
            else:
                break

        event = eventlet.event.Event()
        self._locks[(method_id, this_id)] = (event, thread_marker)
        # noinspection PyProtectedMember
        method_info = '{0}.{1} ({2})'.format(murano_class.name, method._name,
                                             hash((method_id, this_id)))
        # Prepare caller information
        caller_ctx = helpers.get_caller_context(context)
        if caller_ctx:
            caller_info = trace.compose_stack_frame(caller_ctx)
            LOG.debug(
                '{0}: Begin execution: {1} called from {2}'.format(
                    thread_marker, method_info, trace.format_frame(
                        caller_info)))
        else:
            LOG.debug(
                '{0}: Begin execution: {1}'.format(
                    thread_marker, method_info))

        gt = eventlet.spawn(self._invoke_method_implementation_gt, body,
                            this, params, murano_class, context,
                            thread_marker)
        result = gt.wait()
        del self._locks[(method_id, this_id)]
        LOG.debug(
            "{0}: End execution: {1}".format(thread_marker, method_info))
        event.send()
        return result
Example #8
0
    def _send(self, template, wait_results, timeout):
        """Send a message over the MQ interface."""
        msg_id = template.get('ID', uuid.uuid4().hex)
        if wait_results:
            event = eventlet.event.Event()
            listener = self._environment['agentListener']
            listener().subscribe(msg_id, event)

        msg = self._prepare_message(template, msg_id)
        with common.create_rmq_client(self._environment) as client:
            client.send(message=msg, key=self._queue)

        if wait_results:
            try:
                with eventlet.Timeout(timeout):
                    result = event.wait()

            except eventlet.Timeout:
                listener().unsubscribe(msg_id)
                raise exceptions.TimeoutException(
                    'The murano-agent did not respond '
                    'within {0} seconds'.format(timeout))

            if not result:
                return None

            if result.get('FormatVersion', '1.0.0').startswith('1.'):
                return self._process_v1_result(result)

            else:
                return self._process_v2_result(result)

        else:
            return None
Example #9
0
    def _send(self, template, wait_results, timeout):
        """Send a message over the MQ interface."""
        msg_id = template.get('ID', uuid.uuid4().hex)
        if wait_results:
            event = eventlet.event.Event()
            listener = self._environment['agentListener']
            listener().subscribe(msg_id, event)

        msg = self._prepare_message(template, msg_id)
        with common.create_rmq_client() as client:
            client.send(message=msg, key=self._queue)

        if wait_results:
            try:
                with eventlet.Timeout(timeout):
                    result = event.wait()

            except eventlet.Timeout:
                listener().unsubscribe(msg_id)
                raise exceptions.TimeoutException(
                    'The murano-agent did not respond '
                    'within {0} seconds'.format(timeout))

            if not result:
                return None

            if result.get('FormatVersion', '1.0.0').startswith('1.'):
                return self._process_v1_result(result)

            else:
                return self._process_v2_result(result)

        else:
            return None
Example #10
0
    def _send(self, template, wait_results, timeout, _context):
        """Send a message over the MQ interface."""
        msg_id = template.get("ID", uuid.uuid4().hex)
        if wait_results:
            event = eventlet.event.Event()
            listener = self._environment.agentListener
            listener.subscribe(msg_id, event, _context)

        msg = self._prepare_message(template, msg_id)
        with common.create_rmq_client() as client:
            client.send(message=msg, key=self._queue)

        if wait_results:
            try:
                with eventlet.Timeout(timeout):
                    result = event.wait()

            except eventlet.Timeout:
                listener.unsubscribe(msg_id)
                raise exceptions.TimeoutException("The Agent does not respond" "within {0} seconds".format(timeout))

            if not result:
                return None

            if result.get("FormatVersion", "1.0.0").startswith("1."):
                return self._process_v1_result(result)

            else:
                return self._process_v2_result(result)

        else:
            return None
Example #11
0
    def _send(self, template, wait_results):

        msg_id = template.get('ID', uuid.uuid4().hex)
        if wait_results:
            event = eventlet.event.Event()
            listener = self._environment.agentListener
            listener.subscribe(msg_id, event)
            listener.start()

        msg = messaging.Message()
        msg.body = template
        msg.id = msg_id

        with common.create_rmq_client() as client:
            client.declare(self._queue, enable_ha=True, ttl=86400000)
            client.send(message=msg, key=self._queue)

        if wait_results:
            result = event.wait()

            if not result:
                return None

            if result.get('FormatVersion', '1.0.0').startswith('1.'):
                return self._process_v1_result(result)
            else:
                return self._process_v2_result(result)
        else:
            return None
Example #12
0
    def _send(self, template, wait_results):

        msg_id = template.get('ID', uuid.uuid4().hex)
        if wait_results:
            event = eventlet.event.Event()
            listener = self._environment.agentListener
            listener.subscribe(msg_id, event)
            listener.start()

        msg = messaging.Message()
        msg.body = template
        msg.id = msg_id

        with common.create_rmq_client() as client:
            client.declare(self._queue, enable_ha=True, ttl=86400000)
            client.send(message=msg, key=self._queue)

        if wait_results:
            result = event.wait()

            if not result:
                return None

            if result.get('FormatVersion', '1.0.0').startswith('1.'):
                return self._process_v1_result(result)
            else:
                return self._process_v2_result(result)
        else:
            return None
Example #13
0
    def wait_for_instance_event(self, instance, event_names, deadline=300,
                                error_callback=None):
        """Plan to wait for some events, run some code, then wait.

        This context manager will first create plans to wait for the
        provided event_names, yield, and then wait for all the scheduled
        events to complete.

        Note that this uses an eventlet.timeout.Timeout to bound the
        operation, so callers should be prepared to catch that
        failure and handle that situation appropriately.

        If the event is not received by the specified timeout deadline,
        eventlet.timeout.Timeout is raised.

        If the event is received but did not have a 'completed'
        status, a NovaException is raised.  If an error_callback is
        provided, instead of raising an exception as detailed above
        for the failure case, the callback will be called with the
        event_name and instance, and can return True to continue
        waiting for the rest of the events, False to stop processing,
        or raise an exception which will bubble up to the waiter.

        :param instance: The instance for which an event is expected
        :param event_names: A list of event names. Each element can be a
                            string event name or tuple of strings to
                            indicate (name, tag).
        :param deadline: Maximum number of seconds we should wait for all
                         of the specified events to arrive.
        :param error_callback: A function to be called if an event arrives

        """

        if error_callback is None:
            error_callback = self._default_error_callback
        events = {}
        for event_name in event_names:
            if isinstance(event_name, tuple):
                name, tag = event_name
                event_name = objects.InstanceExternalEvent.make_key(
                    name, tag)
            try:
                events[event_name] = (
                    self._compute.instance_events.prepare_for_instance_event(
                        instance, event_name))
            except exception.NovaException:
                error_callback(event_name, instance)
                # NOTE(danms): Don't wait for any of the events. They
                # should all be canceled and fired immediately below,
                # but don't stick around if not.
                deadline = 0
        yield
        with eventlet.timeout.Timeout(deadline):
            for event_name, event in events.items():
                actual_event = event.wait()
                if actual_event.status == 'completed':
                    continue
                decision = error_callback(event_name, instance)
                if decision is False:
                    break
Example #14
0
    def _acquire_method_lock(self, method, this, arg_val_dict):
        if this is None:
            if not arg_val_dict:
                # if neither "this" nor argument values are set then no
                # locking is needed
                key = None
            else:
                # if only the argument values are passed then find the lock
                # list only by the method
                key = (None, id(method))
        else:
            if method.is_static:
                # find the lock list by the type and method
                key = (id(method.declaring_type), id(method))
            else:
                # find the lock list by the object and method
                key = (this.object_id, id(method))
        thread_id = helpers.get_current_thread_id()
        while True:
            event, event_owner = None, None
            if key is None:  # no locking needed
                break

            lock_list = self._locks.setdefault(key, [])
            # lock list contains a list of tuples:
            # first item of each tuple is a dict with the values of locking
            # arguments (it is used for argument values comparison),
            # second item is an event to wait on,
            # third one is the owner thread id

            # If this lock list is empty it means no locks on this object and
            # method at all.
            for arg_vals, l_event, l_event_owner in lock_list:
                if arg_vals == arg_val_dict:
                    event = l_event
                    event_owner = l_event_owner
                    break

            if event:
                if event_owner == thread_id:
                    # this means a re-entrant lock: the tuple with the same
                    # value of the first element exists in the list, but it was
                    # acquired by the same green thread. We may proceed with
                    # the call in this case
                    event = None
                    break
                else:
                    event.wait()
            else:
                # this means either the lock list was empty or didn't contain a
                # tuple with the first element equal to arg_val_dict.
                # Then let's acquire a lock, i.e. create a new tuple and place
                # it into the list
                event = eventlet.event.Event()
                event_owner = thread_id
                lock_list.append((arg_val_dict, event, event_owner))
                break
        try:
            yield
        finally:
            if event is not None:
                lock_list.remove((arg_val_dict, event, event_owner))
                if len(lock_list) == 0:
                    del self._locks[key]
                event.send()
Example #15
0
    def _acquire_method_lock(self, method, this, arg_val_dict):
        if this is None:
            if not arg_val_dict:
                # if neither "this" nor argument values are set then no
                # locking is needed
                key = None
            else:
                # if only the argument values are passed then find the lock
                # list only by the method
                key = (None, id(method))
        else:
            if method.is_static:
                # find the lock list by the type and method
                key = (id(method.declaring_type), id(method))
            else:
                # find the lock list by the object and method
                key = (this.object_id, id(method))
        thread_id = helpers.get_current_thread_id()
        while True:
            event, event_owner = None, None
            if key is None:  # no locking needed
                break

            lock_list = self._locks.setdefault(key, [])
            # lock list contains a list of tuples:
            # first item of each tuple is a dict with the values of locking
            # arguments (it is used for argument values comparison),
            # second item is an event to wait on,
            # third one is the owner thread id

            # If this lock list is empty it means no locks on this object and
            # method at all.
            for arg_vals, l_event, l_event_owner in lock_list:
                if arg_vals == arg_val_dict:
                    event = l_event
                    event_owner = l_event_owner
                    break

            if event:
                if event_owner == thread_id:
                    # this means a re-entrant lock: the tuple with the same
                    # value of the first element exists in the list, but it was
                    # acquired by the same green thread. We may proceed with
                    # the call in this case
                    event = None
                    break
                else:
                    event.wait()
            else:
                # this means either the lock list was empty or didn't contain a
                # tuple with the first element equal to arg_val_dict.
                # Then let's acquire a lock, i.e. create a new tuple and place
                # it into the list
                event = eventlet.event.Event()
                event_owner = thread_id
                lock_list.append((arg_val_dict, event, event_owner))
                break
        try:
            yield
        finally:
            if event is not None:
                lock_list.remove((arg_val_dict, event, event_owner))
                if len(lock_list) == 0:
                    del self._locks[key]
                event.send()