From: Faried N. <fa...@gm...> - 2004-12-27 20:50:45
|
Hello, I'm using webware 0.8.1 with apache2, with the mod_webkit2 adaptor. Is it safe to run apache2 in multithreaded mode (the worker mpm instead of prefork)? I run FreeBSD 5.3.x, and that finally has a stable (?) implementation of kernel threads. I'd like to take advantage of that, if possible. How can I tell how long it takes to render pages? I have a SitePage parent class for all my pages (derived from WebKit.Page); should I store the current time in its awake() and print the difference between it and the current time in sleep() to the console? Lastly, I'd like to cache some objects in memory. When my users do a lookup for a product, I call a method that returns an object which contains everything I need to display the product info. How can I keep a handle on that object and refer to it later when I next get a query for that product? Do I create a dict instance variable in my SitePage class, and have my user-facing pages check self.cachedProduct('Ajax Hammer') or something? I can't find any examples for this, and I could really use a feature like this to speed up my site. I'm sure lots of people have asked these questions, but I can't easily find them using the sf.net search interface. Thanks, Faried. |
From: John D. <jdi...@te...> - 2004-12-27 21:28:12
|
(sent from the wrong email adress the first time) I can answer one or two of those questions. Faried Nawaz wrote: > >How can I tell how long it takes to render pages? I have a SitePage >parent class for all my pages (derived from WebKit.Page); should I >store the current time in its awake() and print the difference between >it and the current time in sleep() to the console? > Unless someone shod me a better way, that's probably what I would do. > >Lastly, I'd like to cache some objects in memory. > I do something very similar to this. I have a class (storage_mod) that handles all of my read and writes to disk. The great thing is that I don't have to worry about how the data is stored (database, files, etc). My servlet pages simply import storage_mod and tell it to get data or save data. All of my data is keyed by a timestamp. I cache accessed data and make sure what I return is the most current piece of information. If there is something more recent than what is in the cache, I stick the new data in the cache. I use the threading module to handle locking the global cache variable (am I doing that correctly?) The only thing I would caution you to keep in mind is that removing a performance hit for accessing data repeatedly can lead to ineffecient code (reading the same data multiple times on one page when it's not necessary). I have had to rewrite some of my code when I find myself doing that. storage_mod.py is below (my tabs got messed up in the copy/paste. I hope I fixed them all). data_mod is what reads and writes the data. If it doesn't make sense, just ask. --John --file storage_mod.py-- #$Date: 2004/11/30 16:01:21 $ import time import data_mod as data_mod import threading cache = {} class storage_mod(object): def __init__(self,group_date='test_20040615'): global cache self.__group_date = group_date self.__l = threading.RLock() if not cache.has_key(group_date): self.__l.acquire() cache[group_date] = {} self.__l.release() # make data_mod's types available from storage_mod types = data_mod.data_mod._type_list for t in types.keys(): self.__dict__[t] = types[t] def saveData(self,type,meta,data): d = data_mod.data_mod(self.__group_date) ts = time.strftime("%Y%m%d%H%M%S") small_part = 0 ts += ('%3d'%small_part).replace(' ','0') while ts in self.getTimestamps(type,meta): if small_part < 999: small_part += 1 else: break ts = ts[:-3] + ('%3d'%small_part).replace(' ','0') d.saveData(type,meta,data,ts) def getData(self,type,meta,allTimeStamps=0): global cache d = data_mod.data_mod(self.__group_date) index = d.getIndex(type,meta) index.sort() ret = {} if not allTimeStamps: self.__l.acquire() if cache[self.__group_date].get((type,meta),[None])[0] == index[-1]: ret = cache[self.__group_date].get((type,meta))[1] else: ret = d.getData(type,meta,index[-1]) if not cache[self.__group_date].has_key((type,meta)): cache[self.__group_date][(type,meta)] = None cache[self.__group_date][(type,meta)] = (index[-1],ret) self.__l.release() else: data = {} for x in index: data[x] = d.getData(type,meta,x) ret = data return ret def getList(self,type): d = data_mod.data_mod(self.__group_date) return d.getIndex(type,'') def getTimestamps(self,type,meta): d = data_mod.data_mod(self.__group_date) return d.getIndex(type,meta) |
From: John D. <jdi...@te...> - 2004-12-27 21:16:14
|
I can answer one or two of those questions. Faried Nawaz wrote: > >How can I tell how long it takes to render pages? I have a SitePage >parent class for all my pages (derived from WebKit.Page); should I >store the current time in its awake() and print the difference between >it and the current time in sleep() to the console? > Unless someone shod me a better way, that's probably what I would do. > >Lastly, I'd like to cache some objects in memory. > I do something very similar to this. I have a class (storage_mod) that handles all of my read and writes to disk. The great thing is that I don't have to worry about how the data is stored (database, files, etc). My servlet pages simply import storage_mod and tell it to get data or save data. All of my data is keyed by a timestamp. I cache accessed data and make sure what I return is the most current piece of information. If there is something more recent than what is in the cache, I stick the new data in the cache. I use the threading module to handle locking the global cache variable (am I doing that correctly?) The only thing I would caution you to keep in mind is that removing a performance hit for accessing data repeatedly can lead to ineffecient code (reading the same data multiple times on one page when it's not necessary). I have had to rewrite some of my code when I find myself doing that. storage_mod.py is below (my tabs got messed up in the copy/paste. I hope I fixed them all). data_mod is what reads and writes the data. If it doesn't make sense, just ask. --John --file storage_mod.py-- #$Date: 2004/11/30 16:01:21 $ import time import data_mod as data_mod import threading cache = {} class storage_mod(object): def __init__(self,group_date='test_20040615'): global cache self.__group_date = group_date self.__l = threading.RLock() if not cache.has_key(group_date): self.__l.acquire() cache[group_date] = {} self.__l.release() # make data_mod's types available from storage_mod types = data_mod.data_mod._type_list for t in types.keys(): self.__dict__[t] = types[t] def saveData(self,type,meta,data): d = data_mod.data_mod(self.__group_date) ts = time.strftime("%Y%m%d%H%M%S") small_part = 0 ts += ('%3d'%small_part).replace(' ','0') while ts in self.getTimestamps(type,meta): if small_part < 999: small_part += 1 else: break ts = ts[:-3] + ('%3d'%small_part).replace(' ','0') d.saveData(type,meta,data,ts) def getData(self,type,meta,allTimeStamps=0): global cache d = data_mod.data_mod(self.__group_date) index = d.getIndex(type,meta) index.sort() ret = {} if not allTimeStamps: self.__l.acquire() if cache[self.__group_date].get((type,meta),[None])[0] == index[-1]: ret = cache[self.__group_date].get((type,meta))[1] else: ret = d.getData(type,meta,index[-1]) if not cache[self.__group_date].has_key((type,meta)): cache[self.__group_date][(type,meta)] = None cache[self.__group_date][(type,meta)] = (index[-1],ret) self.__l.release() else: data = {} for x in index: data[x] = d.getData(type,meta,x) ret = data return ret def getList(self,type): d = data_mod.data_mod(self.__group_date) return d.getIndex(type,'') def getTimestamps(self,type,meta): d = data_mod.data_mod(self.__group_date) return d.getIndex(type,meta) |