Re: getSession, componentized but not async?

Carl Waldbieser <[email protected]> Thu, 7 Jul 2016 08:14:23 -0400
Newsgroups gmane.comp.python.twisted.web
Message-ID <CAHPVzqan=+DFi0FdQwPCpNLKQQt9bXmp3+Pz_T8MuWD=yiuo3Q@mail.gmail.com>
--===============1845187751608425744==
Content-Type: multipart/alternative; boundary=001a114f32586c8f5a05370aa07a

--001a114f32586c8f5a05370aa07a
Content-Type: text/plain; charset=UTF-8

Creating the session follows the normal Twisted modus operandi-- create a
factory that returns the actual thing you want and attach the session to
your site.  I wrote an authenticating web proxy[1] that does just that.  If
you skim down to the `sessionFactory()` function, you can see it is not
overly complicated.

The docs on storing objects in a session[2] are a bit complex.  They are
basically taking the approach where the idea is when you can
`request.getSession()`, you can pass in an interface and get back an object
that corresponds to that interface.  This can actually be useful in larger
systems where you are making use of heavily componentized code, but in some
cases it does seem like overkill.

Since the main thing that the stock `Session` buys you is expiration, you
can use the `Session.notifyOnExpire()` method to update other data
structures.  My authenticating proxy took that approach for keeping track
of authenticated users (see the "txcasproxy.py" file around the `_expired`
function).

As for persisting session data-- I guess the idea is that storing or
retrieving the session object doesn't need to be async because it is just
an object in memory corresponding to a cookie in the request.  However,
writing to or reading from the session could definitely require async
methods that talk to a back end store.  This could potentially be one area
where implementing a component with an interface like
`IRedisSessionStorage` might be useful (get session synchonously from
request passing in IRedisStorage,  then call `storeThingInSession()` which
returns a deferred).

Thanks,
Carl


[1]
https://github.com/cwaldbieser/txcasproxy/blob/master/txcasproxy/service.py

[2]
https://twistedmatrix.com/documents/current/web/howto/web-in-60/session-store.html


On Tue, Jul 5, 2016 at 12:03 PM, Donal McMullan <[email protected]>
wrote:

> I'm curious about request.getSession
>
> Per the docs:
> https://twistedmatrix.com/documents/current/web/howto/using-twistedweb.html
>
> It seems like it's tricky to use correctly. My code needs to:
>  - define an Interface
>  - define a class that implements my Interface
>  - call registerAdapter, passing in my class, server.Session and my
> Interface
>  - get a Session instance
>  - brace myself
>  - create an instance of my Interface class, passing in the Session
> instance
>  - update that Interface instance.... it will persisted, but only in-memory
>
> By default, that data doesn't go to database/memcached/whatever, so it's
> only accessible in-process
>
> On first blush, that seems like a lot of legwork. I'm not clear on what
> utility's provided by all this versus say maintaining a dict as a
> class-attribute on Site or something. It's also (for me) counter-intuitive
> to be creating an instance of an _Interface_ and poking data into it.
>
> Also I was a bit surprised that getSession doesn't return a deferred,
> since it seems like it'd be common to want to persist session data in an
> external store so that multiple twisted-web processes can access it in a
> clustered/load-balanced setup. How do other folks go about that?
>
> I hacked something together a while ago to run session data into Redis,
> but what I ended up with required so much surgery on twisted web's classes
> that I figured I must be doing it wrong. I think Site, SessionFactory and
> Request were all customised.
>
> I was thinking about this again in the context of Cory's "Implement
> server-side HTTP/2 server push" ticket:
> https://twistedmatrix.com/trac/ticket/8485
>
> In this context, I'd like to have access to my session data in multiple
> Resource objects without _necessarily_ having to round-trip to an external
> store each time to get/put the same data. In the case of http 1.1 requests,
> I guess there's no way around that round-trip, so it might be optimal if my
> Resource objects could be oblivious to the underlying protocol version and
> Session get/put mechanism.
>
> So it'd be great if the default Session mechanism could take care of me
> there, and I could just have my cake and eat it.
>
> Another wrinkle that surprised me when I was hacking on this was that
> there didn't seem to be a way to uniquely identify a request instance, so
> within the session code it was impossible to tell if two calls to
> getSession were coming from different points in the callback chain
> responding to a single Request, or if the second belonged to a different
> Request entirely.
>
> So my confusion is probably apparent at this stage :)
>
> I'm guessing others have been here before me. What approaches have you
> taken to storing your sessions? Are there good open source projects that I
> should look to for best practice?
>
> Thanks!
>
> DJM
>
>
>
>
> _______________________________________________
> Twisted-web mailing list
> [email protected]
> http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web
>
>

--001a114f32586c8f5a05370aa07a
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><div><div><div><div>Creating the session follows the =
normal Twisted modus operandi-- create a factory that returns the actual th=
ing you want and attach the session to your site.=C2=A0 I wrote an authenti=
cating web proxy[1] that does just that.=C2=A0 If you skim down to the `ses=
sionFactory()` function, you can see it is not overly complicated.<br><br><=
/div>The docs on storing objects in a session[2] are a bit complex.=C2=A0 T=
hey are basically taking the approach where the idea is when you can `reque=
st.getSession()`, you can pass in an interface and get back an object that =
corresponds to that interface.=C2=A0 This can actually be useful in larger =
systems where you are making use of heavily componentized code, but in some=
 cases it does seem like overkill.<br><br></div>Since the main thing that t=
