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

How to share session between background threads #356

Closed
jmrbcu opened this issue Nov 10, 2016 · 3 comments
Closed

How to share session between background threads #356

jmrbcu opened this issue Nov 10, 2016 · 3 comments
Assignees
Labels

Comments

@jmrbcu
Copy link

jmrbcu commented Nov 10, 2016

Hello again Miguel, sometimes I need to share values stored in the session with my background threads, but for some reason, when I try to read those values from the session in the background threads the only thing I see is the session object empty. Here is an example:

@socketio.on('connect', namespace='/transcriber')
def on_start():
    @copy_current_request_context
    def transcriber():
        while not session.get(request.sid):
            print session
            socketio.sleep(1)

    session['key'] = 'testing value'
    session[request.sid] = False
    socketio.start_background_task(transcriber)


@socketio.on('disconnect', namespace='/transcriber')
def on_disconnect():
    session[request.sid] = True

In this case, the thread will never end because session.get(request.sid) will be always None, which means that changes to the session object at the beginning of the handler are not seen by the thread. Is this the intended behavior?

@miguelgrinberg
Copy link
Owner

There are some differences in how Flask and Flask-SocketIO implement the request context and the context globals, that is probably why Flask's copy_current_request_context does not work inside Flask-SocketIO events. I will look into it.

But if all you need is pass some values into your thread, no need to use the session for that, just pass the values directly as arguments, or the pass the session dictionary as an argument with session._get_current_object(). That will remove the need to use the copy request decorator.

@miguelgrinberg miguelgrinberg self-assigned this Nov 10, 2016
@jmrbcu
Copy link
Author

jmrbcu commented Nov 16, 2016

Sorry for the late response, basically, what you mean is instead of doing this:

@socketio.on('test_event')
def on_test_event():
    @copy_current_request_context
    def long_handler():
        while True:
            print session['key']
            emit('response')
            socketio.sleep(1)

    session['key'] = 'testing value'
    socketio.start_background_task(long_handler)

I should be doing either this:

@copy_current_request_context
def long_handler():
    while True:
        print session['key']
        emit('response')
        socketio.sleep(1)

@socketio.on('test_event')
def on_test_event():
    session['key'] = 'testing value'
    socketio.start_background_task(long_handler)

or better, this:

def long_handler(session):
    while True:
        print session['key']
        emit('response')
        socketio.sleep(1)

@socketio.on('test_event')
def on_test_event():
    session['key'] = 'testing value'
    socketio.start_background_task(long_handler, session._get_current_object())

Am I right?

@miguelgrinberg
Copy link
Owner

miguelgrinberg commented Nov 26, 2016

The last of your examples definitely works, because you are sending the session dictionary directly.

The example in your first post does work in the way it is intended, so this issue is really not a bug, that's how Flask works. The copy_current_request_context decorator makes a copy of the request context, and gives that to the background thread. Any changes that you make to the session right below the thread function will happen after the decorator made the request context copy, so those will not be in the copy. The request context copy is not linked to the original, so changes will not be moved to the thread.

Closing, since this is not an issue. The decorator you are using works in a weird way, the same issue exists in standalone Flask as well.

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

No branches or pull requests

2 participants