Understanding SessionVars and Objects

5 views
Skip to first unread message

johncch

unread,
Dec 9, 2009, 8:44:18 PM12/9/09
to Lift
Hi,

I'm trying to understand the implementation of MetaMegaProtoUser,
reading the code, there are a couple of conceptual questions that I'd
like to ask.

I understand object as a singleton class, or perhaps vaguely similar
to a static class (as in Java) so I'm wondering why is, in the
MetaMegaProtoUser trait, the curUserId an object.

In the sense, perhaps I can imagine an object inside an object is
simple a singleton within a singleton, but the confusion kinda arises
when it extends SessionVar. From my understanding of the functionality
of SessionVars, it actually keeps the user logged in across sessions.
So, I'm trying to understand how does a singleton in a singleton keeps
the log in information safe? If I have multiple users on the site at
the same time, why is the value not overwritten?

I suspect this is related to the deficiency in my knowledge in how
sessions are actually implemented, but please bear with me..

So, I look at the loggedIn_? method that is constantly called on the
User object, it actually looks at currentUserId.isDefined, so I assume
that the currentUserId, once set via the login method will persist
throughout the session. How is that achieved? Is there a method at the
beginning of lift's lifecycle that sets this variable via looking at
the session information?

Lastly, I'd like to ask where is the remove() method defined on the
curUserId private object? I've looked at the implementation of
SessionVar and AnyVar and I couldn't seem to find it.

I'm hacking on a small-ish project and it's been a fun and frustrating
journey so far. Love the framework, it makes doing things very
flexible and easy, but the flexibility of the language is kinda
daunting.. sometimes it really makes my brain hurt. But will try
harder!

regards,
CH

Ross Mellgren

unread,
Dec 9, 2009, 9:24:25 PM12/9/09
to lif...@googlegroups.com
On Dec 9, 2009, at 8:44 PM, johncch wrote:

> Hi,
>
> I'm trying to understand the implementation of MetaMegaProtoUser,
> reading the code, there are a couple of conceptual questions that I'd
> like to ask.
>
> I understand object as a singleton class, or perhaps vaguely similar
> to a static class (as in Java) so I'm wondering why is, in the
> MetaMegaProtoUser trait, the curUserId an object.
>
> In the sense, perhaps I can imagine an object inside an object is
> simple a singleton within a singleton, but the confusion kinda arises
> when it extends SessionVar. From my understanding of the functionality
> of SessionVars, it actually keeps the user logged in across sessions.
> So, I'm trying to understand how does a singleton in a singleton keeps
> the log in information safe? If I have multiple users on the site at
> the same time, why is the value not overwritten?

SessionVars are kind of like thread local variables. They have an internal "name" (which is guaranteed to be unique and is maintained by Lift) which is used to check in a dictionary the session keeps around with the values of each SessionVar for the current session.

