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
(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 -