Beispiel #1
0
    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
Beispiel #2
0
    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
Beispiel #3
0
    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 __init__(self, delegate, vhost, spec, heartbeat=0):
        FrameReceiver.__init__(self, spec)
        self.delegate = delegate

        # XXX Cyclic dependency
        self.delegate.client = self

        self.vhost = vhost

        self.channelFactory = type("Channel%s" % self.spec.klass.__name__,
                                   (self.channelClass, self.spec.klass), {})
        self.channels = {}
        self.channelLock = defer.DeferredLock()

        self.outgoing = defer.DeferredQueue()
        self.work = defer.DeferredQueue()

        self.started = TwistedEvent()

        self.queueLock = defer.DeferredLock()
        self.basic_return_queue = TimeoutDeferredQueue()

        self.queues = {}

        self.outgoing.get().addCallback(self.writer)
        self.work.get().addCallback(self.worker)
        self.heartbeatInterval = heartbeat
        if self.heartbeatInterval > 0:
            self.checkHB = reactor.callLater(
                self.heartbeatInterval * self.MAX_UNSEEN_HEARTBEAT,
                self.checkHeartbeat)
            self.sendHB = LoopingCall(self.sendHeartbeat)
            d = self.started.wait()
            d.addCallback(lambda _: self.reschedule_sendHB())
            d.addCallback(lambda _: self.reschedule_checkHB())
Beispiel #5
0
 def thriftBasicReturnQueue(self, key):
     yield self.thriftBasicReturnQueueLock.acquire()
     try:
         try:
             q = self.thriftBasicReturnQueues[key]
         except KeyError:
             q = TimeoutDeferredQueue()
             self.thriftBasicReturnQueues[key] = q
     finally:
         self.thriftBasicReturnQueueLock.release()
     defer.returnValue(q)
Beispiel #6
0
 def queue(self, key):
     yield self.queueLock.acquire()
     try:
         try:
             q = self.queues[key]
         except KeyError:
             q = TimeoutDeferredQueue(clock=self.clock)
             self.queues[key] = q
     finally:
         self.queueLock.release()
     defer.returnValue(q)
Beispiel #7
0
    def __init__(self,
                 delegate,
                 vhost,
                 spec,
                 heartbeat=0,
                 clock=None,
                 insist=False):
        FrameReceiver.__init__(self, spec)
        self.delegate = delegate

        # XXX Cyclic dependency
        self.delegate.client = self

        self.vhost = vhost

        self.channelFactory = type("Channel%s" % self.spec.klass.__name__,
                                   (self.channelClass, self.spec.klass), {})
        self.channels = {}
        self.channelLock = defer.DeferredLock()

        self.outgoing = defer.DeferredQueue()
        self.work = defer.DeferredQueue()

        self.started = TwistedEvent()
        self.disconnected = TwistedEvent()  # Fired upon connection shutdown
        self.closed = False

        self.queueLock = defer.DeferredLock()
        self.basic_return_queue = TimeoutDeferredQueue()

        self.queues = {}

        self.outgoing.get().addCallback(self.writer)
        self.work.get().addCallback(self.worker)
        self.heartbeatInterval = heartbeat
        self.insist = insist
        if clock is None:
            from twisted.internet import reactor
            clock = reactor
        self.clock = clock
        if self.heartbeatInterval > 0:
            self.checkHB = self.clock.callLater(
                self.heartbeatInterval * self.MAX_UNSEEN_HEARTBEAT,
                self.check_heartbeat)
            self.sendHB = LoopingCall(self.send_heartbeat)
            self.sendHB.clock = self.clock
            d = self.started.wait()
            d.addCallback(lambda _: self.reschedule_send_heartbeat())
            d.addCallback(lambda _: self.reschedule_check_heartbeat())
            # If self.started fails, don't start the heartbeat.
            d.addErrback(lambda _: None)
Beispiel #8
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 #9
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 #10
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 #11
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 #12
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)))