Beispiel #1
0
class AMQChannel(object):

    def __init__(self, id, outgoing, client):
        self.id = id
        self.outgoing = outgoing
        self.client = client
        self.incoming = TimeoutDeferredQueue()
        self.responses = TimeoutDeferredQueue()

        self.queue = None

        self._closing = False
        self.closed = False
        self.reason = None

        self.use_publish_confirms = False
        self.publish_confirms = TimeoutDeferredQueue()

    def close(self, reason):
        """Explicitely close a channel"""
        self._closing = True
        self.doClose(reason)
        self._closing = False

    def doClose(self, reason):
        """Called when channel_close() is received"""
        if self.closed:
            return
        self.closed = True
        self.reason = reason
        self.incoming.close()
        self.responses.close()
        if not self._closing:
            self.client.channelFailed(self, Failure(reason))

    def dispatch(self, frame, work):
        payload = frame.payload
        if isinstance(payload, Method):
            if payload.method.response:
                self.queue = self.responses
            else:
                self.queue = self.incoming
                work.put(self.incoming)
        self.queue.put(frame)

    @defer.inlineCallbacks
    def invoke(self, method, args, content=None):
        if self.closed:
            raise Closed(self.reason)
        frame = Frame(self.id, Method(method, *args))
        self.outgoing.put(frame)

        if method.content:
            if content == None:
                content = Content()
            self.writeContent(method.klass, content, self.outgoing)

        try:
            # here we depend on all nowait fields being named nowait
            f = method.fields.byname["nowait"]
            nowait = args[method.fields.index(f)]
        except KeyError:
            nowait = False

        try:

            if not nowait and method.responses:
                resp = (yield self.responses.get()).payload

                if resp.method.klass.name == 'confirm' and resp.method.name == 'select-ok':
                    self.use_publish_confirms = True

                if resp.method.content:
                    content = yield readContent(self.responses)
                else:
                    content = None
                if resp.method in method.responses:
                    defer.returnValue(Message(resp.method, resp.args, content))
                else:
                    raise ValueError(resp)

            elif self.use_publish_confirms and method.name == 'publish' and method.klass.name == 'basic':
                resp = yield self.publish_confirms.get()
                defer.returnValue(resp.method.name == 'ack')

        except QueueClosed, e:
            if self.closed:
                raise Closed(self.reason)
            else:
                raise e
Beispiel #2
0
class AMQChannel(object):

    def __init__(self, id, outgoing):
        self.id = id
        self.outgoing = outgoing
        self.incoming = TimeoutDeferredQueue()
        self.responses = TimeoutDeferredQueue()

        self.queue = None

        self.closed = False
        self.reason = None

    def close(self, reason):
        if self.closed:
            return
        self.closed = True
        self.reason = reason
        self.incoming.close()
        self.responses.close()

    def dispatch(self, frame, work):
        payload = frame.payload
        if isinstance(payload, Method):
            if payload.method.response:
                self.queue = self.responses
            else:
                self.queue = self.incoming
                work.put(self.incoming)
        self.queue.put(frame)

    @defer.inlineCallbacks
    def invoke(self, method, args, content = None):
        if self.closed:
            raise Closed(self.reason)
        frame = Frame(self.id, Method(method, *args))
        self.outgoing.put(frame)

        if method.content:
            if content == None:
                content = Content()
            self.writeContent(method.klass, content, self.outgoing)

        try:
            # here we depend on all nowait fields being named nowait
            f = method.fields.byname["nowait"]
            nowait = args[method.fields.index(f)]
        except KeyError:
            nowait = False

        try:
            if not nowait and method.responses:
                resp = (yield self.responses.get()).payload

                if resp.method.content:
                    content = yield readContent(self.responses)
                else:
                    content = None
                if resp.method in method.responses:
                    defer.returnValue(Message(resp.method, resp.args, content))
                else:
                    raise ValueError(resp)
        except QueueClosed, e:
            if self.closed:
                raise Closed(self.reason)
            else:
                raise e
Beispiel #3
0
class AMQChannel(object):
    def __init__(self, id, outgoing):
        self.id = id
        self.outgoing = outgoing
        self.incoming = TimeoutDeferredQueue()
        self.responses = TimeoutDeferredQueue()

        self.queue = None

        self.closed = False
        self.reason = None

    def close(self, reason):
        if self.closed:
            return
        self.closed = True
        self.reason = reason
        self.incoming.close()
        self.responses.close()

    def dispatch(self, frame, work):
        payload = frame.payload
        if isinstance(payload, Method):
            if payload.method.response:
                self.queue = self.responses
            else:
                self.queue = self.incoming
                work.put(self.incoming)
        self.queue.put(frame)

    @defer.inlineCallbacks
    def invoke(self, method, args, content=None):
        if self.closed:
            raise Closed(self.reason)
        frame = Frame(self.id, Method(method, *args))
        self.outgoing.put(frame)

        if method.content:
            if content == None:
                content = Content()
            self.writeContent(method.klass, content, self.outgoing)

        try:
            # here we depend on all nowait fields being named nowait
            f = method.fields.byname["nowait"]
            nowait = args[method.fields.index(f)]
        except KeyError:
            nowait = False

        try:
            if not nowait and method.responses:
                resp = (yield self.responses.get()).payload

                if resp.method.content:
                    content = yield readContent(self.responses)
                else:
                    content = None
                if resp.method in method.responses:
                    defer.returnValue(Message(resp.method, resp.args, content))
                else:
                    raise ValueError(resp)
        except QueueClosed, e:
            if self.closed:
                raise Closed(self.reason)
            else:
                raise e
