def handle_hole_punching_timeout(connection): if connection.get_connection_state() == ConnectionState.OPEN: return if not USE_RELAY: logging.info( "Connection {} is unreachable. Not switching to RELAY " "because it was disabled.".format( connection.get_peer().get_public_address()), ) connection.set_connection_state(ConnectionState.UNREACHABLE) return logging.info("Switching connection {} to RELAY".format( connection.get_peer().get_public_address())) connection.set_connection_state(ConnectionState.RELAY) operations = self._document.get_document_operations() payload = InteragentProtocolUtils.serialize( NewOperations(operations_list=json.dumps(operations))) io_data = self._gateway.generate_io_data( payload, connection.get_peer().get_public_address(), ) self._gateway.write_io_data( io_data, reliability=True, )
def _handle_new_patches(self, message): nested_operations = [ self._document.set_text_in_range( patch["start"], patch["end"], patch["text"], ) for patch in message.patch_list ] operations = [] for operations_list in nested_operations: operations.extend(operations_list) connections = ConnectionStore.get_instance().get_open_connections() if len(connections) == 0: return addresses = [ connection.get_active_address() for connection in connections ] payload = InteragentProtocolUtils.serialize( NewOperations(operations_list=json.dumps(operations))) io_data = self._gateway.generate_io_data(payload, addresses) self._gateway.write_io_data( io_data, reliability=True, )
def stop(self): connections = ConnectionStore.get_instance().get_open_connections() io_data = self._gateway.generate_io_data( InteragentProtocolUtils.serialize(Bye()), [connection.get_active_address() for connection in connections], ) self._gateway.write_io_data(io_data) ConnectionStore.reset_instance()
def _handle_connect_to(self, message): hostname = socket.gethostbyname(message.host) logging.info( "Tandem Agent is attempting to establish a direct" " connection to {}:{}.".format(hostname, message.port), ) address = (hostname, message.port) payload = InteragentProtocolUtils.serialize( Hello( id=str(self._id), should_reply=True, )) io_data = self._gateway.generate_io_data(payload, address) self._gateway.write_io_data(io_data)
def _send_all_operations(self, connection, even_if_empty=False): operations = self._document.get_document_operations() if not even_if_empty and len(operations) == 0: return payload = InteragentProtocolUtils.serialize( NewOperations(operations_list=json.dumps(operations))) io_data = self._gateway.generate_io_data( payload, connection.get_active_address(), ) self._gateway.write_io_data( io_data, reliability=True, )
def _handle_ping(self, message, sender_address): peer_id = uuid.UUID(message.id) connection = \ ConnectionStore.get_instance().get_connection_by_id(peer_id) # Only reply to peers we know about to prevent the other peer from # thinking it can reach us successfully if connection is None: return logging.debug( "Replying to ping from {} at {}:{}.".format( message.id, *sender_address), ) io_data = self._gateway.generate_io_data( InteragentProtocolUtils.serialize(PingBack(id=str(self._id))), sender_address, ) self._gateway.write_io_data(io_data)
def _handle_hello(self, message, sender_address): id = uuid.UUID(message.id) new_connection = DirectConnection( Peer( id=id, public_address=sender_address, )) ConnectionStore.get_instance().add_connection(new_connection) logging.info( "Tandem Agent established a direct connection to {}:{}".format( *sender_address), ) if message.should_reply: io_data = self._gateway.generate_io_data( InteragentProtocolUtils.serialize( Hello( id=str(self._id), should_reply=False, )), sender_address, ) self._gateway.write_io_data(io_data) self._send_all_operations(new_connection)
def _send_message(gateway, addresses, message): io_data = gateway.generate_io_data( InteragentProtocolUtils.serialize(message), addresses, ) gateway.write_io_data(io_data)