he stock `Session` buys you is expiration, you can use the `Session.notifyO=
nExpire()` method to update other data structures.=C2=A0 My authenticating =
proxy took that approach for keeping track of authenticated users (see the =
&quot;txcasproxy.py&quot; file around the `<span class=3D""></span><span cl=
ass=3D"">_expired` function).<br><br></span></div><span class=3D"">As for p=
ersisting session data-- I guess the idea is that storing or retrieving the=
 session object doesn&#39;t need to be async because it is just an object i=
n memory corresponding to a cookie in the request.=C2=A0 However, writing t=
o or reading from the session could definitely require async methods that t=
alk to a back end store.=C2=A0 This could potentially be one area where imp=
lementing a component with an interface like `IRedisSessionStorage` might b=
e useful (get session synchonously from request passing in IRedisStorage,=
=C2=A0 then call `storeThingInSession()` which returns a deferred).<br><br>=
</span></div><span class=3D"">Thanks,<br></span></div><span class=3D"">Carl=
 <br></span><div><div><div><div><div><br><br>[1] <a href=3D"https://github.=
com/cwaldbieser/txcasproxy/blob/master/txcasproxy/service.py">https://githu=
b.com/cwaldbieser/txcasproxy/blob/master/txcasproxy/service.py</a><br><br>[=
2] <a href=3D"https://twistedmatrix.com/documents/current/web/howto/web-in-=
60/session-store.html">https://twistedmatrix.com/documents/current/web/howt=
o/web-in-60/session-store.html</a><br><br></div></div></div></div></div></d=
iv><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">On Tue, Jul 5,=
 2016 at 12:03 PM, Donal McMullan <span dir=3D"ltr">&lt;<a href=3D"mailto:d=
[email protected]" target=3D"_blank">[email protected]</a>&gt;=
</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .=
8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">I&#39;m c=
urious about request.getSession<div><br></div><div>Per the docs:</div><div>=
<a href=3D"https://twistedmatrix.com/documents/current/web/howto/using-twis=
tedweb.html" target=3D"_blank">https://twistedmatrix.com/documents/current/=
web/howto/using-twistedweb.html</a><br></div><div><br></div><div>It seems l=
ike it&#39;s tricky to use correctly. My code needs to:</div><div>=C2=A0- d=
efine an Interface</div><div>=C2=A0- define a class that implements my Inte=
rface</div><div>=C2=A0- call registerAdapter, passing in my class, server.S=
ession and my Interface</div><div>=C2=A0- get a Session instance</div><div>=
=C2=A0- brace myself</div><div>=C2=A0- create an instance of my Interface c=
lass, passing in the Session instance</div><div>=C2=A0- update that Interfa=
ce instance.... it will persisted, but only in-memory</div><div><br></div><=
div>By default, that data doesn&#39;t go to database/memcached/whatever, so=
 it&#39;s only accessible in-process</div><div><br></div><div>On first blus=
h, that seems like a lot of legwork. I&#39;m not clear on what utility&#39;=
s provided by all this versus say maintaining a dict as a class-attribute o=
n Site or something. It&#39;s also (for me) counter-intuitive to be creatin=
g an instance of an _Interface_ and poking data into it.</div><div><br></di=
v><div>Also I was a bit surprised that getSession doesn&#39;t return a defe=
rred, since it seems like it&#39;d be common to want to persist session dat=
a in an external store so that multiple twisted-web processes can access it=
 in a clustered/load-balanced setup. How do other folks go about that?</div=
><div><br></div><div>I hacked something together a while ago to run session=
 data into Redis, but what I ended up with required so much surgery on twis=
ted web&#39;s classes that I figured I must be doing it wrong. I think Site=
, SessionFactory and Request were all customised.</div><div><br></div><div>=
I was thinking about this again in the context of Cory&#39;s &quot;Implemen=
t server-side HTTP/2 server push&quot; ticket:</div><div><a href=3D"https:/=
/twistedmatrix.com/trac/ticket/8485" target=3D"_blank">https://twistedmatri=
x.com/trac/ticket/8485</a></div><div><br></div><div>In this context, I&#39;=
d like to have access to my session data in multiple Resource objects witho=
ut _necessarily_ having to round-trip to an external store each time to get=
/put the same data. In the case of http 1.1 requests, I guess there&#39;s n=
o way around that round-trip, so it might be optimal if my Resource objects=
 could be oblivious to the underlying protocol version and Session get/put =
mechanism.</div><div><br></div><div>So it&#39;d be great if the default Ses=
sion mechanism could take care of me there, and I could just have my cake a=
nd eat it.</div><div><br></div><div>Another wrinkle that surprised me when =
I was hacking on this was that there didn&#39;t seem to be a way to uniquel=
y identify a request instance, so within the session code it was impossible=
 to tell if two calls to getSession were coming from different points in th=
e callback chain responding to a single Request, or if the second belonged =
to a different Request entirely.</div><div><br></div><div>So my confusion i=
s probably apparent at this stage :)</div><div><br></div><div>I&#39;m guess=
ing others have been here before me. What approaches have you taken to stor=
ing your sessions? Are there good open source projects that I should look t=
o for best practice?</div><div><br></div><div>Thanks!</div><div><br></div><=
div>DJM</div><div><br></div><div><br></div><div><br></div></div>
<br>_______________________________________________<br>
Twisted-web mailing list<br>
<a href=3D"mailto:[email protected]">Twisted-web@twistedmatrix.=
com</a><br>
<a href=3D"http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web" r=
el=3D"noreferrer" target=3D"_blank">http://twistedmatrix.com/cgi-bin/mailma=
n/listinfo/twisted-web</a><br>
<br></blockquote></div><br></div>

--001a114f32586c8f5a05370aa07a--


--===============1845187751608425744==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Twisted-web mailing list
[email protected]
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web

--===============1845187751608425744==--