示例#1
0
文件: channel.py 项目: swarbhanu/pyon
    def accept(self, n=1, timeout=None):
        """
        Accepts new connections for listening endpoints.

        Can accept more than one message at at time before it returns a new channel back to the
        caller. Optionally can specify a timeout - if n messages aren't received in that time,
        will raise an Empty exception.

        Sets the channel in the ACCEPTED state - caller is responsible for acking all messages
        received on the returned channel in order to put this channel back in the CONSUMING
        state.
        """

        assert self._fsm.current_state in [
            self.S_ACTIVE, self.S_CLOSED
        ], "Channel must be in active/closed state to accept, currently %s (forget to ack messages?)" % str(
            self._fsm.current_state)

        was_consuming = self._consuming

        if not self._should_discard and not was_consuming:
            # tune QOS to get exactly n messages
            if not (self._queue_auto_delete
                    and self._transport is AMQPTransport.get_instance()):
                self._transport.qos_impl(self._amq_chan, prefetch_count=n)

            # start consuming
            self.start_consume()

        with self._recv_queue.await_n(n=n) as ar:
            log.debug("accept: waiting for %s msgs, timeout=%s", n, timeout)
            ar.get(timeout=timeout)

        if not was_consuming:
            # turn consuming back off if we already were off
            if not (self._queue_auto_delete
                    and self._transport is AMQPTransport.get_instance()):
                self.stop_consume()
            else:
                log.debug(
                    "accept should turn consume off, but queue is auto_delete and this would destroy the queue"
                )

        ms = [self.recv() for x in xrange(n)]

        ch = self._create_accepted_channel(self._amq_chan, ms)
        map(ch._recv_queue.put, ms)

        # transition to ACCEPT
        self._fsm.process(self.I_ENTER_ACCEPT)

        # return the channel
        return ch
示例#2
0
文件: channel.py 项目: swarbhanu/pyon
    def __init__(self, transport=None, close_callback=None):
        """
        Initializes a BaseChannel instance.

        @param  transport       Underlying transport used for broker communication. Can be None, if so, will
                                use the AMQPTransport stateless singleton.
        @type   transport       BaseTransport
        @param  close_callback  The method to invoke when close() is called on this BaseChannel. May be left as None,
                                in which case close_impl() will be called. This expects to be a callable taking one
                                param, this channel instance.
        """
        self.set_close_callback(close_callback)
        self._transport = transport or AMQPTransport.get_instance()

        # setup FSM for BaseChannel / SendChannel tree
        self._fsm = FSM(self.S_INIT)
        self._fsm.add_transition(self.I_ATTACH, self.S_INIT, None,
                                 self.S_ACTIVE)
        self._fsm.add_transition(self.I_CLOSE, self.S_ACTIVE, self._on_close,
                                 self.S_CLOSED)
        self._fsm.add_transition(
            self.I_CLOSE, self.S_CLOSED, None, self.S_CLOSED
        )  # closed is a goal state, multiple closes are ok and are no-ops
        self._fsm.add_transition(self.I_CLOSE, self.S_INIT, None,
                                 self.S_CLOSED)  # INIT to CLOSED is fine too
示例#3
0
    def test_delete_xn(self):
        raise unittest.SkipTest("broken 2 mar, skipping for now")
        # same as the other deletes except with queues instead

        xn = self.container.ex_manager.create_xn_service('test_service')

        # prove queue is declared already (can't declare the same named one with diff params)
        ch = self.container.node.channel(RecvChannel)
        ch._queue_auto_delete = not xn._xn_auto_delete

        # must set recv_name
        ch._recv_name = xn
        self.assertRaises(TransportError, ch._declare_queue, xn.queue)

        # now let's delete via ex manager
        self.container.ex_manager.delete_xn(xn)

        # grab another channel and declare (should work fine this time)
        ch = self.container.node.channel(RecvChannel)
        ch._exchange_auto_delete = not xn._xs._xs_auto_delete

        # must set recv_name
        ch._recv_name = xn
        ch._declare_queue(xn.queue)

        # cool, now cleanup (we don't expose this via Channel)
        at = AMQPTransport.get_instance()
        at.delete_queue_impl(ch._amq_chan, xn.queue)
示例#4
0
    def test_delete_xn(self):
        raise unittest.SkipTest("broken 2 mar, skipping for now")
        # same as the other deletes except with queues instead

        xn = self.container.ex_manager.create_xn_service('test_service')

        # prove queue is declared already (can't declare the same named one with diff params)
        ch = self.container.node.channel(RecvChannel)
        ch._queue_auto_delete = not xn._xn_auto_delete

        # must set recv_name
        ch._recv_name = xn
        self.assertRaises(TransportError, ch._declare_queue, xn.queue)

        # now let's delete via ex manager
        self.container.ex_manager.delete_xn(xn)

        # grab another channel and declare (should work fine this time)
        ch = self.container.node.channel(RecvChannel)
        ch._exchange_auto_delete = not xn._xs._xs_auto_delete

        # must set recv_name
        ch._recv_name = xn
        ch._declare_queue(xn.queue)

        # cool, now cleanup (we don't expose this via Channel)
        at = AMQPTransport.get_instance()
        at.delete_queue_impl(ch._amq_chan, xn.queue)
