ashleysommer / sanic-synchro-ctx

Plugin to provide an App context that is shared across multiple workers
MIT License
4 stars 0 forks source link

'types.SimpleNamespace' object has no attribute 'synchro' #1

Closed jonra1993 closed 1 year ago

jonra1993 commented 2 years ago

I was trying to use this lib with:

sanic = "21.9.3" sanic-cors = "^1.0.0" sanic-jwt = "^1.6.0" sanic-routing = "^0.7.2" sanic-ext = "^22.1.2" sanic-synchro-ctx = "^0.1.0"

Output request.app.ctx.synchro.set_default({"counter": 0}) AttributeError: 'types.SimpleNamespace' object has no attribute 'synchro'

ashleysommer commented 2 years ago

Removed comment. See below.

ashleysommer commented 2 years ago

@jonra1993 Sorry, my answer above was completely wrong. The error you're seeing here is caused because when you have sanic-ext installed, you must use plugins a little differently.

See the this example (this is the same as simply.py from examples, but modified for use with sanic-ext).

from sanic import Sanic
from sanic.response import html
from sanic.request import Request
from sanic_ext import Extend
from sanic_synchro_ctx import SanicSynchroCtx

app = Sanic("simple")
Extend(app, extensions=[SanicSynchroCtx])

@app.after_server_start
def handler(app, loop=None):
    # This will only set this value if it doesn't already exist
    # So only the first worker will set this value
    app.ctx.synchro.set_default({"counter": 0})

@app.route("/")
def index(request: Request):
    counter = request.app.ctx.synchro.increment("counter")

    print("counter: {}".format(counter), flush=True)
    return html("<p>Hello World</p>")

app.run("127.0.0.1", port=8000, workers=8, debug=False, auto_reload=False, access_log=False)

I'll update the instructions in README.md and add a new example file, to cover this use case.

jonra1993 commented 2 years ago

Thanks, @ashleysommer Extend(app, extensions=[SanicSynchroCtx]) solved the error message and the example is working. One question do you think I can use this synchro context to share more complex data structures different than dictionaries and numbers. I need to share between workers an instantiated object of an ML.

ashleysommer commented 2 years ago

Thats a good question. To be honest, I haven't tried it other than simple dicts, lists, strings and numbers. I don't think you can pass an instantiated object between workers, unless that object can be pickeled. Python needs to covert the instantiated object into a pickle object in order to send it between workers, and some things simply cannot be picked. Best to try out some experiments yourself with your use case, and see how you go.

jonra1993 commented 2 years ago

Hello, @ashleysommer thanks for the information I was able to add dicts, lists, strings, and numbers but when I try to add an object it returns None in all cases. I want to go to check more about it the pickle concept .