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

0.8.2 change, new error #12

Closed
jmbott opened this issue Aug 20, 2019 · 5 comments
Closed

0.8.2 change, new error #12

jmbott opened this issue Aug 20, 2019 · 5 comments

Comments

@jmbott
Copy link

jmbott commented Aug 20, 2019

On the latest version, 0.8.2 I am getting caught with the error, App must be running before you can run middleware!, here, but not on previous releases. Using spf as a requirement of Sanic-Cors.

Output:

Starting...
[2019-08-20 07:44:33 -0400] [66363] [DEBUG]

                 Sanic
         Build Fast. Run Fast.


[2019-08-20 07:44:33 -0400] [66363] [INFO] Goin' Fast @ http://0.0.0.0:8000
[2019-08-20 07:44:43 -0400] [66363] [ERROR] Exception occurred while handling uri: 'http://127.0.0.1:8000/'
Traceback (most recent call last):
  File ".../venv/lib/python3.7/site-packages/sanic/app.py", line 910, in handle_request
    response = await self._run_request_middleware(request)
  File ".../venv/lib/python3.7/site-packages/spf/framework.py", line 533, in _run_request_middleware
    "App must be running before you can run middleware!"
AssertionError: App must be running before you can run middleware!
[2019-08-20 07:44:43 -0400] [66363] [DEBUG] CORS: Request to '/' matches CORS resource '/*'. Using options: {'origins': ['.*'], 'methods': 'DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT', 'allow_headers': ['.*'], 'expose_headers': None, 'supports_credentials': False, 'max_age': None, 'send_wildcard': False, 'automatic_options': False, 'vary_header': True, 'resources': '/*', 'intercept_exceptions': True, 'always_send': True}
[2019-08-20 07:44:43 -0400] [66363] [DEBUG] CORS: Cannot find the request context. Is request already finished?
[2019-08-20 07:44:43 -0400] [66363] [DEBUG] CORS: Cannot find the request context. Is request already finished?
[2019-08-20 07:44:43 -0400] - (sanic.access)[INFO][127.0.0.1:54246]: GET http://127.0.0.1:8000/  500 144
[2019-08-20 07:44:48 -0400] [66363] [DEBUG] KeepAlive Timeout. Closing connection.

Python 3.7.4 (but same error with earlier versions)

sanic==19.6.2
Sanic-Cors==0.9.8.post3
Sanic-Plugins-Framework==0.8.2

Test to reproduce error:

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

import asyncio

app = Sanic(__name__)

CORS(app, resources=r'/*')

async def hello(request):
    return json({"hello": "world"})

app.add_route(
    hello,
    '/',
    methods=['GET', 'POST']
)

def run():
    loop = asyncio.get_event_loop()
    srv_coro = app.create_server(
        host='0.0.0.0',
        port=8000,
        return_asyncio_server=True,
        asyncio_server_kwargs=None,
        debug=True
    )
    asyncio.ensure_future(srv_coro)

    try:
        loop.run_forever()
    except KeyboardInterrupt:
        loop.stop()


if __name__ == '__main__':
    print('Starting...')
    run()
@ashleysommer
Copy link
Owner

Thanks for this report.

In 0.8.2 some changes needed to be made to the order some things run, to ensure compatibility with Sanic 19.6 (particularly ASGI mode), so I'm guessing theres a side-effect of that which is causing this.

I will look into it.

@ashleysommer
Copy link
Owner

Ok, so I've found the problem.

In pre-v0.8.2, the Sanic-Plugins-Framework before-run initialisation routine was configured to run on before_server_start. This worked great until ASGI support was added. In ASGI mode, the server never runs the before_server_start trigger.

So in v0.8.2 the initialisation routine was changed to run on after_server_start which is in most cases not very different in logic, and sanic.run() and ASGI mode both support it.

Unfortunately it looks like using app.create_server() like in your example, it never triggers the after_server_start event. So Sanic-Plugins-Framework never executes its initialisation routine.

I will need raise this with the Sanic devs as a potential issue going forward, particularly for plugin creators.

As a temporary fix, you can force the run of the _on_server_start method in Sanic-Plugins-Framework, like this:

from sanic import Sanic
from sanic.response import json
from sanic_cors import CORS
from spf import SanicPluginsFramework
import asyncio

app = Sanic(__name__)
spf = SanicPluginsFramework(app)
cors = spf.register_plugin(CORS, resources=r'/*')

async def hello(request):
    return json({"hello": "world"})

app.add_route(
    hello,
    '/',
    methods=['GET', 'POST']
)

def run():
    loop = asyncio.get_event_loop()
    srv_coro = app.create_server(
        host='0.0.0.0',
        port=8000,
        return_asyncio_server=True,
        asyncio_server_kwargs=None,
        debug=True
    )
    asyncio.ensure_future(srv_coro)
    spf._on_server_start(app, loop)
    try:
        loop.run_forever()
    except KeyboardInterrupt:
        loop.stop()


if __name__ == '__main__':
    print('Starting...')
    run()

@jmbott
Copy link
Author

jmbott commented Aug 22, 2019

Thanks @ashleysommer, I can confirm this works for my application.

@ashleysommer
Copy link
Owner

@jmbott I've created a post on the Sanic community forum about this issue.
https://community.sanicframework.org/t/triggering-after-server-start-event-when-running-asyncio-server/385
Feel free to join in.

@ashleysommer
Copy link
Owner

@jmbott
Good news, a fix for this in Sanic Core has been accepted, and will be in the next release of Sanic:
sanic-org/sanic#1676

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