omserv 0.0.0.dev177__py3-none-any.whl → 0.0.0.dev179__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- omserv/server/__init__.py +1 -1
- omserv/server/default.py +34 -0
- omserv/server/inject.py +21 -0
- omserv/server/{workers.py → listener.py} +76 -65
- omserv/server/multiprocess.py +1 -1
- omserv/server/{tcpserver.py → server.py} +8 -2
- {omserv-0.0.0.dev177.dist-info → omserv-0.0.0.dev179.dist-info}/METADATA +2 -2
- {omserv-0.0.0.dev177.dist-info → omserv-0.0.0.dev179.dist-info}/RECORD +12 -10
- {omserv-0.0.0.dev177.dist-info → omserv-0.0.0.dev179.dist-info}/LICENSE +0 -0
- {omserv-0.0.0.dev177.dist-info → omserv-0.0.0.dev179.dist-info}/WHEEL +0 -0
- {omserv-0.0.0.dev177.dist-info → omserv-0.0.0.dev179.dist-info}/entry_points.txt +0 -0
- {omserv-0.0.0.dev177.dist-info → omserv-0.0.0.dev179.dist-info}/top_level.txt +0 -0
omserv/server/__init__.py
CHANGED
omserv/server/default.py
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
import typing as ta
|
2
|
+
|
3
|
+
import anyio.abc
|
4
|
+
|
5
|
+
from omlish import inject as inj
|
6
|
+
|
7
|
+
from .config import Config
|
8
|
+
from .inject import bind_server
|
9
|
+
from .listener import Listener
|
10
|
+
from .sockets import Sockets
|
11
|
+
from .types import AppWrapper
|
12
|
+
from .types import AsgiFramework
|
13
|
+
from .types import wrap_app
|
14
|
+
|
15
|
+
|
16
|
+
async def serve(
|
17
|
+
app: AsgiFramework | AppWrapper,
|
18
|
+
config: Config,
|
19
|
+
*,
|
20
|
+
sockets: Sockets | None = None,
|
21
|
+
shutdown_trigger: ta.Callable[..., ta.Awaitable[None]] | None = None,
|
22
|
+
handle_shutdown_signals: bool = False,
|
23
|
+
task_status: anyio.abc.TaskStatus[ta.Sequence[str]] = anyio.TASK_STATUS_IGNORED,
|
24
|
+
) -> None:
|
25
|
+
injector = inj.create_injector(bind_server(config))
|
26
|
+
listener = injector.inject(Listener)
|
27
|
+
await listener.listen(
|
28
|
+
wrap_app(app),
|
29
|
+
config,
|
30
|
+
sockets=sockets,
|
31
|
+
shutdown_trigger=shutdown_trigger,
|
32
|
+
handle_shutdown_signals=handle_shutdown_signals,
|
33
|
+
task_status=task_status,
|
34
|
+
)
|
omserv/server/inject.py
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
import functools
|
2
|
+
|
3
|
+
from omlish import inject as inj
|
4
|
+
|
5
|
+
from .config import Config
|
6
|
+
from .server import Server
|
7
|
+
from .server import ServerFactory
|
8
|
+
|
9
|
+
|
10
|
+
def _provide_server_factory(config: Config) -> ServerFactory:
|
11
|
+
return ServerFactory(functools.partial(Server, config=config))
|
12
|
+
|
13
|
+
|
14
|
+
def bind_server(
|
15
|
+
config: Config,
|
16
|
+
) -> inj.Elemental:
|
17
|
+
return inj.as_elements(
|
18
|
+
inj.bind(config),
|
19
|
+
|
20
|
+
inj.bind(_provide_server_factory, singleton=True),
|
21
|
+
)
|
@@ -11,10 +11,10 @@ import anyio.abc
|
|
11
11
|
|
12
12
|
from .config import Config
|
13
13
|
from .lifespans import Lifespan
|
14
|
+
from .server import ServerFactory
|
14
15
|
from .sockets import Sockets
|
15
16
|
from .sockets import create_sockets
|
16
17
|
from .sockets import repr_socket_addr
|
17
|
-
from .tcpserver import TcpServer
|
18
18
|
from .types import AppWrapper
|
19
19
|
from .types import AsgiFramework
|
20
20
|
from .types import wrap_app
|
@@ -125,69 +125,80 @@ async def _install_signal_handler(
|
|
125
125
|
return signal_event.wait
|
126
126
|
|
127
127
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
128
|
+
class Listener:
|
129
|
+
def __init__(
|
130
|
+
self,
|
131
|
+
*,
|
132
|
+
server_factory: ServerFactory,
|
133
|
+
) -> None:
|
134
|
+
super().__init__()
|
135
|
+
|
136
|
+
self._server_factory = server_factory
|
137
|
+
|
138
|
+
async def listen(
|
139
|
+
self,
|
140
|
+
app: AsgiFramework | AppWrapper,
|
141
|
+
config: Config,
|
142
|
+
*,
|
143
|
+
sockets: Sockets | None = None,
|
144
|
+
shutdown_trigger: ta.Callable[..., ta.Awaitable[None]] | None = None,
|
145
|
+
handle_shutdown_signals: bool = False,
|
146
|
+
task_status: anyio.abc.TaskStatus[ta.Sequence[str]] = anyio.TASK_STATUS_IGNORED,
|
147
|
+
) -> None:
|
148
|
+
app = wrap_app(app)
|
149
|
+
|
150
|
+
lifespan = Lifespan(app, config)
|
151
|
+
max_requests = None
|
152
|
+
if config.max_requests is not None:
|
153
|
+
max_requests = config.max_requests + random.randint(0, config.max_requests_jitter)
|
154
|
+
context = WorkerContext(max_requests)
|
155
|
+
|
156
|
+
async with anyio.create_task_group() as lifespan_task_group:
|
157
|
+
if shutdown_trigger is None and handle_shutdown_signals:
|
158
|
+
shutdown_trigger = await _install_signal_handler(lifespan_task_group)
|
159
|
+
|
160
|
+
await lifespan_task_group.start(lifespan.handle_lifespan)
|
161
|
+
await lifespan.wait_for_startup()
|
162
|
+
|
163
|
+
async with anyio.create_task_group() as server_task_group:
|
164
|
+
if sockets is None:
|
165
|
+
sockets = create_sockets(config)
|
166
|
+
for sock in sockets.insecure_sockets:
|
167
|
+
sock.listen(config.backlog)
|
168
|
+
|
169
|
+
listeners = []
|
170
|
+
binds = []
|
144
171
|
|
145
|
-
async with anyio.create_task_group() as lifespan_task_group:
|
146
|
-
if shutdown_trigger is None and handle_shutdown_signals:
|
147
|
-
shutdown_trigger = await _install_signal_handler(lifespan_task_group)
|
148
|
-
|
149
|
-
await lifespan_task_group.start(lifespan.handle_lifespan)
|
150
|
-
await lifespan.wait_for_startup()
|
151
|
-
|
152
|
-
async with anyio.create_task_group() as server_task_group:
|
153
|
-
if sockets is None:
|
154
|
-
sockets = create_sockets(config)
|
155
172
|
for sock in sockets.insecure_sockets:
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
await
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
finally:
|
189
|
-
await context.terminated.set()
|
190
|
-
server_task_group.cancel_scope.deadline = anyio.current_time() + config.graceful_timeout
|
191
|
-
|
192
|
-
await lifespan.wait_for_shutdown()
|
193
|
-
lifespan_task_group.cancel_scope.cancel()
|
173
|
+
listeners.append(anyio._core._eventloop.get_async_backend().create_tcp_listener(sock)) # noqa
|
174
|
+
bind = repr_socket_addr(sock.family, sock.getsockname())
|
175
|
+
binds.append(f'http://{bind}')
|
176
|
+
log.info('Running on http://%s (CTRL + C to quit)', bind)
|
177
|
+
|
178
|
+
task_status.started(binds)
|
179
|
+
try:
|
180
|
+
async with anyio.create_task_group() as task_group:
|
181
|
+
if shutdown_trigger is not None:
|
182
|
+
task_group.start_soon(raise_shutdown, shutdown_trigger)
|
183
|
+
task_group.start_soon(raise_shutdown, context.terminate.wait)
|
184
|
+
|
185
|
+
task_group.start_soon(
|
186
|
+
functools.partial(
|
187
|
+
serve_listeners,
|
188
|
+
functools.partial(self._server_factory, app, context),
|
189
|
+
listeners,
|
190
|
+
handler_task_group=server_task_group,
|
191
|
+
),
|
192
|
+
)
|
193
|
+
|
194
|
+
await anyio.sleep_forever()
|
195
|
+
except BaseExceptionGroup as error:
|
196
|
+
_, other_errors = error.split((ShutdownError, KeyboardInterrupt)) # noqa
|
197
|
+
if other_errors is not None:
|
198
|
+
raise other_errors # noqa
|
199
|
+
finally:
|
200
|
+
await context.terminated.set()
|
201
|
+
server_task_group.cancel_scope.deadline = anyio.current_time() + config.graceful_timeout
|
202
|
+
|
203
|
+
await lifespan.wait_for_shutdown()
|
204
|
+
lifespan_task_group.cancel_scope.cancel()
|
omserv/server/multiprocess.py
CHANGED
@@ -12,11 +12,11 @@ import typing as ta
|
|
12
12
|
import anyio
|
13
13
|
|
14
14
|
from .config import Config
|
15
|
+
from .default import serve
|
15
16
|
from .sockets import Sockets
|
16
17
|
from .sockets import create_sockets
|
17
18
|
from .types import AsgiFramework
|
18
19
|
from .types import wrap_app
|
19
|
-
from .workers import serve
|
20
20
|
|
21
21
|
|
22
22
|
async def check_multiprocess_shutdown_event(
|
@@ -6,6 +6,7 @@ import typing as ta
|
|
6
6
|
import anyio.abc
|
7
7
|
|
8
8
|
from omlish import check
|
9
|
+
from omlish import lang
|
9
10
|
|
10
11
|
from .config import Config
|
11
12
|
from .events import Closed
|
@@ -25,13 +26,18 @@ log = logging.getLogger(__name__)
|
|
25
26
|
MAX_RECV = 2 ** 16
|
26
27
|
|
27
28
|
|
28
|
-
class
|
29
|
+
class ServerFactory(lang.Func3[AppWrapper, WorkerContext, anyio.abc.SocketStream, 'Server']):
|
30
|
+
pass
|
31
|
+
|
32
|
+
|
33
|
+
class Server:
|
29
34
|
def __init__(
|
30
35
|
self,
|
31
36
|
app: AppWrapper,
|
32
|
-
config: Config,
|
33
37
|
context: WorkerContext,
|
34
38
|
stream: anyio.abc.SocketStream,
|
39
|
+
*,
|
40
|
+
config: Config,
|
35
41
|
) -> None:
|
36
42
|
super().__init__()
|
37
43
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: omserv
|
3
|
-
Version: 0.0.0.
|
3
|
+
Version: 0.0.0.dev179
|
4
4
|
Summary: omserv
|
5
5
|
Author: wrmsr
|
6
6
|
License: BSD-3-Clause
|
@@ -12,7 +12,7 @@ Classifier: Operating System :: OS Independent
|
|
12
12
|
Classifier: Operating System :: POSIX
|
13
13
|
Requires-Python: >=3.12
|
14
14
|
License-File: LICENSE
|
15
|
-
Requires-Dist: omlish==0.0.0.
|
15
|
+
Requires-Dist: omlish==0.0.0.dev179
|
16
16
|
Provides-Extra: all
|
17
17
|
Requires-Dist: h11~=0.14; extra == "all"
|
18
18
|
Requires-Dist: h2~=4.1; extra == "all"
|
@@ -21,20 +21,22 @@ omserv/node/models.py,sha256=EOaq-aW1rbGOzHTmTULhbVwV5j_burL07qh2QO9smdM,1273
|
|
21
21
|
omserv/node/registry.py,sha256=y67VMowll9IuLiTVgauAcbP8-evFJNqpwocwwt7kZL4,3478
|
22
22
|
omserv/node/sql.py,sha256=vy7RP50JiH3jQHMVa7Hxk0pFJK3QcbGeTvyNppB1W4I,2826
|
23
23
|
omserv/server/LICENSE,sha256=VKPNmbyrS9wcwcx20hBlVtLP01brb2dByHrWHeNLPag,1050
|
24
|
-
omserv/server/__init__.py,sha256=
|
24
|
+
omserv/server/__init__.py,sha256=jrFdrxfnQwjK5DW5y9w0alw6IKToGn2IQyZDhsuGHv4,372
|
25
25
|
omserv/server/config.py,sha256=oGWL1kuk45bJ6sVr8n3ow5Q-1nz9EqByjoykU2iOHIY,1189
|
26
26
|
omserv/server/debug.py,sha256=N7RI0Jj-ttmys3DJD0RREmGG5XZpTCp6y9Yu0x98Agg,299
|
27
|
+
omserv/server/default.py,sha256=hmfy--Q35QFMU8oTf4uHwVM2qBFG8mQDR9Wik2f1yZk,970
|
27
28
|
omserv/server/events.py,sha256=VMr_rArsVjJYnyH9SqLWtOLUg18vSu1O0ep9gNBGR_c,1369
|
28
29
|
omserv/server/headers.py,sha256=3H-NxMMQg5WuF5wF4AWFUEqkToh4NqNqHouavzbOQok,1188
|
30
|
+
omserv/server/inject.py,sha256=mD3MIDd44_nr1mIiDfjzgJ4DCBeD3JILN6STTDNReGc,454
|
29
31
|
omserv/server/lifespans.py,sha256=kRVxDQM18jCBzRUpafyb69q_bGSCyxxjAtrkxjqcZdE,4607
|
30
|
-
omserv/server/
|
32
|
+
omserv/server/listener.py,sha256=t_wUlS6pXnRn-aEXV8D8jhWAeIlQ3a3Sx9i_0BOKV70,7033
|
33
|
+
omserv/server/multiprocess.py,sha256=qvNFQEMpTXXR5ACdja4JVC0HFgdvb8CL94iKLDYvZ48,4253
|
34
|
+
omserv/server/server.py,sha256=hgUTfZAUwF7V-HdsdV98KbYmE1IRKmEO3B1LlKTiPWc,5223
|
31
35
|
omserv/server/sockets.py,sha256=lwqNP7URlp605ibsjHzp0pc-lyjcyTu-hD-uyojLUYk,3389
|
32
36
|
omserv/server/ssl.py,sha256=gmB5ecM8Mck-YtGYF8pb2dwFdjABVGzERFCDzM9lBck,1483
|
33
37
|
omserv/server/taskspawner.py,sha256=ljzF26UPtnp7GLAY_BvjzuwCoCO9aL7TKLwRNTmUy1M,3008
|
34
|
-
omserv/server/tcpserver.py,sha256=akC-2WOhmoIiJBH0Ti0m1uK_sOTBYGie0CoRkEcUmkA,5082
|
35
38
|
omserv/server/types.py,sha256=XXY5py8RYlEeD4FZrWNqSyX7DD-ffSlcG-T2s9BY9eI,2017
|
36
39
|
omserv/server/workercontext.py,sha256=4rcLuGsyiU7URO7T_eHylOBPPNUS9C23QfEUVyJUtIY,1200
|
37
|
-
omserv/server/workers.py,sha256=rdV8qEzWKMZ6HnN9nUoGS58U9LRsrsqOcAd_7yl73Y0,6586
|
38
40
|
omserv/server/protocols/__init__.py,sha256=Ryu2PDZ1TUI6F2l-HBEYgyzZ7wHqE6VmjqnS0tIvmQI,47
|
39
41
|
omserv/server/protocols/h11.py,sha256=_q_paD-ff0AWJEPaNK-6MUsQVtYRiALnWGwFyM3D0KU,11976
|
40
42
|
omserv/server/protocols/h2.py,sha256=bC-qmRQqgLASL1DtF3UX1ozximHH4xtae1d_vN2PffY,15345
|
@@ -46,9 +48,9 @@ omserv/server/streams/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
|
|
46
48
|
omserv/server/streams/httpstream.py,sha256=0DeiAPLGbEGNa0fHTs8lUpi_CFZs4M5_QB-TiS8mobQ,8015
|
47
49
|
omserv/server/streams/utils.py,sha256=aMOrqWIg_Hht5W4kLg3y7oR5AEkVvMrZhyjzo6U5owE,1527
|
48
50
|
omserv/server/streams/wsstream.py,sha256=3Vyzox7dCE1tDSXjb6xBubWo41ZF9d38Hrsrlj6h1J8,15482
|
49
|
-
omserv-0.0.0.
|
50
|
-
omserv-0.0.0.
|
51
|
-
omserv-0.0.0.
|
52
|
-
omserv-0.0.0.
|
53
|
-
omserv-0.0.0.
|
54
|
-
omserv-0.0.0.
|
51
|
+
omserv-0.0.0.dev179.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
52
|
+
omserv-0.0.0.dev179.dist-info/METADATA,sha256=fd2btbHerGBDD_T9ETQdAMBb8XAoY3eo1tVDqQHIrbQ,983
|
53
|
+
omserv-0.0.0.dev179.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
54
|
+
omserv-0.0.0.dev179.dist-info/entry_points.txt,sha256=ivSrdA_ahEbI-eVMu-XZS-z4VrnQISvpecIkOqC9zFM,35
|
55
|
+
omserv-0.0.0.dev179.dist-info/top_level.txt,sha256=HXehpnxeKscKNULzKNzZ27oNawBrsh1PaNAirbX-XNA,7
|
56
|
+
omserv-0.0.0.dev179.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|