def make_listener(endpoint: EndpointConfiguration) -> socket.socket: try: return einhorn.get_socket() except (einhorn.NotEinhornWorker, IndexError): # we're not under einhorn or it didn't bind any sockets for us pass sock = socket.socket(endpoint.family, socket.SOCK_STREAM) # configure the socket to be auto-closed if we exec() e.g. on reload flags = fcntl.fcntl(sock.fileno(), fcntl.F_GETFD) fcntl.fcntl(sock.fileno(), fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # on linux, SO_REUSEPORT is supported for IPv4 and IPv6 but not other # families. we prefer it when available because it more evenly spreads load # among multiple processes sharing a port. (though it does have some # downsides, specifically regarding behaviour during restarts) if endpoint.family in (socket.AF_INET, socket.AF_INET6): sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) sock.bind(endpoint.address) sock.listen(128) return sock
def make_listener(endpoint: EndpointConfiguration) -> socket.socket: try: return einhorn.get_socket() except (einhorn.NotEinhornWorker, IndexError): # we're not under einhorn or it didn't bind any sockets for us pass return bind_socket(endpoint)
def __init__(self, cfg, app): listener = einhorn.get_socket() super(EinhornSyncWorker, self).__init__( age=0, ppid=os.getppid(), sockets=[listener], app=app, timeout=None, cfg=cfg, log=cfg.logger_class(cfg), )
def test_get_socket_out_of_bounds(self): with self.assertRaises(IndexError): einhorn.get_socket(-1) with self.assertRaises(IndexError): einhorn.get_socket(2)
def test_get_socket_unix(self, fromfd): sock = einhorn.get_socket(1) fromfd.assert_called_with(6, socket.AF_UNIX, socket.SOCK_STREAM) self.assertEqual(sock, fromfd.return_value)
def test_get_socket(self, fromfd): sock = einhorn.get_socket() fromfd.assert_called_with(5, socket.AF_INET, socket.SOCK_STREAM) self.assertEqual(sock, fromfd.return_value)
def test_get_socket(self): with self.assertRaises(einhorn.NotEinhornWorker): einhorn.get_socket()