Possible for BlackSheep to use SO_REUSEPORT? #234
-
For a long time, I've been using aiohttp for many of my web services. A few years ago, I found that I could significantly improve its performance by using SO_REUSEPORT (Linux only) so that my backend made use of all available CPU cores. BlackSheep performance is already impressive but I'm wondering if it would be possible to do something similar with it. It is accomplished in aiohttp as: import asyncio
import os
import socket
import time
import traceback
from aiohttp import web
from concurrent.futures import ProcessPoolExecutor
from multiprocessing import cpu_count
CPU_COUNT = cpu_count()
print("CPU Count:", CPU_COUNT)
def mk_socket(host="127.0.0.1", port=80):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, 15, 1)
sock.bind((host, port))
return sock
async def handle(request):
name = request.match_info.get('name', "Anonymous")
pid = os.getpid()
text = "{:.2f}: Hello {}! Process {} is treating you\n".format(time.time(), name, pid)
return web.Response(text=text)
async def start_server():
try:
host = "0.0.0.0"
port = 8000
app = web.Application()
app.add_routes([web.get('/', handle)])
runner = web.AppRunner(app)
await runner.setup()
sock = mk_socket(host, port)
srv = web.SockSite(runner, sock)
await srv.start()
print(f"Server started at http://{host}:{port}")
return srv, app, runner
except Exception:
traceback.print_exc()
raise
async def finalize(srv, app, runner):
sock = srv.sockets[0]
app.loop.remove_reader(sock.fileno())
sock.close()
await runner.cleanup()
srv.close()
await srv.wait_closed()
await app.finish()
def init():
loop = asyncio.get_event_loop()
srv, app, runner = loop.run_until_complete(start_server())
try:
loop.run_forever()
except KeyboardInterrupt:
loop.run_until_complete((finalize(srv, app, runner)))
if __name__ == '__main__':
with ProcessPoolExecutor() as executor:
for i in range(0, CPU_COUNT):
executor.submit(init) |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Hi @bitnom It seems that Uvicorn reuses ports by default, but I cannot find |
Beta Was this translation helpful? Give feedback.
Hi @bitnom
When I first implemented BlackSheep, it included an implementation of HTTP Server and it was handling this kind of details like port reuse (I was indeed using port reuse by default).
But since I implemented support for ASGI HTTP Server in version
0.1.2
and I removed the implementation of the HTTP Server, the framework is not concerned anymore with handling of these details. The question about port reuse is not applicable to BlackSheep at the moment: it depends on the ASGI server that you use to run the application.It seems that Uvicorn reuses ports by default, but I cannot find
SO_REUSEPORT
in its code base.