forked from jonashaag/bjoern
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bjoern.py
84 lines (69 loc) · 2.64 KB
/
bjoern.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import os
import socket
import _bjoern
_default_instance = None
LISTEN_BACKLOG = 1024
def bind_and_listen(host, port=None, reuse_port=False):
if host.startswith("unix:@"):
# Abstract UNIX socket: "unix:@foobar"
sock = socket.socket(socket.AF_UNIX)
sock.bind('\0' + host[6:])
elif host.startswith("unix:"):
# UNIX socket: "unix:/tmp/foobar.sock"
sock = socket.socket(socket.AF_UNIX)
sock.bind(host[5:])
else:
# IP socket
sock = socket.socket(socket.AF_INET)
# Set SO_REUSEADDR to make the IP address available for reuse
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if reuse_port:
# Enable "receive steering" on FreeBSD and Linux >=3.9. This allows
# multiple independent bjoerns to bind to the same port (and ideally
# also set their CPU affinity), resulting in more efficient load
# distribution. https://lwn.net/Articles/542629/
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
sock.bind((host, port))
sock.listen(LISTEN_BACKLOG)
return sock
def server_run(sock, wsgi_app):
_bjoern.server_run(sock, wsgi_app)
# Backwards compatibility API
def listen(wsgi_app, host, port=None, reuse_port=False):
"""
Makes bjoern listen to 'host:port' and use 'wsgi_app' as WSGI application.
(This does not run the server mainloop.)
'reuse_port' -- whether to set SO_REUSEPORT (if available on platform)
"""
global _default_instance
if _default_instance:
raise RuntimeError("Only one global server instance possible")
sock = bind_and_listen(host, port, reuse_port)
_default_instance = (sock, wsgi_app)
def run(*args, **kwargs):
"""
run(*args, **kwargs):
Calls listen(*args, **kwargs) and starts the server mainloop.
run():
Starts the server mainloop. listen(...) has to be called before calling
run() without arguments."
"""
global _default_instance
if args or kwargs:
# Called as `bjoern.run(wsgi_app, host, ...)`
listen(*args, **kwargs)
else:
# Called as `bjoern.run()`
if not _default_instance:
raise RuntimeError("Must call bjoern.listen(wsgi_app, host, ...) "
"before calling bjoern.run() without arguments.")
sock, wsgi_app = _default_instance
try:
server_run(sock, wsgi_app)
finally:
if sock.family == socket.AF_UNIX:
filename = sock.getsockname()
if filename[0] != '\0':
os.unlink(sock.getsockname())
sock.close()
_default_instance = None