Now tracks handlers instead of socks, moved actual instancing, improved stop, improved error handling and offloaded error-handling function to Shared/Utils
This commit is contained in:
parent
126c17475f
commit
f4f9d06880
1 changed files with 19 additions and 31 deletions
|
@ -4,6 +4,7 @@ import Logging
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
from Utils import capture_trace
|
from Utils import capture_trace
|
||||||
|
from Utils import is_socket_related_error
|
||||||
import socket
|
import socket
|
||||||
import _thread
|
import _thread
|
||||||
|
|
||||||
|
@ -14,7 +15,7 @@ class Server:
|
||||||
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
self.sock.bind(host_port_pair)
|
self.sock.bind(host_port_pair)
|
||||||
self.sock.listen(2)
|
self.sock.listen(2)
|
||||||
self.socks = []
|
self.handlers = []
|
||||||
self.debug = debug
|
self.debug = debug
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,43 +23,30 @@ class Server:
|
||||||
self.handler = handler
|
self.handler = handler
|
||||||
while 1:
|
while 1:
|
||||||
sock, info = self.sock.accept()
|
sock, info = self.sock.accept()
|
||||||
self.socks.append(sock)
|
sock = ESock(sock) if not self.debug else ESock(sock, debug=self.debug)
|
||||||
_thread.start_new_thread(self.controller, (sock, info, handler_args))
|
handler = self.handler(sock, info, **handler_args)
|
||||||
|
self.handlers.append(handler)
|
||||||
|
_thread.start_new_thread(self.controller, (handler, ))
|
||||||
|
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
for sock in self.socks:
|
for handler in self.handlers:
|
||||||
try:
|
self.attempt_graceful_close(handler, handler.sock)
|
||||||
sock.close()
|
|
||||||
except (socket.error, OSError):
|
|
||||||
pass
|
|
||||||
self.sock.close()
|
|
||||||
|
|
||||||
def controller(self, sock, info, handler_args):
|
|
||||||
sock = ESock(sock) if not self.debug else ESock(sock, debug=self.debug)
|
def controller(self, handler):
|
||||||
handler = self.handler(sock, info, **handler_args)
|
|
||||||
while 1:
|
while 1:
|
||||||
try:
|
try:
|
||||||
data, route = sock.recv()
|
data, route = handler.sock.recv()
|
||||||
handler.handle(data, route)
|
handler.handle(data, route)
|
||||||
except (BrokenPipeError, ConnectionResetError, OSError) as e:
|
except Exception as e:
|
||||||
socket_related_error = True
|
if not is_socket_related_error(e):
|
||||||
if type(e) not in (BrokenPipeError, ConnectionResetError, OSError):
|
self.print_trace(handler.sock)
|
||||||
socket_related_error = False
|
self.attempt_graceful_close(handler, handler.sock)
|
||||||
if type(e) is OSError:
|
|
||||||
if str(e) not in ("Connection closed", "[Errno 9] Bad file descriptor"):
|
|
||||||
socket_related_error = False
|
|
||||||
if not socket_related_error:
|
|
||||||
self.print_trace(handler, sock)
|
|
||||||
self.attempt_graceful_close(handler, sock)
|
|
||||||
_thread.exit()
|
|
||||||
except Exception:
|
|
||||||
self.print_trace(handler, sock)
|
|
||||||
self.attempt_graceful_close(handler, sock)
|
|
||||||
_thread.exit()
|
_thread.exit()
|
||||||
|
|
||||||
|
|
||||||
def print_trace(self, handler, sock):
|
def print_trace(self, sock):
|
||||||
Logging.error("An unhandled exception forced the controller for '%s:%d' to terminate." % (sock.address, sock.port))
|
Logging.error("An unhandled exception forced the controller for '%s:%d' to terminate." % (sock.address, sock.port))
|
||||||
capture_trace()
|
capture_trace()
|
||||||
|
|
||||||
|
@ -69,9 +57,9 @@ class Server:
|
||||||
except Exception:
|
except Exception:
|
||||||
self.print_trace(handler, sock)
|
self.print_trace(handler, sock)
|
||||||
finally:
|
finally:
|
||||||
if sock in self.socks:
|
if handler in self.handlers:
|
||||||
del self.socks[self.socks.index(sock)]
|
del self.handlers[self.handlers.index(handler)]
|
||||||
sock.close()
|
handler.sock.close()
|
||||||
|
|
||||||
|
|
||||||
class Handler:
|
class Handler:
|
||||||
|
|
Reference in a new issue