def _nextPartition(self): # XXX: One connection to another storage may remain open forever. # All other previous connections are automatically closed # after some time of inactivity. # This should be improved in several ways: # - Keeping connections open between 2 clusters (backup case) is # quite a good thing because establishing a connection costs # time/bandwidth and replication is actually never finished. # - When all storages of a non-backup cluster are up-to-date, # there's no reason to keep any connection open. if self.current_partition is not None or not self.replicate_dict: return app = self.app # Choose a partition with no unfinished transaction if possible. # XXX: When leaving backup mode, we should only consider UP_TO_DATE # cells. for offset in self.replicate_dict: if not self.partition_dict[offset].max_ttid: break try: addr, name = self.source_dict[offset] except KeyError: assert app.pt.getCell(offset, app.uuid).isOutOfDate() node = random.choice([ cell.getNode() for cell in app.pt.getCellList(offset, readable=True) if cell.getNodeState() == NodeStates.RUNNING ]) name = None else: node = app.nm.getByAddress(addr) if node is None: assert name, addr node = app.nm.createStorage(address=addr) self.current_partition = offset previous_node = self.current_node self.current_node = node if node.isConnected(connecting=True): if node.isIdentified(): node.getConnection().asClient() self.fetchTransactions() else: assert name or node.getUUID() != app.uuid, "loopback connection" conn = ClientConnection(app, StorageOperationHandler(app), node) try: conn.ask( Packets.RequestIdentification(NodeTypes.STORAGE, None if name else app.uuid, app.server, name or app.name)) except ConnectionClosed: if previous_node is self.current_node: return if previous_node is not None and previous_node.isConnected(): app.closeClient(previous_node.getConnection())
def connect(node, uuid=app.uuid, name=app.name): if node.getUUID() == app.uuid: return if node.isConnected(connecting=True): conn = node.getConnection() conn.asClient() else: conn = ClientConnection(app, StorageOperationHandler(app), node) conn.ask(Packets.RequestIdentification( NodeTypes.STORAGE, uuid, app.server, name)) self.conn_dict[conn] = node.isIdentified()
def _nextPartition(self): # XXX: One connection to another storage may remain open forever. # All other previous connections are automatically closed # after some time of inactivity. # This should be improved in several ways: # - Keeping connections open between 2 clusters (backup case) is # quite a good thing because establishing a connection costs # time/bandwidth and replication is actually never finished. # - When all storages of a non-backup cluster are up-to-date, # there's no reason to keep any connection open. if self.current_partition is not None or not self.replicate_dict: return app = self.app # Choose a partition with no unfinished transaction if possible. # XXX: When leaving backup mode, we should only consider UP_TO_DATE # cells. for offset in self.replicate_dict: if not self.partition_dict[offset].max_ttid: break try: addr, name = self.source_dict[offset] except KeyError: assert app.pt.getCell(offset, app.uuid).isOutOfDate() node = random.choice([cell.getNode() for cell in app.pt.getCellList(offset, readable=True) if cell.getNodeState() == NodeStates.RUNNING]) name = None else: node = app.nm.getByAddress(addr) if node is None: assert name, addr node = app.nm.createStorage(address=addr) self.current_partition = offset previous_node = self.current_node self.current_node = node if node.isConnected(connecting=True): if node.isIdentified(): node.getConnection().asClient() self.fetchTransactions() else: assert name or node.getUUID() != app.uuid, "loopback connection" conn = ClientConnection(app, StorageOperationHandler(app), node) try: conn.ask(Packets.RequestIdentification(NodeTypes.STORAGE, None if name else app.uuid, app.server, name or app.name)) except ConnectionClosed: if previous_node is self.current_node: return if previous_node is not None and previous_node.isConnected(): app.closeClient(previous_node.getConnection())