sanic-org / sanic

Accelerate your web app development | Build fast. Run fast.
https://sanic.dev
MIT License
18.01k stars 1.54k forks source link

simple shared_ctx example hangs #2789

Closed themanifold closed 1 year ago

themanifold commented 1 year ago

Is there an existing issue for this?

Describe the bug

Executing the code snippet and running curl against the endpoint gives curl: (52) Empty reply from server when I perform a curl request curl localhost:6677 the first time, then hangs the second time.

The above code is run using the sanic CLI.

I found the following ticket https://github.com/sanic-org/sanic/issues/2751 where someone works around this issue by adding Sanic.start_method = "fork" into the code, but the official documentation does not ever state this, and it seems like this is a regression as sanic was moved to the SpawnContext recently.

Code snippet

from multiprocessing import Queue

from sanic import Sanic
from sanic.response import text

app = Sanic(__name__)

@app.get('/')
async def index(request):
    request.app.shared_ctx.queue.put(1)
    return text('Hello')

@app.main_process_start
async def main_start(app):
    app.shared_ctx.queue = Queue()

Expected Behavior

Hello to be returned from a curl command

How do you run Sanic?

Sanic CLI

Operating System

Linux

Sanic Version

Sanic 23.3.0; Routing 22.8.0

Additional context

Pretty major regression if this is true, probably could do with more tests around this feature.

I tested this on every version since shared_ctx was introduced in 22.9 but they all show this behaviour.

ahopkins commented 1 year ago

This will be resolved by this PR: https://github.com/sanic-org/sanic/pull/2776. Release coming soon.

In the meantime, you can do this:

from multiprocessing import Manager

@app.main_process_start
async def main_start(app: Sanic):
    app.ctx.manager = Manager()
    app.shared_ctx.queue = app.ctx.manager.Queue()

@app.main_process_stop
async def main_stop(app: Sanic):
    app.ctx.manager.shutdown()