Ejemplo n.º 1
0
class Main:
    @staticmethod
    def send_data(sock: SCTSock, code: ErrorCodes, data=None):
        sock.send_data({"res": code, "data": data})
        sock.close()

    def __init__(self, threads:int=20, listener_timeout:int=600, request_timeout:int=50):
        self._request_timout = request_timeout

        signal.signal(signal.SIGTERM, self.stop)

        self._pool = multiprocessing.pool.ThreadPool(threads + 1)
        self._lock = multiprocessing.Lock()

        self._plugin = Plugin()
        self._timeout = Timeout(self.stop, listener_timeout)
        self._connections = Connections(threads)
        self._listener = Listener(self.handle_connection)
        self._listener.run()

    def stop(self, signum:int=0, frame=None):
        self._timeout.stop()
        self._listener.close()
        self._connections.apply(lambda con: self.send_data(con, ErrorCodes.listener_timeout))
        self._pool.close()

    def handle_connection(self, sock: SCTSock):
        self._pool.apply_async(self._handle_connection_thread, [sock])

    def _handle_connection_thread(self, sock: SCTSock):
        try:
            with ConnectionsWrapper(sock, self._connections):
                self._timeout.reset()
                with self._lock:
                    version = sock.recv().payload
                    if not self._plugin.checkVersion(version):
                        sock.send_init("init")
                        data = sock.recv().payload
                        self._plugin.setSettings(version, data)
                sock.send_init("data")
                con_pool = multiprocessing.pool.ThreadPool(1)
                data = sock.recv().payload
                result = con_pool.apply_async(self._plugin.exec, [data]).get(
                    self._request_timout
                )
                con_pool.close()
                self.send_data(sock, ErrorCodes.none, result)
        except multiprocessing.TimeoutError:
            self.send_data(sock, ErrorCodes.execution_timeout)
        except TooManyConnectionsError:
            self.send_data(sock, ErrorCodes.too_many_connections)
        except Exception as e:
            traceback = get_traceback(e)
            self.send_data(sock, ErrorCodes.exception, traceback)
            print(traceback)
        finally:
            sock.close()