omserv 0.0.0.dev177__tar.gz → 0.0.0.dev179__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. {omserv-0.0.0.dev177/omserv.egg-info → omserv-0.0.0.dev179}/PKG-INFO +2 -2
  2. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/__init__.py +1 -1
  3. omserv-0.0.0.dev179/omserv/server/default.py +34 -0
  4. omserv-0.0.0.dev179/omserv/server/inject.py +21 -0
  5. omserv-0.0.0.dev177/omserv/server/workers.py → omserv-0.0.0.dev179/omserv/server/listener.py +76 -65
  6. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/multiprocess.py +1 -1
  7. omserv-0.0.0.dev177/omserv/server/tcpserver.py → omserv-0.0.0.dev179/omserv/server/server.py +8 -2
  8. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179/omserv.egg-info}/PKG-INFO +2 -2
  9. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv.egg-info/SOURCES.txt +4 -2
  10. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv.egg-info/requires.txt +1 -1
  11. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/pyproject.toml +2 -2
  12. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/LICENSE +0 -0
  13. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/MANIFEST.in +0 -0
  14. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/README.rst +0 -0
  15. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/.manifests.json +0 -0
  16. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/__about__.py +0 -0
  17. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/__init__.py +0 -0
  18. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/apps/__init__.py +0 -0
  19. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/apps/base.py +0 -0
  20. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/apps/inject.py +0 -0
  21. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/apps/markers.py +0 -0
  22. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/apps/routes.py +0 -0
  23. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/apps/sessions.py +0 -0
  24. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/apps/templates.py +0 -0
  25. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/daemon/__init__.py +0 -0
  26. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/nginx/__init__.py +0 -0
  27. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/nginx/build.py +0 -0
  28. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/nginx/configs.py +0 -0
  29. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/nginx/logs.py +0 -0
  30. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/nginx/patches/__init__.py +0 -0
  31. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/nginx/patches/nginx-1.27.3_http_status.patch +0 -0
  32. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/nginx/stubstatus.py +0 -0
  33. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/node/__init__.py +0 -0
  34. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/node/models.py +0 -0
  35. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/node/registry.py +0 -0
  36. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/node/sql.py +0 -0
  37. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/LICENSE +0 -0
  38. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/config.py +0 -0
  39. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/debug.py +0 -0
  40. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/events.py +0 -0
  41. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/headers.py +0 -0
  42. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/lifespans.py +0 -0
  43. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/protocols/__init__.py +0 -0
  44. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/protocols/h11.py +0 -0
  45. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/protocols/h2.py +0 -0
  46. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/protocols/protocols.py +0 -0
  47. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/protocols/types.py +0 -0
  48. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/resources/__init__.py +0 -0
  49. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/resources/favicon.ico +0 -0
  50. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/sockets.py +0 -0
  51. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/ssl.py +0 -0
  52. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/streams/__init__.py +0 -0
  53. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/streams/httpstream.py +0 -0
  54. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/streams/utils.py +0 -0
  55. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/streams/wsstream.py +0 -0
  56. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/taskspawner.py +0 -0
  57. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/types.py +0 -0
  58. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv/server/workercontext.py +0 -0
  59. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv.egg-info/dependency_links.txt +0 -0
  60. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv.egg-info/entry_points.txt +0 -0
  61. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/omserv.egg-info/top_level.txt +0 -0
  62. {omserv-0.0.0.dev177 → omserv-0.0.0.dev179}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omserv
3
- Version: 0.0.0.dev177
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.dev177
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"
@@ -15,4 +15,4 @@ See:
15
15
  - https://github.com/tiangolo/fastapi
