FWIW, some interesting ideas (and not so interesting ideas) for sessioning architecture in general are captured at
http://www.zope.org/Wikis/DevSite/Projects/CoreSessionTracking/UseCases and http://www.zope.org/Wikis/DevSite/Projects/CoreSessionTracking/CoreSessionTrackingDiscussion UML that more or less represents Zope's current sessioning model is at: http://www.zope.org/Wikis/DevSite/Projects/CoreSessionTracking/CoreSessionTrackingUML - C On Wed, 2005-08-17 at 00:31 -0500, Ian Bicking wrote: > Mike Orr wrote: > > Regarding Ian's session interface: > > http://svn.colorstudy.com/home/ianb/scarecrow_session_interface.py > > > > Ian Bicking wrote: > > > >> Thinking on it more, probably a good place to start would be agreeing > >> on specific terminology for the objects involved, since I've seen > >> several different sets of terminology, many of which use the same > >> words for different ideas: > >> > >> Session: > >> An instance of this represents one user/browser's session. > >> SessionStore: > >> An instance of this represents the persistence mechanism. This > >> is a functional component, not embodying any policy. > >> SessionManager: > >> This is a container for sessions, and uses a SessionStore. This > >> contains all the policy for loading, saving, locking, expiring > >> sessions. > >> > >> > > > > > > At minimum, the SessionManager links the SessionStore, Session, and > > application together. It can be generic, along with > > loading/saving/locking. (Although we might allow the application to > > choose a locking policy.) > > That could be a little difficult, since multiple applications may be > sharing a session. But at the same time, applications that don't expect > ConflictError are going to be pissed if you configure your system for > optimistic locking. > > Of course, given a session ID and a session store, each application > could have its own manager. Possibly. Hmm... interesting. In that > case each SessionManager needs an id, which is a bit annoying -- it has > to be stable and shared, because the same SessionManager has to be > identifiable over multiple processes. But I hate inventing IDs all over > the place. I feel like I'm pulling string keys out of my ass, and if > I'm going to pull things out of my ass I at least don't want to then put > them into my code. I sense UUIDs coming on :( > > That said, this isn't the only place I need strings that are unique to > an application instance. > > > But expiring is very application-specific, > > and it may not be the "application" doing it but a separate cron job. > > Perhaps most applications will be happy with an "expire all sessions > > unmodified for N minutes", but some will want to inspect the metadata > > and others the content. So maybe all the SessionManager can do is: > > > > .delete_session(id) => pass message directly to SessionStore > > .iter_sessions() => tuples of (id, metadata) > > .iter_sessions_with_content() => tuples of (id, metadata, content) > > I think metadata is probably good; or lazily-loaded sessions or > something. The metadata is important I think, because updating metadata > shouldn't be effected by locking and whatnot. I think Mike mentioned a > problem with locking and updating the timestamp contained in the session > -- we should avoid that. > > > ... where metadata includes the access time and whatever else we > > decide. Of course, iterating the content may be disk/memory intensive. > > Sure. We could have a callback to do filtering too, maybe with a > default filter by expiration time. Or event callbacks. > > > If .delete_expired_sessions() is included, the application would have to > > subclass SessionManager rather than just using it. That's not > > necessarily bad but a potential limitation. Or the application could > > kludge up a policy from your methods: > > > > cutoff = time.time() - (60 * 60 * 4) > > for sid in sm.session_ids(): > > if sm.last_accessed(sid) < cutoff: > > sm.delete_session(sid) > > > > I suppose kludgy is in the eye of the beholder. This would not be kludgy: > > > > cutoff = time.time() - (60 * 60 * 4) > > for sid, metadata in sm.iter_sessions(): > > if metadata.atime < cutoff: > > sm.delete_session(sid) > > > > Curses on anybody who says, "What's the difference?" > > > > PS. Kudos for using .names_with_underscores rather than .studlyCaps. > > > > Your other methods look all right at first glance. We'll know when we > > port existing frameworks to it whether it's adequate. (Or should that > > be "when we port it to existing frameworks"? Or "when we make existing > > frameworks use it as middleware"?) We'll also have to keep an eye on a > > usage pattern to recommend for future frameworks, and on whether this > > API has anything to do with the "sessionless" persistance patterns that > > have also been proposed. > > Acquiring or creating a session ID is outside of the scope of this > interface, but I think that's much of what would be useful to > sessionless users. Or, rather, people who want application-specific > sessions. > > > Interesting ideas you've had about read/write vs read-only sessions. > > I'd say let's support read-only sessions, and maybe that will encourage > > applications to use them. > > > > Session ID cookies seem like a generic thing this class should handle, > > especially for applications that don't otherwise use cookies. XML-RPC > > encapsulates the XML (an necessary evil); why shouldn't we encapsulate > > the cookie (another necessary evil)? > > XML-RPC contains the XML, but it doesn't deal with the transport really. > And, just using XML-RPC as an example, what if you want to stuff the > session ID inside the XML-RPC request instead of in a cookie header? > > But anyway, the reason I don't want to handle this is because this would > be much easier if building upon a Standard That Does Not Yet Exist, and > I'd rather avoid overlapping with that standard. > > >> Does that sound good? Note that the attached interface conflates > >> SessionStore and SessionManager. Some interfaces make an explicit > >> ApplicationSession, which is contained by Session and keyed off some > >> application ID; my interface implies that separation, but does not > >> enforce it, and does not offer any extra functionality at that level > >> (e.g., per-ApplicationSession locks or transactions). > >> > >> > > > > > > I'm not sure what you mean by ApplicationSession. Perl's session object > > is a dictionary, and you can store anything in it. Our top-level object > > has to be flexible due to grandfathering, unless we want to force > > applications to translate to/from our session object to their native > > session format. Yet you define certain attributes/methods the Session > > must have, which legacy Sessions don't. I guess allow the application > > to provide a subclass or compatible class, and let it worry about how to > > upgrade its native session object. > > I was thinking of pythonweb's "Store": > http://pythonweb.org/projects/webmodules/doc/0.5.3/html_multipage/lib/node153.html > > I vaguely suggest in the interface that each application should put all > of its data in a single key (based on the application name). Now I > think that should be based on a unique name (not the application name, > because the application may exist multiple times in the process), and > maybe with an entirely different manager. > > > Regarding sessionless persistence, that reminds me of a disagreement I > > had with Titus in designing session2. Quixote provides Session.user > > default None, but doesn't define what other values it can have. I put a > > full-fledged User object with username/group/permission info. Titus > > puts a string name and stores everything else in his application > > database. So his *SessionStore classes put the name in a VARCHAR column > > and didn't save the rest of the session data. I argued that "most > > people will have a User object, and they'll expect the entire Session to > > be pickled because that's what PHP/Perl do." He relented, so the > > current *SessionStores can be used either way. > > In the interface I suggest anything pickleable can go in a key. This > requirement has been the source of some controversy in Webware, since > people wanted to put open file objects and such in the session; mostly > people coming from Java where apparently that's the norm. Anyway, it's > still possible with this interface to have a store that never pickles > anything; I can just hope no one writes code they expect anyone else to > use that demands in-memory session storage. Those are lame even when > you are using threads. > > I think the example shows one reason the session shouldn't be considered > a public API. I think it's fine to put the username or the user object > in the session -- we can debate the pluses and minuses, but it works -- > but I think you should definitely wrap that implementation detail in > something else. E.g., request.user should return > request.session['user'] or something. > > > Perhaps applications should store all session data directly, keyed by > > session ID (and perhaps "username"), rather than using pickled > > Sessions. That would be a good idea for a parallel project. I'm not > > sure how relevant that would be to this API except to share "cookie > > code". This API + implementations are required in any case, both > > because "most users" will not consider Python if it doesn't have "robust > > session handling", and a common library would allow frameworks to use it > > rather than reinventing the wheel incompatibly. This is true regardless > > of the merits of sessions. > > I guess if applications each have their own SessionManager, they could > have their own Session classes, and if they wanted to the Session > objects could use application-specific storage and even an > application-specific API (not just a dictionary interface). I don't > know what the point of that would be, though, since it's all > application-specific and not generic, so you might as well just use the > session ID and ignore the rest of the API. > _______________________________________________ Web-SIG mailing list Web-SIG@python.org Web SIG: http://www.python.org/sigs/web-sig Unsubscribe: http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com