Beispiel #4
0
class AMQChannel(object):
    def __init__(self, id, outgoing, client):
        self.id = id
        self.outgoing = outgoing
        self.client = client
        self.incoming = TimeoutDeferredQueue()
        self.responses = TimeoutDeferredQueue()

        self.queue = None

        self._closing = False
        self.closed = False
        self.reason = None

    def close(self, reason):
        """Explicitly close a channel"""
        self._closing = True
        self.do_close(reason)
        self._closing = False

    def do_close(self, reason):
        """Called when channel_close() is received"""
        if self.closed:
            return
        self.closed = True
        self.reason = reason
        self.incoming.close()
        self.responses.close()
        if not self._closing:
            self.client.channel_failed(self, Failure(reason))

    def dispatch(self, frame, work):
        payload = frame.payload
        if isinstance(payload, Method):
            if payload.method.response:
                self.queue = self.responses
            else:
                self.queue = self.incoming
                work.put(self.incoming)
        self.queue.put(frame)

    @defer.inlineCallbacks
    def invoke(self, method, args, content=None):
        if self.closed:
            self._raise_closed(self.reason)
        frame = Frame(self.id, Method(method, *args))
        self.outgoing.put(frame)

        if method.content:
            if content is None:
                content = Content()
            self.write_content(method.klass, content, self.outgoing)

        try:
            # here we depend on all nowait fields being named nowait
            f = method.fields.byname["nowait"]
            nowait = args[method.fields.index(f)]
        except KeyError:
            nowait = False

        try:
            if not nowait and method.responses:
                resp = (yield self.responses.get()).payload

                if resp.method.content:
                    content = yield read_content(self.responses)
                else:
                    content = None
                if resp.method in method.responses:
                    defer.returnValue(Message(resp.method, resp.args, content))
                else:
                    raise ValueError(resp)
        except QueueClosed as e:
            if self.closed:
                self._raise_closed(self.reason)
            else:
                raise e

    def write_content(self, klass, content, queue):
        size = content.size()
        header = Frame(
            self.id, Header(klass, content.weight(), size,
                            **content.properties))
        queue.put(header)
        for child in content.children:
            self.write_content(klass, child, queue)
        if size > 0:
            max_chunk_size = self.client.MAX_LENGTH - 8
            for i in range(0, len(content.body), max_chunk_size):
                chunk = content.body[i:i + max_chunk_size]
                queue.put(Frame(self.id, Body(chunk)))

    @staticmethod
    def _raise_closed(reason):
        """Raise the appropriate Closed-based error for the given reason."""
        if isinstance(reason, Message):
            if reason.method.klass.name == "channel":
                raise ChannelClosed(reason)
            elif reason.method.klass.name == "connection":
                raise ConnectionClosed(reason)
        raise Closed(reason)
Beispiel #5
0
class AMQChannel(object):

    def __init__(self, id, outgoing):
        self.id = id
        self.outgoing = outgoing
        self.incoming = TimeoutDeferredQueue()
        self.responses = TimeoutDeferredQueue()

        self.queue = None

        self.closed = False
        self.reason = None

    def close(self, reason):
        if self.closed:
            return
        self.closed = True
        self.reason = reason
        self.incoming.close()
        self.responses.close()

    def dispatch(self, frame, work):
        payload = frame.payload
        if isinstance(payload, Method):
            if payload.method.response:
                self.queue = self.responses
            else:
                self.queue = self.incoming
                work.put(self.incoming)
        self.queue.put(frame)

    def invoke(self, method, args, content = None):
        if self.closed:
            return defer.fail(Closed(self.reason))
        frame = Frame(self.id, Method(method, *args))
        self.outgoing.put(frame)

        if method.content:
            if content == None:
                content = Content()
            self.writeContent(method.klass, content, self.outgoing)

        try:
            # here we depend on all nowait fields being named nowait
            f = method.fields.byname["nowait"]
            nowait = args[method.fields.index(f)]
        except KeyError:
            nowait = False

        def handleQueueClosed(fail):
            if self.closed:
                return defer.fail(Closed(self.reason))
            else:
                return fail

        def getResponse():
            def gotResponse(response):
                resp = response.payload

                def getContent():
                    if resp.method.content:
                        return readContent(self.responses)
                    else:
                        return None
                
                def gotContent(content):
                    if resp.method in method.responses:
                        return Message(resp.method, resp.args, content)
                    else:
                        raise ValueError(resp)

                return defer.maybeDeferred(getContent).addCallback(gotContent)

            return self.responses.get().addCallback(gotResponse)

        if not nowait and method.responses:
            return getResponse().addErrback(handleQueueClosed)
        else:
            return defer.succeed(None)

    def writeContent(self, klass, content, queue):
        size = content.size()
        header = Frame(self.id, Header(klass, content.weight(), size, **content.properties))
        queue.put(header)
        for child in content.children:
            self.writeContent(klass, child, queue)
        # should split up if content.body exceeds max frame size
        if size > 0:
            queue.put(Frame(self.id, Body(content.body)))