示例#5
0
文件: channel.py 项目: swarbhanu/pyon
    def close_impl(self):
        if not self._queue_auto_delete and self._recv_name and self._transport is AMQPTransport.get_instance(
        ) and self._recv_name.queue.startswith("amq.gen-"):
            log.debug("Anonymous Subscriber detected, deleting queue (%s)",
                      self._recv_name)
            self._destroy_queue()

        ListenChannel.close_impl(self)
示例#6
0
文件: channel.py 项目: swarbhanu/pyon
    def accept(self, n=1, timeout=None):
        """
        Accepts new connections for listening endpoints.

        Can accept more than one message at at time before it returns a new channel back to the
        caller. Optionally can specify a timeout - if n messages aren't received in that time,
        will raise an Empty exception.

        Sets the channel in the ACCEPTED state - caller is responsible for acking all messages
        received on the returned channel in order to put this channel back in the CONSUMING
        state.
        """

        assert self._fsm.current_state in [self.S_ACTIVE, self.S_CLOSED], "Channel must be in active/closed state to accept, currently %s (forget to ack messages?)" % str(self._fsm.current_state)

        was_consuming = self._consuming

        if not self._should_discard and not was_consuming:
            # tune QOS to get exactly n messages
            if not (self._queue_auto_delete and self._transport is AMQPTransport.get_instance()):
                self._transport.qos_impl(self._amq_chan, prefetch_count=n)

            # start consuming
            self.start_consume()

        with self._recv_queue.await_n(n=n) as ar:
            log.debug("accept: waiting for %s msgs, timeout=%s", n, timeout)
            ar.get(timeout=timeout)

        if not was_consuming:
            # turn consuming back off if we already were off
            if not (self._queue_auto_delete and self._transport is AMQPTransport.get_instance()):
                self.stop_consume()
            else:
                log.debug("accept should turn consume off, but queue is auto_delete and this would destroy the queue")

        ms = [self.recv() for x in xrange(n)]

        ch = self._create_accepted_channel(self._amq_chan, ms)
        map(ch._recv_queue.put, ms)

        # transition to ACCEPT
        self._fsm.process(self.I_ENTER_ACCEPT)

        # return the channel
        return ch
示例#7
0
    def start(self):
        log.debug("ExchangeManager.start")

        total_count = 0

        def handle_failure(name, node):
            log.warn("Node %s could not be started", name)
            node.ready.set()        # let it fall out below

        # Establish connection(s) to broker
        for name, cfgkey in CFG.container.messaging.server.iteritems():
            if not cfgkey:
                continue

            if cfgkey not in CFG.server:
                raise ExchangeManagerError("Config key %s (name: %s) (from CFG.container.messaging.server) not in CFG.server" % (cfgkey, name))

            total_count += 1
            log.debug("Starting connection: %s", name)

            # start it with a zero timeout so it comes right back to us
            try:
                node, ioloop = messaging.make_node(CFG.server[cfgkey], name, 0)

                # install a finished handler directly on the ioloop just for this startup period
                fail_handle = lambda _: handle_failure(name, node)
                ioloop.link(fail_handle)

                # wait for the node ready event, with a large timeout just in case
                node_ready = node.ready.wait(timeout=15)

                # remove the finished handler, we don't care about it here
                ioloop.unlink(fail_handle)

                # only add to our list if we started successfully
                if not node.running:
                    ioloop.kill()      # make sure ioloop dead
                else:
                    self._nodes[name]   = node
                    self._ioloops[name] = ioloop

            except socket.error as e:
                log.warn("Could not start connection %s due to socket error, continuing", name)

        fail_count = total_count - len(self._nodes)
        if fail_count > 0 or total_count == 0:
            if fail_count == total_count:
                raise ExchangeManagerError("No node connection was able to start (%d nodes attempted, %d nodes failed)" % (total_count, fail_count))

            log.warn("Some nodes could not be started, ignoring for now")   # @TODO change when ready

        self._transport = AMQPTransport.get_instance()

        # load interceptors into each
        map(lambda x: x.setup_interceptors(CFG.interceptor), self._nodes.itervalues())

        log.debug("Started %d connections (%s)", len(self._nodes), ",".join(self._nodes.iterkeys()))
