예제 #1
0
def _multi_send(method,
                context,
                topic,
                msg,
                timeout=None,
                envelope=False,
                _msg_id=None):
    """Wraps the sending of messages.

    Dispatches to the matchmaker and sends message to all relevant hosts.
    """
    conf = CONF
    LOG.debug(_("%(msg)s") % {'msg': ' '.join(map(pformat, (topic, msg)))})

    queues = _get_matchmaker().queues(topic)
    LOG.debug(_("Sending message(s) to: %s"), queues)

    # Don't stack if we have no matchmaker results
    if not queues:
        LOG.warn(_("No matchmaker results. Not casting."))
        # While not strictly a timeout, callers know how to handle
        # this exception and a timeout isn't too big a lie.
        raise rpc_common.Timeout(_("No match from matchmaker."))

    # This supports brokerless fanout (addresses > 1)
    for queue in queues:
        (_topic, ip_addr) = queue
        _addr = "tcp://%s:%s" % (ip_addr, conf.rpc_zmq_port)

        if method.__name__ == '_cast':
            eventlet.spawn_n(method, _addr, context, _topic, msg, timeout,
                             envelope, _msg_id)
            return
        return method(_addr, context, _topic, msg, timeout, envelope)
예제 #2
0
 def _error_callback(exc):
     if isinstance(exc, qpid_exceptions.Empty):
         LOG.debug(_('Timed out waiting for RPC response: %s') %
                   str(exc))
         raise rpc_common.Timeout()
     else:
         LOG.exception(_('Failed to consume message from queue: %s') %
                       str(exc))
예제 #3
0
 def _error_callback(exc):
     if isinstance(exc, socket.timeout):
         LOG.debug(
             _('Timed out waiting for RPC response: %s') % str(exc))
         raise rpc_common.Timeout()
     else:
         LOG.exception(
             _('Failed to consume message from queue: %s') % str(exc))
         info['do_consume'] = True
예제 #4
0
def multicall(conf, context, topic, msg, timeout=None):
    """Make a call that returns multiple times."""

    check_serialize(msg)

    method = msg.get('method')
    if not method:
        return
    args = msg.get('args', {})
    version = msg.get('version', None)
    namespace = msg.get('namespace', None)

    try:
        consumer = CONSUMERS[topic][0]
    except (KeyError, IndexError):
        raise rpc_common.Timeout("No consumers available")
    else:
        return consumer.call(context, version, method, namespace, args,
                             timeout)
예제 #5
0
 def __iter__(self):
     """Return a result until we get a reply with an 'ending' flag."""
     if self._done:
         raise StopIteration
     while True:
         try:
             data = self._dataqueue.get(timeout=self._timeout)
             result = self._process_data(data)
         except queue.Empty:
             self.done()
             raise rpc_common.Timeout()
         except Exception:
             with excutils.save_and_reraise_exception():
                 self.done()
         if self._got_ending:
             self.done()
             raise StopIteration
         if isinstance(result, Exception):
             self.done()
             raise result
         yield result
예제 #6
0
    def call(self, context, version, method, namespace, args, timeout):
        done = eventlet.event.Event()

        def _inner():
            ctxt = RpcContext.from_dict(context.to_dict())
            try:
                rval = self.proxy.dispatch(context, version, method, namespace,
                                           **args)
                res = []
                # Caller might have called ctxt.reply() manually
                for (reply, failure) in ctxt._response:
                    if failure:
                        raise failure[0], failure[1], failure[2]
                    res.append(reply)
                # if ending not 'sent'...we might have more data to
                # return from the function itself
                if not ctxt._done:
                    if inspect.isgenerator(rval):
                        for val in rval:
                            res.append(val)
                    else:
                        res.append(rval)
                done.send(res)
            except rpc_common.ClientException as e:
                done.send_exception(e._exc_info[1])
            except Exception as e:
                done.send_exception(e)

        thread = eventlet.greenthread.spawn(_inner)

        if timeout:
            start_time = time.time()
            while not done.ready():
                eventlet.greenthread.sleep(1)
                cur_time = time.time()
                if (cur_time - start_time) > timeout:
                    thread.kill()
                    raise rpc_common.Timeout()

        return done.wait()