def _processIncoming(self, delivery, connector): link = proton.pn_delivery_link(delivery) ssn = proton.pn_link_session(link) msg = [] self.log.debug("Receiving '%s'", proton.pn_delivery_tag(delivery)) while True: rc, buff = proton.pn_link_recv(link, 1024) msg.append(buff) if rc == proton.PN_EOS: break msg = ''.join(msg) self.log.debug("Received '%s'", proton.pn_delivery_tag(delivery)) proton.pn_link_advance(link) proton.pn_delivery_update(delivery, proton.PN_ACCEPTED) proton.pn_delivery_settle(delivery) msgObj = proton.Message() msgObj.decode(msg) ctx = proton.pn_session_get_context(ssn) ctx._pushIncomingMessage(msgObj.body) # if more credit is needed, grant it if proton.pn_link_credit(link) == 0: proton.pn_link_flow(link, MBUFF_SIZE)
def _queueOutgoingDeliveries(self, conn): for ssn in self._iterSessions(conn, proton.PN_LOCAL_ACTIVE): ctx = proton.pn_session_get_context(ssn) sender = ctx.sender if sender is None: # No sender link sender = proton.pn_sender(ctx.session, "sender-%s" % str(uuid.uuid4())) ctx.sender = sender continue while proton.pn_link_credit(sender) > 0: try: data = ctx._popPendingMessage() except Empty: break else: msg = proton.Message() msg.body = data d = proton.pn_delivery(sender, "delivery-%s" % str(uuid.uuid4())) proton.pn_delivery_set_context(d, msg.encode()) self.log.debug("Queueing delivery (%s)", proton.pn_delivery_tag(d))
def _processOutgoing(self, delivery): link = proton.pn_delivery_link(delivery) msg = proton.pn_delivery_get_context(delivery) proton.pn_link_send(link, msg) if proton.pn_link_advance(link): self.log.debug("Delivery finished (%s)", proton.pn_delivery_tag(delivery)) proton.pn_delivery_set_context(delivery, time.time())
def _processDeliveries(self, conn, connector): delivery = proton.pn_work_head(conn) while delivery: self.log.debug("Process delivery %s" % proton.pn_delivery_tag(delivery)) if proton.pn_delivery_readable(delivery): self._processIncoming(delivery, connector) elif proton.pn_delivery_writable(delivery): self._processOutgoing(delivery) delivery = proton.pn_work_next(delivery)
def _cleanDeliveries(self, conn): def link_iter(conn): link = proton.pn_link_head(conn, (proton.PN_LOCAL_ACTIVE)) while link: yield link link = proton.pn_link_next(link, (proton.PN_LOCAL_ACTIVE)) def delivery_iter(link): d = proton.pn_unsettled_head(link) while d: yield d d = proton.pn_unsettled_next(d) for link in link_iter(conn): for d in delivery_iter(link): ctx = proton.pn_delivery_get_context(d) if isinstance(ctx, str): continue disp = proton.pn_delivery_remote_state(d) age = time.time() - ctx self.log.debug("Checking delivery (%s)", proton.pn_delivery_tag(d)) if disp and disp != proton.PN_ACCEPTED: self.log.warn("Message was not accepted by remote end") if disp and proton.pn_delivery_settled(d): self.log.debug("Message settled by remote end") proton.pn_delivery_settle(d) proton.pn_delivery_clear(d) elif age > self._deliveryTimeout: self.log.warn("Delivary not settled by remote host") proton.pn_delivery_settle(d) proton.pn_delivery_clear(d) elif proton.pn_link_state(link) & proton.PN_REMOTE_CLOSED: self.log.warn("Link closed before settling message") proton.pn_delivery_settle(d) proton.pn_delivery_clear(d)