Unable to run two apps with Application multi-serve in dev mode
gmrmn opened this issue · comments
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
Hello,
I am trying to run Sanic as a script with two applications on board via Sanic.serve()
. Applications are prepared to serve on different ports and development mode is enabled for both of them (see the snippet and additional context below).
When I fire the script and hit the endpoint of the second app I get Server Error:
curl localhost:80/hello
world%
curl localhost:81/metrics
curl: (52) Empty reply from server
The log:
python test_two.py
[2023-09-08 11:42:52 +0300] [5436] [DEBUG] Creating multiprocessing context using 'spawn'
[2023-09-08 11:42:52 +0300] [5436] [DEBUG] Starting a process: Sanic-Server-0-0
[2023-09-08 11:42:52 +0300] [5436] [DEBUG] Starting a process: Sanic-Reloader-0
[2023-09-08 11:42:53 +0300] [5441] [DEBUG] Process ack: Sanic-Server-0-0 [5441]
[2023-09-08 11:42:53 +0300] [5441] [INFO] Starting worker [5441]
[2023-09-08 11:43:06 +0300] [5441] [ERROR] protocol.connection_task uncaught
Traceback (most recent call last):
File "/Users/test/venv/lib/python3.10/site-packages/sanic/signals.py", line 99, in get
group, param_basket = self.find_route(
File "", line 22, in find_route
sanic_routing.exceptions.NotFound: Not Found
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/test/venv/lib/python3.10/site-packages/sanic/server/protocols/http_protocol.py", line 148, in connection_task
await self.app.dispatch(
File "/Users/test/venv/lib/python3.10/site-packages/sanic/signals.py", line 208, in dispatch
return await dispatch
File "/Users/test/venv/lib/python3.10/site-packages/sanic/signals.py", line 141, in _dispatch
raise e
File "/Users/test/venv/lib/python3.10/site-packages/sanic/signals.py", line 137, in _dispatch
group, handlers, params = self.get(event, condition=condition)
File "/Users/test/venv/lib/python3.10/site-packages/sanic/signals.py", line 112, in get
raise NotFound(message % tuple(terms))
sanic_routing.exceptions.NotFound: Could not find signal http.lifecycle.begin
Task exception was never retrieved
future: <Task finished name='Task-7' coro=<HttpProtocol.connection_task() done, defined at /Users/test/venv/lib/python3.10/site-packages/sanic/server/protocols/http_protocol.py:139> exception=NotFound('Could not find signal http.lifecycle.complete') created at /Users/test/venv/lib/python3.10/site-packages/sanic/server/protocols/http_protocol.py:265>
source_traceback: Object created at (most recent call last):
File "<string>", line 1, in <module>
File "/usr/local/Cellar/python@3.10/3.10.12_1/Frameworks/Python.framework/Versions/3.10/lib/python3.10/multiprocessing/spawn.py", line 116, in spawn_main
exitcode = _main(fd, parent_sentinel)
File "/usr/local/Cellar/python@3.10/3.10.12_1/Frameworks/Python.framework/Versions/3.10/lib/python3.10/multiprocessing/spawn.py", line 129, in _main
return self._bootstrap(parent_sentinel)
File "/usr/local/Cellar/python@3.10/3.10.12_1/Frameworks/Python.framework/Versions/3.10/lib/python3.10/multiprocessing/process.py", line 314, in _bootstrap
self.run()
File "/usr/local/Cellar/python@3.10/3.10.12_1/Frameworks/Python.framework/Versions/3.10/lib/python3.10/multiprocessing/process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "/Users/test/venv/lib/python3.10/site-packages/sanic/worker/serve.py", line 117, in worker_serve
return _serve_http_1(
File "/Users/test/venv/lib/python3.10/site-packages/sanic/server/runners.py", line 264, in _serve_http_1
_run_server_forever(
File "/Users/test/venv/lib/python3.10/site-packages/sanic/server/runners.py", line 145, in _run_server_forever
loop.run_forever()
File "/Users/test/venv/lib/python3.10/site-packages/sanic/server/protocols/http_protocol.py", line 265, in connection_made
self._task = self.loop.create_task(self.connection_task())
Traceback (most recent call last):
File "/Users/test/venv/lib/python3.10/site-packages/sanic/signals.py", line 99, in get
group, param_basket = self.find_route(
File "", line 22, in find_route
sanic_routing.exceptions.NotFound: Not Found
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/test/venv/lib/python3.10/site-packages/sanic/server/protocols/http_protocol.py", line 177, in connection_task
await self.app.dispatch(
File "/Users/test/venv/lib/python3.10/site-packages/sanic/signals.py", line 208, in dispatch
return await dispatch
File "/Users/test/venv/lib/python3.10/site-packages/sanic/signals.py", line 141, in _dispatch
raise e
File "/Users/test/venv/lib/python3.10/site-packages/sanic/signals.py", line 137, in _dispatch
group, handlers, params = self.get(event, condition=condition)
File "/Users/test/venv/lib/python3.10/site-packages/sanic/signals.py", line 112, in get
raise NotFound(message % tuple(terms))
sanic_routing.exceptions.NotFound: Could not find signal http.lifecycle.complete
Code snippet
# test/test_two.py
from sanic import Sanic, response
app1 = Sanic("app1")
@app1.get("/hello")
async def get(_):
return response.text("world")
app2 = Sanic("app2")
@app2.get("/metrics")
async def get(_):
return response.text("metrics")
if __name__ == "__main__":
app1.prepare("0.0.0.0", port=80, motd=False, dev=True)
app2.prepare("0.0.0.0", port=81, motd=False, dev=True)
Sanic.serve(primary=app1)
Expected Behavior
curl http://localhost:80/hello
world
curl http://localhost:81/metrics
metrics
How do you run Sanic?
As a script (app.run
or Sanic.serve
)
Operating System
MacOS
Sanic Version
Sanic 23.6.0; Routing 23.6.0
Additional context
(!) The problem appears only when dev=True
applied to the first or both apps.
These configurations cause exceptions:
app1.prepare("0.0.0.0", port=80, motd=False, dev=True)
app2.prepare("0.0.0.0", port=81, motd=False, dev=True)
# or
app1.prepare("0.0.0.0", port=80, motd=False, dev=True)
app2.prepare("0.0.0.0", port=81, motd=False)
These don't (works fine):
app1.prepare("0.0.0.0", port=80, motd=False)
app2.prepare("0.0.0.0", port=81, motd=False, dev=True)
# or
app1.prepare("0.0.0.0", port=80, motd=False)
app2.prepare("0.0.0.0", port=81, motd=False)
Confirmed the problem. I believe the solution is to give a secondary app startup method, and in that set signal_router.allow_fail_builtin = False
.