def close(self): Endpoint.close(self) self.kill(EndpointDied)
class Service: """ Define'' the service of message redistribution """ def __init__(self, host, port): """ Define the main components useful for the loop """ self.__endpoint = Endpoint(host, port) self.__connections = [] self.__pendings = [] def accept_new_conn(self): """ Check if new connection requests have been made and add these """ self.__connections += self.__endpoint.accept(constants.ACCEPT_TIMEOUT) def turn_messages(self): """ Wait for or gather the connections which are ready to send or receive messages Attends ou recupère les éventuels If there are ones, close and delete upon detection terminated connections Save each received message to send it to all clients, send each message to the ready to receive clients that have not already received the message and delete messages sent to all clients. """ ready_rconns, ready_wconns, _ = select(self.__connections, self.__connections, [], constants.RECV_SEND_TIMEOUT) for conn in ready_rconns: # Receive the complete client message msg = conn.receive() if msg: self.__pendings.append(PendingMessage(msg, self.__connections)) else: conn.close() self.__connections.remove(conn) self.__send_pendings(ready_wconns) def close(self): """ Close properly the server and all the connection still open Send the last saved messages but don't receive anymore """ while self.__pendings: _, ready_wconns, _ = select([], self.__connections, [], constants.RECV_SEND_TIMEOUT) self.__send_pendings(ready_wconns) for conn in self.__connections: conn.close() self.__endpoint.close() def __send_pendings(self, conns): """ Send pending messages to the clients that can receive them conns (iterable[Connection])--- the connections to the clients that can receive a message """ done_pendings = [] for pending in self.__pendings: # Remove connexions that couldn't # send the message for conn in pending.send(conns): conn.close() self.__connections.remove(conn) if pending.is_done(): done_pendings.append(pending) # Remove the messages sent to all clients for pending in done_pendings: self.__pendings.remove(pending)
def close(self): Endpoint.close(self) gr = self.greenlet self.greenlet = None gr and gr.kill(EndpointDied)