From: Olivier M. <om...@ol...> - 2004-09-22 21:19:37
|
Hi all, this is my first post to this group, after a couple of days playing with webware. I'm creating a page containing a form including a <select> field which <options> values are filled from a database query. I would like to cache the result of the query, in order to make the query only once, and therefore speed up the rendering. I really mean once, not once per session. To the best of my knowledge (correct me if I'm wrong), you can't rely on instances variables to store persistent-accross-requests variables : the instance may or may be not reused, may or not be cached. I though that storing the result of my query in a class variable would solve the problem, but it doesn't. My code looks like this: class MyPage(SitePage.SitePage): def getData(self): ... cur = self.con.cursor() cur.execute("select foo, bar from mytable") data = cur.fetchall() options = ['<option value="%s">%s</option>' % x for x in data] self.__class__.data = "<select>%s</select>" % options def writeHTML(self): ... if hasattr(self.__class__, "data"): # data already stored in a class variable pass else: self.getData() ... self.write(.... + self.__class__.data + ...) So, my questions are : 1) why doesn't it work ? It's not a caching issue because my CacheServletClasses is set to 0 in my Application.config file. 2) what is the best way to make persistent variables accross requests and sessions ? 3) I did some mod_python programming and I used to deal with this issue by running a SOAP server alongside the HTTP server, which was holding all the persistent data. Is this an option with Webware or is there something more clever to do ? many thanks, Olivier |
From: deelan <de...@in...> - 2004-09-22 21:57:46
|
Olivier Migeon wrote: > To the best of my knowledge (correct me if I'm wrong), you can't rely on > instances variables to store persistent-accross-requests variables : the > instance may or may be not reused, may or not be cached. true. > > I though that storing the result of my query in a class variable would > solve the problem, but it doesn't. > My code looks like this: (...) > So, my questions are : > > 1) why doesn't it work ? It's not a caching issue because my > CacheServletClasses is set to 0 in my Application.config file. i may be wrong but this setting means that at *every* page request your MyPage class will be recreated from scratch. > > 2) what is the best way to make persistent variables accross requests > and sessions ? i use to compile-once cheetah templates and store them in a dictionary stored in SitePage class var, like you do your code. see below: class SitePage(Page): # master page template HTML = 'site.html' # ... other code ... _cache = {} # master page template objects def writeHTML(self): if self.HTML in SitePage._cache: t = SitePage._cache[self.HTML] else: app = self.application() path = app.serverSidePath('www/t/%s' % self.HTML) # if file changes reload app modloader.watchFile(path) t = Template(file=path, filter=Latin1Encoder) SitePage._cache[self.HTML] = t # access to self with $s in template t.s = self self.write(str(t)) but CacheServletClasses must be set to 1 if I want that webware caches servlet classes, hence page templates. cheers, deelan. |
From: Olivier M. <om...@ol...> - 2004-09-23 07:08:11
|
> I'm creating a page containing a form including a <select> field which > <options> values are filled from a database query. I would like to > cache the result of the query, in order to make the query only once, > and therefore speed up the rendering. I really mean once, not once per > session. > > I though that storing the result of my query in a class variable would > solve the problem, but it doesn't. Ok, I thought that CacheServletClasses = 1 would "freeze" the class as it is when first loaded, but actually, it's just the contrary. Many thanks to Jason and deelan. I did my homework and had a look at ServletFactory.py. If CacheServletClasses is set to 0, the PythonServletFactory reloads the module containing the servlet class from file (by calling ImportAsPackage, which calls _importModuleFromDirectory with forceReload set to 1), which means that all dynamically-changed members of the class are lost. In plain Python, this would be like : *** file testImp.py *** class myClass: data = "From module" *** *** file test.py *** import testImp myInst = testImp.myClass() testImp.myClass.data = "Dynamically changed" reload(testImp) print testImp.myClass.data # --> "From module" *** Cheers, olivier |
From: Thomas E J. <tho...@gm...> - 2004-09-23 14:27:37
|
On Wed, 22 Sep 2004 23:19:26 +0200, Olivier Migeon <om...@ol...> wrote: > Hi all, this is my first post to this group, after a couple of days > playing with webware. > > I'm creating a page containing a form including a <select> field which > <options> values are filled from a database query. I would like to > cache the result of the query, in order to make the query only once, > and therefore speed up the rendering. I really mean once, not once per > session. > > To the best of my knowledge (correct me if I'm wrong), you can't rely > on instances variables to store persistent-accross-requests variables : > the instance may or may be not reused, may or not be cached. > > I though that storing the result of my query in a class variable would > solve the problem, but it doesn't. > My code looks like this: > > class MyPage(SitePage.SitePage): > > def getData(self): > ... > cur = self.con.cursor() > cur.execute("select foo, bar from mytable") > data = cur.fetchall() > options = ['<option value="%s">%s</option>' % x for x in data] > self.__class__.data = "<select>%s</select>" % options > > def writeHTML(self): > ... > if hasattr(self.__class__, "data"): > # data already stored in a class variable > pass > else: > self.getData() > ... > self.write(.... + self.__class__.data + ...) > > So, my questions are : > > 1) why doesn't it work ? It's not a caching issue because my > CacheServletClasses is set to 0 in my Application.config file. > > 2) what is the best way to make persistent variables accross requests > and sessions ? > > 3) I did some mod_python programming and I used to deal with this issue > by running a SOAP server alongside the HTTP server, which was holding > all the persistent data. Is this an option with Webware or is there > something more clever to do ? > > many thanks, > > Olivier If you are only fetching the information once for the entire application, you can grab it on context init. You would have to then store the information in a variable in the AppServer object but it would only be evaluated when you first start the server. Not sure if this a correct solution to the problem but I've been using it to store information read from a config file. Look at contextInitialize in context_name/__init__.py. |