From 4e10ff90634adff5293aea823288ab1a0f1487b1 Mon Sep 17 00:00:00 2001 From: BreakWa11 Date: Fri, 20 May 2016 15:49:19 +0800 Subject: [PATCH] better way to stop a server --- Config.py | 2 +- db_transfer.py | 12 +++++++++++- server_pool.py | 8 ++++---- shadowsocks/tcprelay.py | 5 ++--- shadowsocks/udprelay.py | 22 +++++++++++++--------- 5 files changed, 31 insertions(+), 18 deletions(-) diff --git a/Config.py b/Config.py index eb81abf..752ebde 100644 --- a/Config.py +++ b/Config.py @@ -5,7 +5,7 @@ MYSQL_USER = 'ss' MYSQL_PASS = 'ss' MYSQL_DB = 'shadowsocks' MYSQL_TRANSFER_MUL = 1.0 -MYSQL_UPDATE_TIME = 15 +MYSQL_UPDATE_TIME = 60 MANAGE_PASS = 'ss233333333' #if you want manage in other server you should set this value to global ip diff --git a/db_transfer.py b/db_transfer.py index e50e459..d5c6994 100644 --- a/db_transfer.py +++ b/db_transfer.py @@ -115,6 +115,7 @@ class DbTransfer(object): except Exception as e: logging.error('load switchrule.py fail') cur_servers = {} + new_servers = {} for row in rows: try: allow = switchrule.isTurnOn(row) and row['enable'] == 1 and row['u'] + row['d'] < row['transfer_enable'] @@ -139,9 +140,10 @@ class DbTransfer(object): #password changed logging.info('db stop server at port [%s] reason: password changed' % (port,)) ServerPool.get_instance().cb_del_server(port) - ServerPool.get_instance().new_server(port, passwd) + new_servers[port] = passwd elif allow and ServerPool.get_instance().server_run_status(port) is False: + #new_servers[port] = passwd logging.info('db start server at port [%s] pass [%s]' % (port, passwd)) ServerPool.get_instance().new_server(port, passwd) @@ -152,6 +154,14 @@ class DbTransfer(object): logging.info('db stop server at port [%s] reason: port not exist' % (row['port'])) ServerPool.get_instance().cb_del_server(row['port']) + if len(new_servers) > 0: + from shadowsocks import eventloop + DbTransfer.get_instance().event.wait(eventloop.TIMEOUT_PRECISION) + for port in new_servers.keys(): + passwd = new_servers[port] + logging.info('db start server at port [%s] pass [%s]' % (port, passwd)) + ServerPool.get_instance().new_server(port, passwd) + @staticmethod def del_servers(): for port in ServerPool.get_instance().tcp_servers_pool.keys(): diff --git a/server_pool.py b/server_pool.py index 4030477..27e1168 100644 --- a/server_pool.py +++ b/server_pool.py @@ -186,12 +186,12 @@ class ServerPool(object): else: logging.info("stopped server at %s:%d" % (self.config['server'], port)) try: - self.tcp_servers_pool[port].close(False) + self.tcp_servers_pool[port].close(True) del self.tcp_servers_pool[port] except Exception as e: logging.warn(e) try: - self.udp_servers_pool[port].close(False) + self.udp_servers_pool[port].close(True) del self.udp_servers_pool[port] except Exception as e: logging.warn(e) @@ -202,12 +202,12 @@ class ServerPool(object): else: logging.info("stopped server at [%s]:%d" % (self.config['server_ipv6'], port)) try: - self.tcp_ipv6_servers_pool[port].close(False) + self.tcp_ipv6_servers_pool[port].close(True) del self.tcp_ipv6_servers_pool[port] except Exception as e: logging.warn(e) try: - self.udp_ipv6_servers_pool[port].close(False) + self.udp_ipv6_servers_pool[port].close(True) del self.udp_ipv6_servers_pool[port] except Exception as e: logging.warn(e) diff --git a/shadowsocks/tcprelay.py b/shadowsocks/tcprelay.py index 1a080bb..0433669 100644 --- a/shadowsocks/tcprelay.py +++ b/shadowsocks/tcprelay.py @@ -1018,9 +1018,8 @@ class TCPRelay(object): self._server_socket.close() self._server_socket = None logging.info('closed TCP port %d', self._listen_port) - if not self._fd_to_handlers: - logging.info('stopping') - self._eventloop.stop() + for handler in list(self._fd_to_handlers.values()): + handler.destroy() self._sweep_timeout() def close(self, next_tick=False): diff --git a/shadowsocks/udprelay.py b/shadowsocks/udprelay.py index 7fb67b1..4c66ac8 100644 --- a/shadowsocks/udprelay.py +++ b/shadowsocks/udprelay.py @@ -1343,25 +1343,29 @@ class UDPRelay(object): def handle_periodic(self): if self._closed: + self._cache.clear(0) + self._dns_cache.sweep() + if self._eventloop: + self._eventloop.remove_periodic(self.handle_periodic) + self._eventloop.remove(self._server_socket) if self._server_socket: self._server_socket.close() self._server_socket = None - #for sock in self._sockets: - # sock.close() logging.info('closed UDP port %d', self._listen_port) - before_sweep_size = len(self._sockets) - self._cache.sweep() - self._dns_cache.sweep() - if before_sweep_size != len(self._sockets): - logging.debug('UDP port %5d sockets %d' % (self._listen_port, len(self._sockets))) - self._sweep_timeout() + else: + before_sweep_size = len(self._sockets) + self._cache.sweep() + self._dns_cache.sweep() + if before_sweep_size != len(self._sockets): + logging.debug('UDP port %5d sockets %d' % (self._listen_port, len(self._sockets))) + self._sweep_timeout() def close(self, next_tick=False): logging.debug('UDP close') self._closed = True if not next_tick: - self._cache.clear(0) if self._eventloop: self._eventloop.remove_periodic(self.handle_periodic) self._eventloop.remove(self._server_socket) self._server_socket.close() + self._cache.clear(0)