Global variable usage with web.py in Apache

2019-07-29 11:03发布

问题:

I have come across a strange problem when I configured my web.py code with Apache. I have 3 variable which I need to use across 2 classes. I used to handle this using global variables but unfortunately that doesn't work now.

Example:

   urls = (
              '/', 'index',
              '/result','Result' 
   )
   # index is basically a form which takes some inputs     
   class index:
        def POST(self):
                global VAR1, VAR2, VAR3
                 i = web.input()
                 VAR1 = i.word1.__str__()
                 VAR2 = i.word2.__str__()
                 VAR3 = i.word3.__str__()
                 raise web.seeother('/result')
   class Result:
        def GET(self):
                print VAR1, VAR2
                return r_result(VAR1, VAR2)
        def POST(self):
                print VAR2, VAR3

This works perfectly fine when I run the code independently (i.e. python webappy.py) but when used in the apache settings it gives:

NameError: global name 'VAR1' is not defined at the print statement in Result.Get

I was checking the ApplicationIssues: http://code.google.com/p/modwsgi/wiki/ApplicationIssues and found out following statement.

Application Global Variables

Because the Python sub interpreter which hosts a WSGI application is retained in memory between requests, any global data is effectively persistent and can be used to carry state forward from one request to the next. On UNIX systems however, Apache will normally use multiple processes to handle requests and each such process will have its own global data. This means that although global data can be used, it can only be used to cache data which can be safely reused within the context of that single process. You cannot use global data as a means of holding information that must be visible to any request handler no matter which process it runs in.

I have to pass those variables across the classes and functions. I tried appending the variables to builtin & web module but it didn't workout either.

PS: Also I don't want to store these variables in files or db.

I hope I made myself clear.

回答1:

You shouldn't rely on global variables when developing web application, because at some point it may be configured to run in separate processes that won't share these variables.

To keep them between requests you should save and load them from persistent storage so I guess its not possible without using database or similar solution.

A good way to load and save them would be by using application processors that will load these variables in web.ctx so you can access them in controller methods.

For example:

def global_variables_processor(handle):
    # load variables from persistent storage and save them in web.ctx.global_variables
    try:
        return handle()
    finally:
        # save variables from web.ctx.global_variables in persistent storage

app = web.application(urls, globals()
app.add_processor(global_variables_processor)


回答2:

Well, there's a possible reason in this excerpt from your question...

Apache will normally use multiple processes to handle requests and each such process will have its own global data.

...so your code will only work reliably if you've configured apache to use a single process which never terminates, with the directives...

MaxClients 1
MaxRequestsPerChild 0

If this isn't a practical option, you'll have to store those variables somewhere else.