Greenlet context local variables

469 views
Skip to first unread message

parun...@gmail.com

unread,
Nov 25, 2014, 3:26:05 AM11/25/14
to gev...@googlegroups.com
Hello, could someone please enlighten me on gevent/greenlet context locals? Particularly:

1) Is it correct that all variables declared and used e.g. in my gevent.wsgi apps should be managed with a local context manager (like the one provided by Werkzeug)?
2) What happens if I don't?
3) Why are references to arguments passed to the greenlet function preserved in greenlet contexts correctly without such measures (if they indeed are)?

I've read several articles on this topic, but I still feel confused and ignorant.

AM

unread,
Nov 25, 2014, 12:13:32 PM11/25/14
to gev...@googlegroups.com
On 11/25/14 12:26 AM, parun...@gmail.com wrote:
> Hello, could someone please enlighten me on gevent/greenlet context
> locals? Particularly:
>
> 1) Is it correct that all variables declared and used e.g. in my
> gevent.wsgi apps should be managed with a local context manager (like
> the one provided by Werkzeug)?

Per my understanding, once you are in the request handler ie the
app(env, start_response) function you are already operating in a
greenlet local context and should not need to do anything.

> 2) What happens if I don't?

Could you possibly give an example of what you want to do? That might
help clarify the consequences of not using a context.

> 3) Why are references to arguments passed to the greenlet function
> preserved in greenlet contexts correctly without such measures (if
> they indeed are)?
I think an example would be very useful here. If you are in an
application handler, then all you get is the response function and the
environment. The handler itself is spawned as a greenlet which has its
local context setup appropriately.

>
> I've read several articles on this topic, but I still feel confused
> and ignorant.
> --
> You received this message because you are subscribed to the Google
> Groups "gevent: coroutine-based Python network library" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to gevent+un...@googlegroups.com
> <mailto:gevent+un...@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout.
HTH
AM

parun...@gmail.com

unread,
Nov 25, 2014, 3:14:48 PM11/25/14
to gev...@googlegroups.com
Per my understanding, once you are in the request handler ie the
app(env, start_response) function you are already operating in a
greenlet local context and should not need to do anything.

For instance, in the gevent tutorial [[https://sdiehl.github.io/gevent-tutorial/#thread-locals]] we see the following code:

@contextmanager
def sessionmanager(environ):
    _requests.request = Request(environ)
    yield
    _requests.request = None

def logic():
    return "Hello " + request.remote_addr

def application(environ, start_response):
    status = '200 OK'

    with sessionmanager(environ): 
        body = logic()

If what you say is true, why use such a construction at all? Why not something along the lines of the following?

def logic(self, environ, start_response):
    request = Request(environ)
    return "Hello " + remote_addr

AM

unread,
Nov 25, 2014, 6:48:55 PM11/25/14
to gev...@googlegroups.com
On 11/25/14 12:14 PM, parun...@gmail.com wrote:
>
> Per my understanding, once you are in the request handler ie the
> app(env, start_response) function you are already operating in a
> greenlet local context and should not need to do anything.
>
>
> For instance, in the gevent tutorial
> [[https://sdiehl.github.io/gevent-tutorial/#thread-locals]] we see the
> following code:
>
> @contextmanager
> def sessionmanager(environ):
> _requests.request = Request(environ)
> yield
> _requests.request = None
>
> def logic():
> return "Hello " + request.remote_addr
>
> def application(environ, start_response):
> status = '200 OK'
>
> with sessionmanager(environ):
> body = logic()
>
> If what you say is true, why use such a construction at all? Why not
> something along the lines of the following
>
> def logic(self, environ, start_response):
> request = Request(environ)
> return "Hello " + remote_addr

So as far as I understand nothing stops you from doing that. This
particular example was illustrating the use cases for threadlocal(s) in
context of greenlets.

In this case, the _requests is a threadlocal which will be initialized
per request greenlet and sessionmanager is the context manager which
will initilize _requests.request and make it available via a proxy object.

IMO that is a very contrived example and you don't particularly need the
sessionmanager, you can do as you mention above or by just directly
assigning to _requests.request.

HTH
AM

parun...@gmail.com

unread,
Nov 26, 2014, 3:51:43 AM11/26/14
to gev...@googlegroups.com
Thanks, I think I'm starting to get the gist of it. So in other words thread locals are for global variables [as claimed by one of the tutorials I've read] only, and are needed to pass "global" variables between different functions while ensuring thread safety (i.e. that the second function will use the correct values for the variables as assigned by the first function). Is this correct? If so, then why not just invoke these secondary functions passing these variables as arguments?

AM

unread,
Nov 26, 2014, 12:51:29 PM11/26/14
to gev...@googlegroups.com
On 11/26/14 12:51 AM, parun...@gmail.com wrote:
> Thanks, I think I'm starting to get the gist of it. So in other words
> thread locals are for global variables [as claimed by one of the
> tutorials I've read] only, and are needed to pass "global" variables
> between different functions while ensuring thread safety (i.e. that
> the second function will use the correct values for the variables as
> assigned by the first function). Is this correct?
In most common use cases, yes.

> If so, then why not just invoke these secondary functions passing
> these variables as arguments?
You can certainly do so and in most cases it actually makes sense.
However if you were writing a framework where you may not have
sufficient control over the usage, going the sessionmanager style route
is better as it does not force the user of the framework to stick to
specific design constraints.
Reply all
Reply to author
Forward
0 new messages