示例#8
0
文件: channel.py 项目: tgiguere/pyon
    def __init__(self, transport=None, close_callback=None):
        """
        Initializes a BaseChannel instance.

        @param  transport       Underlying transport used for broker communication. Can be None, if so, will
                                use the AMQPTransport stateless singleton.
        @type   transport       BaseTransport
        @param  close_callback  The method to invoke when close() is called on this BaseChannel. May be left as None,
                                in which case close_impl() will be called. This expects to be a callable taking one
                                param, this channel instance.
        """
        self.set_close_callback(close_callback)
        self._transport = transport or AMQPTransport.get_instance()
示例#9
0
文件: exchange.py 项目: ooici-dm/pyon
    def start(self):
        log.debug("ExchangeManager starting ...")

        # Establish connection to broker
        # @TODO: raise error if sux
        node, ioloop = messaging.make_node()

        self._transport = AMQPTransport.get_instance()
        self._client    = self._get_channel(node)

        # Declare root exchange
        #self.default_xs.ensure_exists(self._get_channel())
        return node, ioloop
示例#10
0
文件: exchange.py 项目: ooici-dm/pyon
    def start(self):
        log.debug("ExchangeManager starting ...")

        # Establish connection to broker
        # @TODO: raise error if sux
        node, ioloop = messaging.make_node()

        self._transport = AMQPTransport.get_instance()
        self._client = self._get_channel(node)

        # Declare root exchange
        #self.default_xs.ensure_exists(self._get_channel())
        return node, ioloop
示例#11
0
文件: channel.py 项目: swarbhanu/pyon
    def _on_stop_consume(self):
        """
        Stops consuming messages.

        If the queue has auto_delete, this will delete it.
        """
        #log.debug("RecvChannel._on_stop_consume")

        if self._queue_auto_delete and self._transport is AMQPTransport.get_instance():
            log.debug("Autodelete is on, this will destroy this queue: %s", self._recv_name.queue)

        self._ensure_amq_chan()

        self._sync_call(self._amq_chan.basic_cancel, 'callback', self._consumer_tag)
示例#12
0
文件: channel.py 项目: swarbhanu/pyon
    def _on_stop_consume(self):
        """
        Stops consuming messages.

        If the queue has auto_delete, this will delete it.
        """
        #log.debug("RecvChannel._on_stop_consume")

        if self._queue_auto_delete and self._transport is AMQPTransport.get_instance(
        ):
            log.debug("Autodelete is on, this will destroy this queue: %s",
                      self._recv_name.queue)

        self._ensure_amq_chan()

        self._sync_call(self._amq_chan.basic_cancel, 'callback',
                        self._consumer_tag)
示例#13
0
文件: channel.py 项目: swarbhanu/pyon
    def _on_start_consume(self):
        """
        Starts consuming messages.

        setup_listener must have been called first.
        """
        #log.debug("RecvChannel._on_start_consume")

        if self._consumer_tag and (self._queue_auto_delete and self._transport is AMQPTransport.get_instance()):
            log.warn("Attempting to start consuming on a queue that may have been auto-deleted")

        self._ensure_amq_chan()

        self._consumer_tag = self._amq_chan.basic_consume(self._on_deliver,
                                                          queue=self._recv_name.queue,
                                                          no_ack=self._consumer_no_ack,
                                                          exclusive=self._consumer_exclusive)
示例#14
0
文件: channel.py 项目: swarbhanu/pyon
    def __init__(self, transport=None, close_callback=None):
        """
        Initializes a BaseChannel instance.

        @param  transport       Underlying transport used for broker communication. Can be None, if so, will
                                use the AMQPTransport stateless singleton.
        @type   transport       BaseTransport
        @param  close_callback  The method to invoke when close() is called on this BaseChannel. May be left as None,
                                in which case close_impl() will be called. This expects to be a callable taking one
                                param, this channel instance.
        """
        self.set_close_callback(close_callback)
        self._transport = transport or AMQPTransport.get_instance()

        # setup FSM for BaseChannel / SendChannel tree
        self._fsm = FSM(self.S_INIT)
        self._fsm.add_transition(self.I_ATTACH, self.S_INIT, None, self.S_ACTIVE)
        self._fsm.add_transition(self.I_CLOSE, self.S_ACTIVE, self._on_close, self.S_CLOSED)
        self._fsm.add_transition(self.I_CLOSE, self.S_CLOSED, None, self.S_CLOSED)              # closed is a goal state, multiple closes are ok and are no-ops
        self._fsm.add_transition(self.I_CLOSE, self.S_INIT, None, self.S_CLOSED)                # INIT to CLOSED is fine too
