Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SPF error when using Asyncio server instance #49

Open
WoodyFleurant opened this issue Sep 3, 2020 · 3 comments
Open

SPF error when using Asyncio server instance #49

WoodyFleurant opened this issue Sep 3, 2020 · 3 comments

Comments

@WoodyFleurant
Copy link

WoodyFleurant commented Sep 3, 2020

Following official documentation from Sanic , it is not possible to use CORS plugin with AsyncIO server instanciation.

Doing the following will provoke a crash, and server won't be able to process requests : "Error is SPF processing a request before App server is started."

import asyncio
import socket
import os

from sanic import Sanic
from sanic.response import json
from sanic_cors import CORS

app = Sanic(__name__)
CORS(app)

@app.route("/")
async def test(request):
    return json({"hello": "world"})


server_socket = '/tmp/sanic.sock'

sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)

try:
    os.remove(server_socket)
finally:
    sock.bind(server_socket)

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    srv_coro = app.create_server(
        sock=sock,
        return_asyncio_server=True,
        asyncio_server_kwargs=dict(
            start_serving=False
        )
    )
    srv = loop.run_until_complete(srv_coro)
    try:
        assert srv.is_serving() is False
        loop.run_until_complete(srv.start_serving())
        assert srv.is_serving() is True
        loop.run_until_complete(srv.serve_forever())
    except KeyboardInterrupt:
        srv.close()
        loop.close()
@ashleysommer
Copy link
Owner

ashleysommer commented Sep 3, 2020

This is very similar to this bug: ashleysommer/sanic-plugin-toolkit#12
This is a SanicPluginsFramework issue, not specifically caused by Sanic-CORS.

This bug is triggered because starting Sanic in non-standard ways does not trigger the before_server_start or after_server_start events. So any listeners waiting for those events never get triggered. Another similar problem is mentioned in #47.

You can manually trigger the on_server_start listener from Sanic-Plugins-Framework, you can use the same workaround that is mentioned in ashleysommer/sanic-plugin-toolkit#12 (comment)

import asyncio
import socket
import os

from sanic import Sanic
from sanic.response import json
from sanic_cors import CORS
from spf import SanicPluginsFramework #<- this is added

app = Sanic(__name__)
spf = SanicPluginsFramework(app) #<- this is added
cors = spf.register_plugin(CORS) #<- this is changed

@app.route("/")
async def test(request):
    return json({"hello": "world"})

server_socket = '/tmp/sanic.sock'

sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)

try:
    os.remove(server_socket)
finally:
    sock.bind(server_socket)

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    srv_coro = app.create_server(
        sock=sock,
        return_asyncio_server=True,
        asyncio_server_kwargs=dict(
            start_serving=False
        )
    )
    srv = loop.run_until_complete(srv_coro)
    try:
        assert srv.is_serving() is False
        spf._on_server_start(app, loop) #<- this is added
        loop.run_until_complete(srv.start_serving())
        assert srv.is_serving() is True
        loop.run_until_complete(srv.serve_forever())
    except KeyboardInterrupt:
        srv.close()
        loop.close()

@WoodyFleurant
Copy link
Author

Thanks for your quick answer, really appreciated. Would you suggest that I add documentation about this use case in this project or in Sanic ?

@ashleysommer
Copy link
Owner

Documentation about this really should go in the Sanic Plugins Framework project.
The issue is caused by spf not receiving signal that the app started up, and the solution is to manually trigger _on_server_start() of the spf object. However most people probably wouldn't immediately go to the SPF docs to read about about it if they're seeing this problem. It might be a documentation problem with Sanic, because the docs don't currently mention that this way of starting sanic might break plugins which expect Sanic to behave in a conventional way.
See this recent issue which is another side-effect of using the create_server() method: sanic-org/sanic#1925

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants