Search code examples
pythongoogle-app-enginewsgiwebapp2

Google App Engine Application Cache


In google app engine i have created my own user API appropriately called user so it doesn't interfere with the google app engine API users. Like most multiuser websites, two "versions" of the site are available to the user depending on whether or not they are logged in. Thus is created a file called router.py with the following code

import webapp2

from lib import user
import guest
import authorized

if user.isLoggedIn():
    app = webapp2.WSGIApplication(authorized.WSGIHandler,debug=True)
else:
    app = webapp2.WSGIApplication(guest.WSGIHandler,debug=True)

the guest and authorized modules are formated like your conventional application script for example:

import webapp2
import os

class MainPage(webapp2.RequestHandler):
    def get(self,_random):
        self.response.out.write('authorized: '+_random)

WSGIHandler = [('/(.*)', MainPage)]

Thus the router file easily selects which WSGIApplication url director to use by grabbing the WSGIHandler variable from either the guest or authorized module. However the user must close all tabs for the router to detect a change in the isLoggedIn() function. If you log in it does not recognize that you have done so until every tab is closed. I have two possible reasons for this:

  1. isLoggedIn() uses os.environ['HTTP_COOKIE'] to retrieve cookies and see if a user is logged in, it then checks the cookie data against the database to make sure they are valid cookie. Possibly this could have an error where the cookies on the server's end aren't being refreshed when the page is? Maybe because i'm not getting the cookies from self.request.

  2. Is it possible that in order to conserve frontend hours or something that google app engine caches the scripts from the server with in the server's memcache? i Doubt it but i am at a loss for the reason for this behavior.

Thanks in advance for the help

Edit

Upon more testing i found that as suspected the router.py file responded correctly and directed the user based in logged in when a comment was added to it. This seems to indicate caching.

Edit 2

I have uncovered some more information on the WSHI Application:

The Python runtime environment caches imported modules between requests on a single web server, similar to how a standalone Python application loads a module only once even if the module is imported by multiple files. Since WSGI handlers are modules, they are cached between requests. CGI handler scripts are only cached if they provide a main() routine; otherwise, the CGI handler script is loaded for every request.

I wonder how efficient to refresh the WSGI module somehow. This would undoubtably task the server, but solve my problem. Again, this seems to be a partial solution.

Edit 3

Again, any attempt to randomize a comment in the router.py file is ineffective. The id statement looking for user login is completely overlooked and the WSGIApplication is set to its original state. I'm not yet sure if this is due to the module cache in the webapp2 module or thanks to the module cache on the user API. I suspect the latter.


Solution

  • replace router.py with:

    from google.appengine.ext import webapp
    from google.appengine.ext.webapp.util import run_wsgi_app
    
    from lib import user
    import guest
    import authorized
    
    def main():
        if user.isLoggedIn():
            run_wsgi_app(authorized.application)
        else:
            run_wsgi_app(guest.application)
    
    if __name__ == "__main__":
        main()
    

    downgrading to the old webapp allows you to change dynamically the wsgi application. it's tested and works perfectly! The CGI adaptor run_wsgi_app allows for the webapp to change it's directory list without caching.