示例#15
0
文件: channel.py 项目: swarbhanu/pyon
    def _on_start_consume(self):
        """
        Starts consuming messages.

        setup_listener must have been called first.
        """
        #log.debug("RecvChannel._on_start_consume")

        if self._consumer_tag and (self._queue_auto_delete and self._transport
                                   is AMQPTransport.get_instance()):
            log.warn(
                "Attempting to start consuming on a queue that may have been auto-deleted"
            )

        self._ensure_amq_chan()

        self._consumer_tag = self._amq_chan.basic_consume(
            self._on_deliver,
            queue=self._recv_name.queue,
            no_ack=self._consumer_no_ack,
            exclusive=self._consumer_exclusive)
示例#16
0
    def test_delete_xp(self):
        # same as test_delete_xs
        xp = self.container.ex_manager.create_xp('test_xp')

        # prove XS is declared already (can't declare the same named one with diff params)
        ch = self.container.node.channel(RecvChannel)
        ch._exchange_auto_delete = not xp._xs._xs_auto_delete

        self.assertRaises(TransportError, ch._declare_exchange, xp.exchange)

        # now let's delete via ex manager
        self.container.ex_manager.delete_xp(xp)

        # grab another channel and declare (should work fine this time)
        ch = self.container.node.channel(RecvChannel)
        ch._exchange_auto_delete = not xp._xs._xs_auto_delete

        ch._declare_exchange(xp.exchange)

        # cool, now cleanup (we don't expose this via Channel)
        at = AMQPTransport.get_instance()
        at.delete_exchange_impl(ch._amq_chan, xp.exchange)
示例#17
0
    def test_delete_xp(self):
        # same as test_delete_xs
        xp = self.container.ex_manager.create_xp('test_xp')

        # prove XS is declared already (can't declare the same named one with diff params)
        ch = self.container.node.channel(RecvChannel)
        ch._exchange_auto_delete = not xp._xs._xs_auto_delete

        self.assertRaises(TransportError, ch._declare_exchange, xp.exchange)

        # now let's delete via ex manager
        self.container.ex_manager.delete_xp(xp)

        # grab another channel and declare (should work fine this time)
        ch = self.container.node.channel(RecvChannel)
        ch._exchange_auto_delete = not xp._xs._xs_auto_delete

        ch._declare_exchange(xp.exchange)

        # cool, now cleanup (we don't expose this via Channel)
        at = AMQPTransport.get_instance()
        at.delete_exchange_impl(ch._amq_chan, xp.exchange)
示例#18
0
    def test_delete_xs(self):
        # we get interesting here.  we have to create or xs, try to declare again to prove it is there,
        # then delete, then declare to prove we CAN create, then make sure to clean it up.  whew.
        xs = self.container.ex_manager.create_xs('test_xs')

        # prove XS is declared already (can't declare the same named one with diff params)
        ch = self.container.node.channel(RecvChannel)
        ch._exchange_auto_delete = not xs._xs_auto_delete

        self.assertRaises(TransportError, ch._declare_exchange, xs.exchange)

        # now let's delete via ex manager
        self.container.ex_manager.delete_xs(xs)

        # grab another channel and declare (should work fine this time)
        ch = self.container.node.channel(RecvChannel)
        ch._exchange_auto_delete = not xs._xs_auto_delete

        ch._declare_exchange(xs.exchange)

        # cool, now cleanup (we don't expose this via Channel)
        at = AMQPTransport.get_instance()
        at.delete_exchange_impl(ch._amq_chan, xs.exchange)
示例#19
0
    def test_delete_xs(self):
        # we get interesting here.  we have to create or xs, try to declare again to prove it is there,
        # then delete, then declare to prove we CAN create, then make sure to clean it up.  whew.
        xs = self.container.ex_manager.create_xs('test_xs')

        # prove XS is declared already (can't declare the same named one with diff params)
        ch = self.container.node.channel(RecvChannel)
        ch._exchange_auto_delete = not xs._xs_auto_delete

        self.assertRaises(TransportError, ch._declare_exchange, xs.exchange)

        # now let's delete via ex manager
        self.container.ex_manager.delete_xs(xs)

        # grab another channel and declare (should work fine this time)
        ch = self.container.node.channel(RecvChannel)
        ch._exchange_auto_delete = not xs._xs_auto_delete

        ch._declare_exchange(xs.exchange)

        # cool, now cleanup (we don't expose this via Channel)
        at = AMQPTransport.get_instance()
        at.delete_exchange_impl(ch._amq_chan, xs.exchange)
示例#20
0
文件: channel.py 项目: swarbhanu/pyon
    def close_impl(self):
        if not self._queue_auto_delete and self._recv_name and self._transport is AMQPTransport.get_instance() and self._recv_name.queue.startswith("amq.gen-"):
            log.debug("Anonymous Subscriber detected, deleting queue (%s)", self._recv_name)
            self._destroy_queue()

        ListenChannel.close_impl(self)