def __init__(self, messaging, agent): log.Logger.__init__(self, messaging) self._messaging = messaging self._sink = IChannelSink(agent) self._bindings = [] self._queue = None self._disconnected = False self._consume_deferred = None self._queue_name = agent.get_agent_id() self.log_name = self._queue_name
def __init__(self, backend, agent): log.Logger.__init__(self, backend) self._backend = IBackend(backend) self._sink = IChannelSink(agent) self._channel_id = self._sink.get_agent_id() backend._register_channel(self)
class Channel(log.Logger): implements(IChannel) channel_type = CHANNEL_TYPE support_broadcast = False def __init__(self, backend, agent): log.Logger.__init__(self, backend) self._backend = IBackend(backend) self._sink = IChannelSink(agent) self._channel_id = self._sink.get_agent_id() backend._register_channel(self) @property def channel_id(self): return self._channel_id ### IChannel ### def release(self): self._backend._release_channel(self) def post(self, recipients, message): if not isinstance(message, BaseMessage): raise ValueError("Expected second argument to be " "f.a.b.BaseMessage, got %r instead" % (type(message), )) if IDialogMessage.providedBy(message): reply_to = message.reply_to if reply_to is None: reply_to = recipient.Recipient(self._sink.get_agent_id(), self._backend.route, self.channel_type) message.reply_to = reply_to elif ((reply_to.type is not RecipientType.agent) or (reply_to.channel != self.channel_type)): self.error("Invalid reply_to for tunneling, " "dropping %d instance(s) of message: %r", len(list(IRecipients(recipients))), message) return return self._backend.post(recipients, message) def bind(self, key, route=None): return None def get_bindings(self, route=None): return [] def get_recipient(self): return recipient.Recipient(self._channel_id, self._backend.route, self._backend.channel_type) ### protected ### def initiate(self): return defer.succeed(self) def _dispatch(self, message): self._sink.on_message(message)
class Connection(log.Logger): implements(IMessagingClient, IChannel) support_broadcast = True def __init__(self, messaging, agent): log.Logger.__init__(self, messaging) self._messaging = messaging self._sink = IChannelSink(agent) self._bindings = [] self._queue = None self._disconnected = False self._consume_deferred = None self._queue_name = agent.get_agent_id() self.log_name = self._queue_name def initiate(self): d = defer.succeed(None) if self._queue_name is not None: d.addCallback(defer.drop_param, self._messaging.define_queue, self._queue_name) d.addCallback(self._main_loop) else: self.warning('Queue name is None, skipping creating queue ' 'and consumer.') d.addCallback(defer.override_result, self) return d ### IMessagingClient ### def disconnect(self): warnings.warn("IMessagingClient's diconnect() is deprecated, " "please use IChannel's release() instead.", DeprecationWarning) return self.release() def personal_binding(self, key, shard=None): warnings.warn("IMessagingClient's personal_binding() is deprecated, " "please use IChannel's bind() instead.", DeprecationWarning) return self.bind(key, shard) def publish(self, key, shard, message): warnings.warn("IMessagingClient's publish() is deprecated, " "please use IChannel's post() instead.", DeprecationWarning) return self.post(recipient.Recipient(key=key, route=shard), message) ### IChannel ### @property def channel_type(self): return self._messaging.channel_type def post(self, recipients, message): if not isinstance(message, BaseMessage): raise ValueError("Expected second argument to be " "f.a.b.BaseMessage, got %r instead" % (type(message), )) recipients = recipient.IRecipients(recipients) if IDialogMessage.providedBy(message): reply_to = message.reply_to if reply_to is None: reply_to = recipient.Recipient(self._queue_name, self._sink.get_shard_id(), self.channel_type) message.reply_to = reply_to elif reply_to.channel != self.channel_type: self.error("Invalid reply_to for messaging backend, " "dropping %d instance(s) of message: %r", len(list(recipients)), message) return defers = [] for recip in recipients: assert recip.channel == self.channel_type, \ "Unexpected channel type" self.log('Sending message to %r', recip) d = self._messaging.publish(recip.key, recip.route, message) defers.append(d) return defer.DeferredList(defers) def release(self): self._disconnected = True if self._consume_deferred and not self._consume_deferred.called: ex = FinishConnection("Disconnecting") self._consume_deferred.errback(ex) return self._messaging.disconnect() def bind(self, key, route=None): if not route: route = self._sink.get_shard_id() recip = recipient.Recipient(key=key, route=route) return PersonalBinding(self, self._queue_name, recip) def get_bindings(self, route=None): if route is None: return list(self._bindings) return [x for x in self._bindings if x.recipient.route == route] def get_recipient(self): return recipient.Recipient(self._queue_name, self._sink.get_shard_id()) ### protected ### def _register_binding(self, binding): self._bindings.append(binding) def _revoke_binding(self, binding): self._bindings.remove(binding) def _define_exchange(self, route, exchange_type="direct"): return self._messaging.define_exchange(route, exchange_type) def _create_binding(self, recipient, queue_name): return self._messaging.create_binding(recipient.route, recipient.key, queue_name) def _delete_binding(self, recipient, queue_name): return self._messaging.delete_binding(recipient.route, recipient.key, queue_name) ### private ### def _main_loop(self, queue): self._queue = queue def rebind(_): reactor.callLater(0, bind) def stop(reason): if reason.check(FinishConnection): self.log('Error handler: exiting, reason %r' % reason) else: reason.raiseException() def bind(): if self._disconnected: return d = self._consume_queue(queue) d.addCallbacks(rebind, stop) bind() def _consume_queue(self, queue): def get_and_call_on_message(message): return self._sink.on_message(message) self._consume_deferred = queue.get() self._consume_deferred.addCallback(get_and_call_on_message) return self._consume_deferred