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.

Reply via email to