On May 30, 2008, at 9:44 AM, Martijn Faassen wrote:


Michael Bayer wrote:

[snip discussion on BoundMetadata I don't comprehend yet but probably should :)]

As far as ScopedSession, it's really just a thread local variable. Like any global threadlocal, you can stick whatever you want on it at the start of a request, and tear it down at the end.

Is it really needed to set things up at the start and the request and tear things down on the end, or can a session be retained between requests? I.e. is the intent to recreate a Session class each time a request is issued?

in the 0.4 series, the Session is "sticky" in that whatever is in it retains the state that was last loaded - 0.4 does not go back to the database to re-fetch the state of an object unless its explicitly told to do so. When an HTTP request ends, assuming all objects in the session are marked as "clean", they're weakly referenced and will fall out of scope assuming those objects were only referenced by the request. So in that sense, you can just leave the Session alone and it'll work just fine for the next request...but any pending changes in the Session that weren't flushed for some reason would get carried over, as well as anything that might be strongly referenced elsewhere. So we always recommended in 0.4 to at least issue a session.clear() at the end of a request to just empty it out (but you can still reuse that session). Other options included scopedsession.remove() which tears the whole session down, the advantage there being that the new request could configure the next session differently (as in, binding it to something else).

in 0.5, Session has been changed to be less reluctant to go and "re- fetch" data (which is contrary to the particular background I came from, but since then I've learned to see a broader scope of use cases). In 0.5, after a commit() or rollback(), the Session still may be holding on to objects, but their state is expired such that it will all be re-loaded upon access, and all "pending" and "deleted" states are reverted. So 0.5's Session, when configured in the default way, makes it very hard to get at "stale" state, so in that sense you can just re-use a session wihtout worrying much about what may have been left over.

Then again it's also reasonable that you might want to have individual ScopedSessions for each application instance within a multi-app process, that way the burden of setting up/tearing down is reduced or removed.

This indicates to me is possible to retain a Session object between two requests? I.e. it's a worthwhile goal to reduce the amount of Session configuration going on, right?

Its not a strong argument either way to reuse a session or just make a new one on each request. In 0.4, making a brand new session on each request does have a "cleaner" feel to it since theres no chance of any state left hanging around. Its not an expensive operation.

A single ScopedSession for a multi-app process is like a one- dimensional approach where both current thread and current app are identified by the current "get()" of the registry; a collection of ScopedSessions is more like a two-dimensional approach where the first level of registry (i.e. which ScopedSession do I choose) distinguishes between app instance, and the second level (i.e. what Session is bound to this thread ID) distinguishes between threads. All of that said I think it can work either way but I think the latter approach might have the explicitness you're looking for.

I'm trying to understand why you think so. I am looking for a way to let developers use SQLAlchemy in a straightforward way. They should be able to import 'Session', instantiate session in their app, and everything works as expected. The framework takes care of making you get the appropriately configured Session.

they can in fact do this without any issue. The question is, when someone writes the call "s = Session()" three times within one request, do you want each "s" to all reference the *same* set of objects ? that was the issue scoped_session() was meant to solve. Configuration is easy since you just configure a "Session" callable for that application.

But you guys have this issue of "multiple applications in the same process" at play, which each talk to a different database. So thats where a decision has to be made how to deal with that complexity, either configure engine on one scoped_session per request, or configure multiple scoped_sessions, one per engine. The latter approach seems "easier" to me since you don't actually have to do anything on a per-request basis assuming 0.5 usage. Neither of these make any difference to the end user who sees the exact same usage pattern.

(I'd still absolutely like to avoid passing in context explicitly each time you need a session; it puts unnecessary burden on the developer and promises to make multi-application interactions easier while it actually doesn't do so)

so one scoped_session() per app instance/engine seems like the easiest way to do this.

Zope-Dev maillist  -  Zope-Dev@zope.org
**  No cross posts or HTML encoding!  **
(Related lists - http://mail.zope.org/mailman/listinfo/zope-announce
http://mail.zope.org/mailman/listinfo/zope )

Reply via email to