On 04/28/2014 11:28 PM, Mike Orr wrote:
On Mon, Apr 28, 2014 at 3:07 PM, Chris McDonough <[email protected]> wrote:
On 04/28/2014 04:05 PM, Jonathan Vanasco wrote:
IMO, the point of an interface is to provide an abstract API which folks can
meet to provide alternate implementations. If server-side session
implementations had a session id, but client-side session implementations
did not, it would mean that *deployers* of an application could not switch
out the sessioning implementation from one to the other and still expect the
parts of their applications which rely on sessions to work, which is AFAICT
exactly what you're objecting to now.
We don't need two interfaces. We just need an interface that says
'session.id' or 'session.get_session_id()' should return the session
ID string, or None if it doesn't support session IDs or doesn't wish
to expose it. Presto, everybody's problem is solved.
FWIW, I'd consider this problem created rather than solved in a scenario
that I'd like to support. I create applications that are themselves
frameworks (e.g. substanced). These applications rely on being able to
let deployers of those applications (note: these are not necessarily the
same people as the developers of all the various parts of the
application) configure in different sessioning implementations based on
their deployment requirements. For example, some systems are deployed
across multiple app servers, and the deployer may therefore need to use
cookie-based sessions or a shared backend session store to make sure the
same session data can be read by all of the appservers. These
applications also, in the meantime, allow pluggability of add-ons
written by unrelated people.
In this scenario, what happens when someone writes an add-on that (just
because it's available) uses the session id as a key into something, and
the deployer uses this add-on, and the session implementation the
deployer has configured in returns None from get_session_id? Nothing
good, AFAICT. What's the add-on code meant to do in this circumstance?
Either the add-on has to check for None as a return value from
get_session_id, or it has to check that the current sessioning
implementation implements the interface that supports a non-None return
value from get_session_id. And what if it does return None? What's the
add-in meant to do?
There is effectively no difference between this and having two
interfaces. In either case, the add-on implementer has to be aware that
not every sessioning implementation supports returning non-None session
ids. And you can bet that they won't, and instead of actually working,
the add-on is going to use None as a key into something that expects it
to be a unique session id value, and things are going to break in
strange ways. Detecting and fixing this breakage will be turned into
the deployer's problem when it really should be the application and/or
add-on developer's problem. Right now, without a get_session_id
interface, it just *is* the developer's problem, which puts the onus on
them to think about it, and this is the right division of responsibility
IMO.
FWIW, I've made similar mistakes in creating APIs in other pluggable
systems where I define a single interface that effectively requires a
capabilities check against its return value, and it has never ended
well. There are probably even some APIs like this in Pyramid; but it's
a poor pattern.
The only difference between this
scenario and the one you're objecting to is that you started relying on
something *outside* the interface, and when you changed to using something
that actually complied with it, you got hosed.
I switched from Pylons to Pyramid and got hosed. Pyramid is supposed
to be better than Pylons and more flexible, but in this case it's
worse and less flexible.
You are confusing flexible with featureful, AFAICT. Not requiring a
sesion id is more flexible than requiring one. Smaller APIs are
generally more flexible than larger ones.
You seem to be disappointed that you had to add code to maintain a
session id. Given that you are *not* writing a pluggable system, and
you control the horizontal and vertical of both the application code and
the deployment, how much code was it? Was it more code than a function
like this?
def get_session_id(session):
return session.setdefault('myapp.sessionid', uuid.uuid4())
Replace uuid.uuid4() with whatever makes sense for your system, of
course. Note that this is more flexible than Pyramid mandating the
composition of a session id, because you can make it whatever the heck
you want, as long as it meets the uniqueness requirements for your
deployment.
The Pyramid interface is less useful than Beaker's. That's a
limitation of the Pyramid interface, and can arguably be considered a
bug.
In the meantime, AFAICT, it's reasonably simple to put a random id (or
... in the session
dict. This would make the application run under any sessioning
implementation.
That's what I ended up doing, but why not have a standard way to get
the session ID?
No one, AFAICT, has described what they actually use the session id for.
If you have, I'm sorry, and I've missed it. But all the traffic about
this seems a bit misplaced without some examples.
client-side sessions don't have an id, but server-side sessions require
it. because pyramid doesn't have an official interface to support this,
all server side session libraries need to implement this themselves --
somehow -- to support it. I stress "somehow". There's no way to ensure
or expect consistency in this across libraries. If you look at how
different session providers in the ecosystem have dealt with this, there
is little uniformity in approach. I've seen `session_id`,
`_session_id`, `sessionID` and a few other variations -- both as
attributes and internal dict values. If ISession had an official
`session_id` attribute, then people developing server side libraries
would adapt to that; there would be uniformity and portability. Those
using client-side sessions would never use or expect a session_id , and
not be inconvenienced.
I *tried* to write a 'pyramid_[session]' library...
I *tried* to modify 'pyramid_redis_sessions' to put the ID as
'session.id' or 'session["id"]''...
I *tried* to understand how Beaker did it...
But every time I got lost in how they generate the ID and manage the
cookie. And when I tried to just read the cookie in my tween, I
realized I would have to unsign it and get the secret... all the stuff
that the session library does, and why should I have to reimplement it
all? Why can't the library just have a METHOD that I can CALL?
Everything else in Pyramid does.
I hope the above and my prior emails explain the why-not.
- C
--
You received this message because you are subscribed to the Google Groups
"pylons-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/pylons-discuss.
For more options, visit https://groups.google.com/d/optout.