16
16
  """
17
17
  from .config import Config # noqa
18
- from .workers import serve # noqa
18
+ from .default import serve # noqa
@@ -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
+ )
@@ -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
- async def serve(
129
- app: AsgiFramework | AppWrapper,
130
- config: Config,
131
- *,
132
- sockets: Sockets | None = None,
133
- shutdown_trigger: ta.Callable[..., ta.Awaitable[None]] | None = None,
134
- handle_shutdown_signals: bool = False,
135
- task_status: anyio.abc.TaskStatus[ta.Sequence[str]] = anyio.TASK_STATUS_IGNORED,
136
- ) -> None:
137
- app = wrap_app(app)
138
-
139
- lifespan = Lifespan(app, config)
140
- max_requests = None
141
- if config.max_requests is not None:
142
- max_requests = config.max_requests + random.randint(0, config.max_requests_jitter)
143
- context = WorkerContext(max_requests)
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
- sock.listen(config.backlog)
157
-
158
- listeners = []
159
- binds = []
160
-
161
- for sock in sockets.insecure_sockets:
162
- listeners.append(anyio._core._eventloop.get_async_backend().create_tcp_listener(sock)) # noqa
163
- bind = repr_socket_addr(sock.family, sock.getsockname())
164
- binds.append(f'http://{bind}')
165
- log.info('Running on http://%s (CTRL + C to quit)', bind)
166
-
167
- task_status.started(binds)
168
- try:
169
- async with anyio.create_task_group() as task_group:
170
- if shutdown_trigger is not None:
171
- task_group.start_soon(raise_shutdown, shutdown_trigger)
172
- task_group.start_soon(raise_shutdown, context.terminate.wait)
173
-
174
- task_group.start_soon(
175
- functools.partial(
176
- serve_listeners,
177
- functools.partial(TcpServer, app, config, context),
178
- listeners,
179
- handler_task_group=server_task_group,
180
- ),
181
- )
182
-
183
- await anyio.sleep_forever()
184
- except BaseExceptionGroup as error:
185
- _, other_errors = error.split((ShutdownError, KeyboardInterrupt)) # noqa
186
- if other_errors is not None:
187
- raise other_errors # noqa
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()
@@ -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 TcpServer:
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.dev177
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.dev177
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"
@@ -34,17 +34,19 @@ omserv/server/LICENSE
34
34
  omserv/server/__init__.py
35
35
  omserv/server/config.py
36
36
  omserv/server/debug.py
37
+ omserv/server/default.py
37
38
  omserv/server/events.py
38
39
  omserv/server/headers.py
40
+ omserv/server/inject.py
39
41
  omserv/server/lifespans.py
42
+ omserv/server/listener.py
40
43
  omserv/server/multiprocess.py
44
+ omserv/server/server.py
41
45
  omserv/server/sockets.py
42
46
  omserv/server/ssl.py
43
47
  omserv/server/taskspawner.py
44
- omserv/server/tcpserver.py
45
48
  omserv/server/types.py
46
49
  omserv/server/workercontext.py
47
- omserv/server/workers.py
48
50
  omserv/server/protocols/__init__.py
49
51
  omserv/server/protocols/h11.py
50
52
  omserv/server/protocols/h2.py
@@ -1,4 +1,4 @@
1
- omlish==0.0.0.dev177
1
+ omlish==0.0.0.dev179
2
2
 
3
3
  [all]
4
4
  h11~=0.14
@@ -12,7 +12,7 @@ authors = [
12
12
  urls = {source = 'https://github.com/wrmsr/omlish'}
13
13
  license = {text = 'BSD-3-Clause'}
14
14
  requires-python = '>=3.12'
15
- version = '0.0.0.dev177'
15
+ version = '0.0.0.dev179'
16
16
  classifiers = [
17
17
  'License :: OSI Approved :: BSD License',
18
18
  'Development Status :: 2 - Pre-Alpha',
@@ -22,7 +22,7 @@ classifiers = [
22
22
  ]
23
23
  description = 'omserv'
24
24
  dependencies = [
25
- 'omlish == 0.0.0.dev177',
25
+ 'omlish == 0.0.0.dev179',
26
26
  ]
27
27
 
28
28
  [project.optional-dependencies]
File without changes
File without changes
File without changes
File without changes