Re: [Webware-discuss] Automatic Session Save in Transaction.py
On Thu, Mar 3, 2011 at 9:28 AM, Christoph Zwerschke c...@online.de wrote: IMHO the most simple solution would be to keep a dirty flag (set whenever __setitem__ or __delitem__ is called for the session) and then save the session only when the dirty flag has been set. This will also be good for performance. We could also add an AppConfig setting for manual saving (False by default to maintain backward compatibility). In this case, the dirty flag would not be set automatically, but by calling a save() method on the session. But I'm already seeing a problem with that approach: Since the lastAccessTime is stored along with the session, it will not get updated if the session is not saved, so the session will expire too early if the user does not do anything that alters the session. I kind of don't care if the lastAccessTime isn't updated in this session saving mode. We use very long session expiry times so if a read only user had to relogin a little more frequently I don't think it would be an issue that anyone would notice. Also for our system at some point they will perform an action that modifies the session. Since this is a new feature which Webware users would have to turn on I'd recommend we do the simplest thing that works and provide a new config setting for Sessions that takes multiple values: EveryRequest - default and current functionality WhenChanged - only saves when add/delete has been called Best Regards, Steve -- Free Software Download: Index, Search Analyze Logs and other IT data in Real-Time with Splunk. Collect, index and harness all the fast moving IT data generated by your applications, servers and devices whether physical, virtual or in the cloud. Deliver compliance at lower cost and gain new business insights. http://p.sf.net/sfu/splunk-dev2dev ___ Webware-discuss mailing list Webware-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/webware-discuss
Re: [Webware-discuss] Automatic Session Save in Transaction.py
On Thu, Mar 3, 2011 at 2:23 PM, Christoph Zwerschke c...@online.de wrote: Btw, which kind of session store are you using? The default DynamicStore is based on the MemoryStore, and here requests share the same session object. So the scenario you described should actually not cause a problem for this kind of session store. We use multiple appservers without session affinity so we use MemcacheSession to share sessions across appservers Best Regards, Steve -- Free Software Download: Index, Search Analyze Logs and other IT data in Real-Time with Splunk. Collect, index and harness all the fast moving IT data generated by your applications, servers and devices whether physical, virtual or in the cloud. Deliver compliance at lower cost and gain new business insights. http://p.sf.net/sfu/splunk-dev2dev ___ Webware-discuss mailing list Webware-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/webware-discuss
[Webware-discuss] Automatic Session Save in Transaction.py
Hi, We ran across an interesting problem with sessions being automatically saved by Transaction.py. We had a situation where two AJAX requests were issued and one of the requests updates the session and it started and completed within the lifetime of another request. In that scenario the completion of the first request overwrites the session and the changes to the session made by the shorter request are lost. Here's an easier to follow timeline: Request 1 - reads session (assume session is empty) Request 2 - reads session (assume session is empty) Request 2 - adds data to session Request 2 - sleep() called - session is stored (session contains data) Request 1 - sleep() called - session is stored (session is now empty - the value of the session when Request 1 read it) So when later requests go to read the data stored in the session by request 2 the data isn't there. Here's the code from WebKit.Transaction: def sleep(self): Send sleep() to the session and the servlet. Note that sleep() is sent in reverse order as awake() (which is typical for shutdown/cleanup methods). self._nested -= 1 self._servlet.sleep(self) if not self._nested and self._session: self._session.sleep(self) self._application.sessions().storeSession(self._session) We put a hack in the longer running AJAX page's sleep() to keep the session from being stored since it doesn't modify the session: def sleep(self, trans): trans._session = None Is there an official way to disable the automatic storage of sessions? If not there are a number of ways to resolve this problem more generally: - Explicit session saves by servlet - Transaction never calls storeSession() - Explicit opt in/opt out of session storage by servlet - Explicit opt in/opt out of session storage by AppConfig - Extend Session functionality to keep a dirty flag and only automatically save the session if it has been modified during the request/response. IMO Webware shouldn't be saving the session automatically at the end of each request. I'd rather the servlet logic explicitly decide when and if to save the session, but this would break backward compatibility. I'd be happy to supply a patch if we can decide on a way forward. Best Regards, Steve Blog: http://tech.agilitynerd.com/ -- Free Software Download: Index, Search Analyze Logs and other IT data in Real-Time with Splunk. Collect, index and harness all the fast moving IT data generated by your applications, servers and devices whether physical, virtual or in the cloud. Deliver compliance at lower cost and gain new business insights. http://p.sf.net/sfu/splunk-dev2dev ___ Webware-discuss mailing list Webware-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/webware-discuss
Re: [Webware-discuss] Why does ThreadedAppServer.addSocketHandler() write to disk?
On Tue, Jun 8, 2010 at 2:35 PM, Christoph Zwerschke c...@online.de wrote: Am 08.06.2010 21:27 schrieb Steve Schwarz: We'd like to simplify our deployment. Now our admins have to install Webware multiple times for each appserver instance on multiple servers. It would be easier to just deploy once and have all instance refer to that one check out. Ok, as I understand, your working dir is on a shared directory? In the process pool install each server would have one checkout shared by 10-20 SingleThreadedAppServer Webware instances. We also see better performance running with a pool of single threaded appservers instead of using the ThreadedAppServer. Are you using multi-core/multi-processing machines? Yep. Looks like we are experiencing GIL contention on our compute heavy pages. Refactoring is also going on in the application to solve that problem. Steve -- ThinkGeek and WIRED's GeekDad team up for the Ultimate GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the lucky parental unit. See the prize list and enter to win: http://p.sf.net/sfu/thinkgeek-promo___ Webware-discuss mailing list Webware-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/webware-discuss
Re: [Webware-discuss] Why does ThreadedAppServer.addSocketHandler() write to disk?
On Tue, Jun 8, 2010 at 3:56 PM, Christoph Zwerschke c...@online.de wrote: Maybe a MultiProcessAppServer could be the alternative or somethin with an approach like Concurrence or Twisted. We are using Twisted to dispatch/maintain the Webware process pool. Will see about possibility of open sourcing our SingleThreadedAppServer and our twisted server as this progresses. Steve -- ThinkGeek and WIRED's GeekDad team up for the Ultimate GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the lucky parental unit. See the prize list and enter to win: http://p.sf.net/sfu/thinkgeek-promo___ Webware-discuss mailing list Webware-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/webware-discuss
[Webware-discuss] Why does ThreadedAppServer.addSocketHandler() write to disk?
Hi, We are looking to run multiple Webware instances from a single Webware directory/checkout and can do so by providing configuration differences via command line args. But I noticed that ThreadedAppServer.addSocketHandler() creates files like http.address and adapter.address containing the address:port for each adapter: # write text file with server address adrFile = self.addressFileName(handlerClass) if os.path.exists(adrFile): print Warning: %s already exists % adrFile try: os.unlink(adrFile) except OSError: # we cannot remove the file if open(adrFile).read() == adrStr: return # same content, so never mind else: print Error: Could not remove, adrFile sys.stdout.flush() raise try: f = open(adrFile, 'w') f.write(adrStr) f.close() except IOError: print Error: Could not write, adrFile sys.stdout.flush() raise Can anyone explain the purpose? Trying to stop running multiple appservers on the same address/port? If so the port will already be bound so the appserver will fail... Thanks, Steve -- ThinkGeek and WIRED's GeekDad team up for the Ultimate GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the lucky parental unit. See the prize list and enter to win: http://p.sf.net/sfu/thinkgeek-promo___ Webware-discuss mailing list Webware-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/webware-discuss
Re: [Webware-discuss] Memcached Session Submission
On Sun, Apr 11, 2010 at 4:23 PM, Christoph Zwerschke c...@online.de wrote: Am 15.03.2010 19:38 schrieb Steve Schwarz: I've written a memcached based Session that others might find useful. Feel free to use as you wish. I had some time today to try it out. Works nicely. I have added some improvements (namespaces, clear() and some more methods) and tests. Committed to the 1.1. branch now. Only one thing was not quite clear: Why do you inherit the store from threading.local? As far as I see, this should not be necessary. Christoph, Must have been a cut/paste error from the Session subclass on which I based this implementation; there is no need for threading.local. I'll take a look at your version. Steve -- Download Intel#174; Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev___ Webware-discuss mailing list Webware-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/webware-discuss
Re: [Webware-discuss] Memcached Session Submission
On Sun, Apr 11, 2010 at 4:32 PM, Steve Schwarz st...@agilitynerd.comwrote: On Sun, Apr 11, 2010 at 4:23 PM, Christoph Zwerschke c...@online.dewrote: Am 15.03.2010 19:38 schrieb Steve Schwarz: I've written a memcached based Session that others might find useful. Feel free to use as you wish. I had some time today to try it out. Works nicely. I have added some improvements (namespaces, clear() and some more methods) and tests. Committed to the 1.1. branch now. Christoph, I took a look at the commit and I think the namespace idea is a good enhancement. We use separate memcached servers only for session data so it hasn't been an issue for us. However I'm concerned by the added code/complexity required to support clear(). In our usage of the memcached session store users are moved between servers based on load. So if the sessions are cleared on one appserver what mechanism is used to trigger the other servers to call getCounter() and reset their notion of the session counter? Similarly if an appserver restarts it will get the latest session namespace key but appservers that didn't call clear() won't have the latest session namespace key. I'd much rather the session store fail early and raise an exception if you try to clear(). The less code in the session implementation the safer I'd feel. Best Regards, Steve -- Download Intel#174; Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev___ Webware-discuss mailing list Webware-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/webware-discuss
[Webware-discuss] Memcached Session Submission
Hi, I don't recall if I've already submitted this enhancement... I've written a memcached based Session that others might find useful. Feel free to use as you wish. Usage: 1. Name the file SessionMemcachedStore.py in WebKit directory 2. Configure your Application.config: SessionStore = 'WebKit.SessionMemcachedStore' SessionMemcachedServers = ['127.0.0.1:11211'] SessionTimeout = 180 # minutes Best Regards, Steve import threading from memcache import memcache from WebKit.SessionStore import SessionStore debug = False class SessionMemcachedStore(SessionStore, threading.local): A session memached store. Stores the sessions in a single memcached using 'last write wins' semantics. This is useful for various situations: 1. Fault tolerance 2. Clustering In clustering configurations with concurrent writes for the same session(s) the last writer will always overwrite the session. Cleaning/timing out of sessions is performed by the memcached(s) themselves since no one appserver can know about the existence of all sessions or the last access for a given session. Besides it is built in memcached functionality. Consequently, correct sizing of memcached(s) is necessary to hold all user's session data. ## Init ## def __init__(self, app): threading.local.__init__(self) SessionStore.__init__(self, app) self._memcachedServers = app.setting( 'MemcachedServers', ['127.0.0.1:11211']) # timeout in seconds self._sessionTimeout = app.setting( 'SessionTimeout', 180) * 60 ## try: ## import cPickle as pickle ## except ImportError: ## import pickle import pickle self._client = memcache.Client(self._memcachedServers, pickleProtocol=pickle.HIGHEST_PROTOCOL) ## Access ## def __len__(self): if debug: print ' len', len(self.keys()) return len(self.keys()) def __getitem__(self, key): if debug: print ' getitem(%s)' % (key) # returns None if key non-existent or no server to contact value = self._client.get(key) if value is None: # SessionStore expects KeyError when no result raise KeyError return value def __setitem__(self, key, item): if debug: print ' setitem(%s, %s)' % (key, item) try: val = self._client.set(key, item, time=self._sessionTimeout) if not val: raise Exception except Exception, e: # Not able to store the session is a failure print Error saving session '%s' to memcached: %s % (key, e) self.application().handleException() def __delitem__(self, key): In contracts with SessionFileStore not finding a key to delete isn't a KeyError if debug: print ' delitem(%s)' % (key) self._client.delete(key) def removeKey(self, key): pass def has_key(self, key): if debug: print has_key(%s) % (key) return self._client.get(key) is not None def keys(self): if debug: print keys() return [] def clear(self): memcache handles clearing keys itself if debug: print clear() def setdefault(self, key, default): return value associated with key otherwise set key to default and return default if debug: print ' setdefault (%s, %s)' % (key, default) try: return self[key] except KeyError: self[key] = default return default ## Application support ## def storeSession(self, session): if debug: print storeSession(%s) % (session) key = session.identifier() self[key] = session def storeAllSessions(self): pass -- Download Intel#174; Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev___ Webware-discuss mailing list Webware-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/webware-discuss
Re: [Webware-discuss] Can psp read the html field value?
On Sun, Jan 31, 2010 at 9:11 PM, HS WAI drwa...@yahoo.com.sg wrote: Hi, Thanks for your prompt response. I want to get the value form user input/selected option html body select name='query' id='query' option value='a'a/option option value='b'b/option /select % # How to get user selected option? # what I want to do # if option == a, get data from a xml file... where the childNode is a # # i.e. select different option will get different data from a xml file # no form is called % input type=hidden id=selected name=selected value=%= #data from xml % /body /html Thanks for your help and advise. Hi, Take a look at WebKit/Examples/ListBox.py for how to handle the client's post (action) and get at the values in the form. You'll basically look at self.request().field('yourfieldnamehere') to get the submitted value. There are a number of useful examples in that directory that should help you. Best Regards, Steve http://agilitynerd.com/ http://googility.com/ Wristband Closeout Sale! http://store.agilitynerd.com/ -- The Planet: dedicated and managed hosting, cloud storage, colocation Stay online with enterprise data centers and the best network in the business Choose flexible plans and management services without long-term contracts Personal 24x7 support from experience hosting pros just a phone call away. http://p.sf.net/sfu/theplanet-com___ Webware-discuss mailing list Webware-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/webware-discuss