def allow_to_enter(self, broker, message_id): self.clock_adjustments() message = build_message_between_brokers(OperationType.ALLOW.value, self.clock, "", self.broker_id, message_id) message_bytes = general_encode(self.serialization, message) send_message_packed_with_size_to_another_broker(broker, message_bytes) print(f'Sent allow for {message_id} to enter')
def handle_list(self, conn): nodes = [topic.path for topic in self.trie.find_all_nodes()] connection_info = self.connections[conn] serialization = connection_info.serialization if len(nodes) == 0: nodes = "No topics yet" message = build_message(serialization, OperationType.LIST.value, None, nodes) message_bytes = general_encode(serialization, message) connection_info.send(message_bytes)
def connect_to_brokers(self): print('Waiting for brokers.') time.sleep(5) self.brokers_dict = { p: ExternalBroker(socket.create_connection(('localhost', p)), p) for p in self.brokers_ports } send_to_all_brokers(self.brokers_dict.values(), str.encode(self.serialization)) message = build_message_between_brokers(OperationType.GREETING.value, self.clock, "", self.broker_id) message_bytes = general_encode(self.serialization, message) send_to_all_brokers(self.brokers_dict.values(), message_bytes)
def release(self): self.clock_adjustments() first_request = self.request_queue[0] if first_request.broker_id == self.broker_id: message = build_message_between_brokers( OperationType.RELEASE.value, self.clock, "", self.broker_id, first_request.message_id) message_bytes = general_encode(self.serialization, message) send_to_all_brokers(self.brokers_dict.values(), message_bytes) print(f"Sent release for {first_request.message_id}") print(f"Publishing {first_request.message_id}") self.publish(first_request.message) self.clean_up_queue(first_request.message_id)
def handle_subscribe(self, conn, topic_node: Node, message): if topic_node is None: self.remove_closed_connection(conn) print(f"Unknown topic path: {message['topic']}") return connection_info = self.connections[conn] topic_node.topic.add_subscriber(connection_info) connection_info.add_subscribed_topic(topic_node.topic) # TODO: handle messages in other brokers last_message = topic_node.topic.last_message if last_message is not None: message_bytes = general_encode(connection_info.serialization, last_message) connection_info.send(message_bytes)
def publish(self, message): topic_path = message["topic"] topic_node = self.trie.find_node(topic_path) relevant_topics = topic_node.find_ancestors_and_self() update_last_message(relevant_topics, message) message_cache = { } # Key: SerializationType, Value: corresponding encoded message for topic in relevant_topics: for subscriber in topic.subscribers: # each subscriber is a ConnectionInfo subscriber_serialization = subscriber.serialization # Check if the serialized message already exists in the cache if subscriber_serialization in message_cache: subscriber.send(message_cache[subscriber_serialization]) # If not, go through the encoding process else: message_bytes = general_encode(subscriber_serialization, message) message_cache[subscriber_serialization] = message_bytes subscriber.send(message_bytes)
def request_to_enter(self, topic_node, message): self.clock_adjustments() timestamp = message["timestamp"] content = message["content"] serialization = message["serialization"] message_to_publish = build_message(serialization, OperationType.PUBLISH.value, topic_node.topic.path, content, timestamp) enter_message = build_message_between_brokers( OperationType.ENTER.value, self.clock, message_to_publish, self.broker_id) request = Request(OperationType.ENTER.value, self.clock, enter_message["message_id"], self.broker_id, message_to_publish) self.request_queue.append(request) self.sort_queue() message_bytes = general_encode(self.serialization, enter_message) send_to_all_brokers(self.brokers_dict.values(), message_bytes) print(f"Sent enter for {enter_message['message_id']}")
def cancel(self): message = build_message(self.serialization_type, OperationType.CANCEL.value, self.topic, "") message_bytes = general_encode(self.serialization_type, message) send_message_packed_with_size(self.queue_socket, message_bytes) self.subscribed = False
def list(self): message = build_message(self.serialization_type, OperationType.LIST.value, None, "") message_bytes = general_encode(self.serialization_type, message) send_message_packed_with_size(self.queue_socket, message_bytes)
def subscribe(self): message = build_message(self.serialization_type, OperationType.SUBSCRIBE.value, self.topic, "") message_bytes = general_encode(self.serialization_type, message) send_message_packed_with_size(self.queue_socket, message_bytes) self.subscribed = True
def push(self, value): message = build_message(self.serialization_type, OperationType.PUBLISH.value, self.topic, value) message_bytes = general_encode(self.serialization_type, message) send_message_packed_with_size(self.queue_socket, message_bytes)