When you access a SessionVar with myVar.is (or myVar.get, or using the implicit) under the covers it obtains the current session from a thread local variable in S (I believe, maybe it's in LiftSession) and then looks for the value for the variable in the current session. If not found, it executes the initializer to pick an initial value.

Similarly, when you set a SessionVar with myVar.set the same kind of thing happens except it stores the value you give it in the session.

So, the singleton within a singleton is essentially only keeping that unique name you don't need to know about.

> I suspect this is related to the deficiency in my knowledge in how
> sessions are actually implemented, but please bear with me..
>
> So, I look at the loggedIn_? method that is constantly called on the
> User object, it actually looks at currentUserId.isDefined, so I assume
> that the currentUserId, once set via the login method will persist
> throughout the session. How is that achieved? Is there a method at the
> beginning of lift's lifecycle that sets this variable via looking at
> the session information?

curUserId is set via the mechanism I describe earlier in MetaMetaProtoUser's login handling.

> Lastly, I'd like to ask where is the remove() method defined on the
> curUserId private object? I've looked at the implementation of
> SessionVar and AnyVar and I couldn't seem to find it.

It's on AnyVar. Finding where a method is implemented is made alot easier by using the vscaladocs and checking the "Inherited" box at the bottom right of each page. Here's a direct link to the lift-webkit docs (1.1-SNAPSHOT):

http://www.scala-tools.org/mvnsites-snapshots/liftweb/lift-webkit/scaladocs/index.html

By the way, if you're not using 1.1-SNAPSHOT (soon to be 2.0-SNAPSHOT), you definitely should. It's leagues ahead of 1.0 and tends to be stable.


> I'm hacking on a small-ish project and it's been a fun and frustrating
> journey so far. Love the framework, it makes doing things very
> flexible and easy, but the flexibility of the language is kinda
> daunting.. sometimes it really makes my brain hurt. But will try
> harder!

Good! If you get stuck always feel free to ask questions on the mailing list. We like helping.

-Ross

johncch

unread,
Dec 10, 2009, 1:52:03 AM12/10/09
to Lift
Thanks for the explanation!

> SessionVars are kind of like thread local variables. They have an internal "name" (which is guaranteed to be unique and is maintained by Lift) which is used to check in a dictionary the session keeps around with the values of each SessionVar for the current session.
>
> When you access a SessionVar with myVar.is (or myVar.get, or using the implicit) under the covers it obtains the current session from a thread local variable in S (I believe, maybe it's in LiftSession) and then looks for the value for the variable in the current session. If not found, it executes the initializer to pick an initial value.
>
> Similarly, when you set a SessionVar with myVar.set the same kind of thing happens except it stores the value you give it in the session.
>
> So, the singleton within a singleton is essentially only keeping that unique name you don't need to know about.
>

Is the object found via reflection? It's really interesting to me
actually I'd like to know how it really works under the cover.

Another small-ish question that I wanted to ask.. my textareas are
swallowing up html tags (actually converting them to &gt) somewhere
between clicking the save button and displaying them. Is there any
part of the code that does the escaping? I'm trying to look for it..

The scaladocs seem to be blank. Is there some sort of bug in the build
process?

Thanks

David Pollak

unread,
Dec 10, 2009, 9:25:07 AM12/10/09
to lif...@googlegroups.com
On Wed, Dec 9, 2009 at 10:52 PM, johncch <joh...@gmail.com> wrote:
Thanks for the explanation!

> SessionVars are kind of like thread local variables. They have an internal "name" (which is guaranteed to be unique and is maintained by Lift) which is used to check in a dictionary the session keeps around with the values of each SessionVar for the current session.
>
> When you access a SessionVar with myVar.is (or myVar.get, or using the implicit) under the covers it obtains the current session from a thread local variable in S (I believe, maybe it's in LiftSession) and then looks for the value for the variable in the current session. If not found, it executes the initializer to pick an initial value.
>
> Similarly, when you set a SessionVar with myVar.set the same kind of thing happens except it stores the value you give it in the session.
>
> So, the singleton within a singleton is essentially only keeping that unique name you don't need to know about.
>

Is the object found via reflection? It's really interesting to me
actually I'd like to know how it really works under the cover.

Very little reflection... just enough to determine the class name for the singleton.  The net.liftweb.util.AnyVars.scala file holds the core piece which is the name thing that Ross mentioned.  Each subclass has to implement a get and set that will take the name and translate it to the correct backing store (session-based for SessionVar and ThreadLocal based for RequestVar).
 

Another small-ish question that I wanted to ask.. my textareas are
swallowing up html tags (actually converting them to &gt) somewhere
between clicking the save button and displaying them. Is there any
part of the code that does the escaping? I'm trying to look for it..


I think you'll have to provide some code that is not working as you expect it to.  I don't understand the issue from the description you've give.

Thanks,

David
 
The scaladocs seem to be blank. Is there some sort of bug in the build
process?

Thanks

--

You received this message because you are subscribed to the Google Groups "Lift" group.
To post to this group, send email to lif...@googlegroups.com.
To unsubscribe from this group, send email to liftweb+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/liftweb?hl=en.





--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Surf the harmonics
Reply all
Reply to author
Forward
0 new messages