You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Vishy Kasar <vk...@borland.com> on 2001/08/08 00:25:18 UTC

Addition of 'dirty' field to Session interface

Hi,

In order to support persistent failover, we have written our own Store
class that writes session data to DB of our choice. We decided to use
maxIdleBackups as that will save the data periodically to disk without
getting rid of it in memory.
PersistentManagerBase.processMaxIdleBackups() writes the session data to
DB at periodical intervals irrespective of session has changed or not.
I think it will be very valuable addition to add getDirty() and
setDirty(boolean) methods to the Session interface. When
PersistentManagerBase saves the session contents, it can set dirty bit
to false and from then onwards save the session only if the bit is set
to true.

Selected setXXX methods in StandardSession will set the dirty bit to
true indicating that Session data has changed and it needs to be saved
in the next save cycle by PersistentManager.

Let me know what you guys think of this useful optimization. I can
contribute the code if necessary.

--
Cheers!




Re: Addition of 'dirty' field to Session interface

Posted by "Craig R. McClanahan" <cr...@apache.org>.

On Fri, 10 Aug 2001, Kief Morris wrote:

> Craig R. McClanahan typed the following on 12:40 PM 8/9/2001 -0700
> >> Now that I think about it though, any time a session is used in a request, 
> >its 
> >> lastAccessedTime will be updated, so the session must be considered dirty.
> >> So worrying about tracking attributes isn't necessary: the session only needs
> >> to be flagged dirty when it is retrieved. Tracking the dirty status is 
> >still a good 
> >> optimization, since it ensures sessions aren't saved multiple times between 
> >> requests, or after requests which never access the session.
> >> 
> >
> >If I knew that the access time had been updated but not any attributes, I
> >could probably distribute that information pretty cheaply (without having
> >to serialize and deserialize the attributes as well).  Thus, it's probably
> >worth distinguishing between the two cases.
> 
> But we're still stuck with trusting the user to signal that they've modified
> an attribute, which I'm not comfortable with. Asking them to call setAttribute()
> is fairly clean, portability wise, but we would be guaranteed to get a perpetual
> stream of developers missing that bit of the docs and asking why Catalina
> sometimes loses their session data across restarts. Plus people might use
> 3rd party code which doesn't conform to this Catalina-specific requirement.
> 
> I think my suggestion of flagging any attribute retrieved with getAttribute() 
> as dirty should guarantee modified attributes are always saved, although these
> would be unnecessarily saved if the attributes are only read. My opinion is
> that guaranteeing correctness without relying on developers following a
> non-standard technique is worth the trade-off.
> 
> Kief
> 
> 

Sounds like a policy decision we should leave in the hands of whoever
deploys the application (i.e. a configuration switch :-).

Craig



Re: Addition of 'dirty' field to Session interface

Posted by Kief Morris <ki...@bitbull.com>.
Craig R. McClanahan typed the following on 12:40 PM 8/9/2001 -0700
>> Now that I think about it though, any time a session is used in a request, 
>its 
>> lastAccessedTime will be updated, so the session must be considered dirty.
>> So worrying about tracking attributes isn't necessary: the session only needs
>> to be flagged dirty when it is retrieved. Tracking the dirty status is 
>still a good 
>> optimization, since it ensures sessions aren't saved multiple times between 
>> requests, or after requests which never access the session.
>> 
>
>If I knew that the access time had been updated but not any attributes, I
>could probably distribute that information pretty cheaply (without having
>to serialize and deserialize the attributes as well).  Thus, it's probably
>worth distinguishing between the two cases.

But we're still stuck with trusting the user to signal that they've modified
an attribute, which I'm not comfortable with. Asking them to call setAttribute()
is fairly clean, portability wise, but we would be guaranteed to get a perpetual
stream of developers missing that bit of the docs and asking why Catalina
sometimes loses their session data across restarts. Plus people might use
3rd party code which doesn't conform to this Catalina-specific requirement.

I think my suggestion of flagging any attribute retrieved with getAttribute() 
as dirty should guarantee modified attributes are always saved, although these
would be unnecessarily saved if the attributes are only read. My opinion is
that guaranteeing correctness without relying on developers following a
non-standard technique is worth the trade-off.

Kief


Re: Addition of 'dirty' field to Session interface

Posted by "Craig R. McClanahan" <cr...@apache.org>.

On Thu, 9 Aug 2001, Kief Morris wrote:

> Craig R. McClanahan typed the following on 12:57 PM 8/8/2001 -0700
> >> Another possibility would be to flag the session is dirty when getAttribute()
> >> is called - it would result in unnecessary saves since it assumes the 
> >attribute
> >> was modified even when it wasn't, but it would be safer.
> >
> >Someone has told me (haven't confirmed personally) that some app servers
> >treat a setAttribute() -- as opposed to getAttribute() -- as the signal to
> >set the internal "dirty" flag.  The idea is that, if your application
> >modifies the internal state of an existing session attribute, then you
> >should call session.setAttribute() again to notify the container.
> 
> Yes, flagging the session is dirty on setAttribute() makes sense. I was
> thinking that by also flagging it on getAttribute(), you're depending less
> on developers to take an extra step (calling setDirty() or making another
> call to setAttribute()). If an attribute is retrieved from the session, it may 
> have been modified, so make the assumption that it was just to be safe.
> But this could erase a lot of the benefit of the dirty flag optimization, since
> writes are typically more common than reads. 
> 
> Now that I think about it though, any time a session is used in a request, its 
> lastAccessedTime will be updated, so the session must be considered dirty.
> So worrying about tracking attributes isn't necessary: the session only needs
> to be flagged dirty when it is retrieved. Tracking the dirty status is still a good 
> optimization, since it ensures sessions aren't saved multiple times between 
> requests, or after requests which never access the session.
> 

If I knew that the access time had been updated but not any attributes, I
could probably distribute that information pretty cheaply (without having
to serialize and deserialize the attributes as well).  Thus, it's probably
worth distinguishing between the two cases.

> Vishy, what do you think?
> 
> Kief
> 
> 

Craig



Re: Addition of 'dirty' field to Session interface

Posted by Kief Morris <ki...@bitbull.com>.
Craig R. McClanahan typed the following on 12:57 PM 8/8/2001 -0700
>> Another possibility would be to flag the session is dirty when getAttribute()
>> is called - it would result in unnecessary saves since it assumes the 
>attribute
>> was modified even when it wasn't, but it would be safer.
>
>Someone has told me (haven't confirmed personally) that some app servers
>treat a setAttribute() -- as opposed to getAttribute() -- as the signal to
>set the internal "dirty" flag.  The idea is that, if your application
>modifies the internal state of an existing session attribute, then you
>should call session.setAttribute() again to notify the container.

Yes, flagging the session is dirty on setAttribute() makes sense. I was
thinking that by also flagging it on getAttribute(), you're depending less
on developers to take an extra step (calling setDirty() or making another
call to setAttribute()). If an attribute is retrieved from the session, it may 
have been modified, so make the assumption that it was just to be safe.
But this could erase a lot of the benefit of the dirty flag optimization, since
writes are typically more common than reads. 

Now that I think about it though, any time a session is used in a request, its 
lastAccessedTime will be updated, so the session must be considered dirty.
So worrying about tracking attributes isn't necessary: the session only needs
to be flagged dirty when it is retrieved. Tracking the dirty status is still a good 
optimization, since it ensures sessions aren't saved multiple times between 
requests, or after requests which never access the session.

Vishy, what do you think?

Kief


RE: Addition of 'dirty' field to Session interface

Posted by Tomas Rokicki <ro...@instantis.com>.
Best to do this by layering your own abstraction on top of Sessions.
That's what we do [although we don't use it to solve this particular
problem].

-tom
-----Original Message-----
From: Kief Morris [mailto:kief@bitbull.com]
Sent: Wednesday, August 08, 2001 12:36 PM
To: tomcat-dev@jakarta.apache.org
Subject: Re: Addition of 'dirty' field to Session interface


Jim Seach typed the following on 04:29 PM 8/7/2001 -0700
>> Selected setXXX methods in StandardSession will set the dirty bit to
>> true indicating that Session data has changed and it needs to be
>> saved
>> in the next save cycle by PersistentManager.
>
>But what happens if in one servlet you put an object in the session,
>then later, after the session has been saved, another request is
>handled by a different servlet that get's the object from the session
>and changes its state.
>
>In this case, you have to have the cooperation of the application
>developer to call setDirty(true) so you know something has changed.

This doesn't seem like a good idea - not only is it prone to developer
error as you said, it also makes any application which uses it non-portable
to other servlet containers.

Another possibility would be to flag the session is dirty when
getAttribute()
is called - it would result in unnecessary saves since it assumes the
attribute
was modified even when it wasn't, but it would be safer. Maybe it's possible
to use reflection to detect if an object has been modified? I've seen a DB
persistence package which appears to do this, although I haven't examined
that part of the code (ObjectBridge, aka OJB, on sourceforge).

Kief






Re: Addition of 'dirty' field to Session interface

Posted by "Craig R. McClanahan" <cr...@apache.org>.

On Wed, 8 Aug 2001, Kief Morris wrote:

> Jim Seach typed the following on 04:29 PM 8/7/2001 -0700
> >> Selected setXXX methods in StandardSession will set the dirty bit to
> >> true indicating that Session data has changed and it needs to be
> >> saved
> >> in the next save cycle by PersistentManager.
> >
> >But what happens if in one servlet you put an object in the session,
> >then later, after the session has been saved, another request is
> >handled by a different servlet that get's the object from the session
> >and changes its state.
> >
> >In this case, you have to have the cooperation of the application
> >developer to call setDirty(true) so you know something has changed.  
> 
> This doesn't seem like a good idea - not only is it prone to developer
> error as you said, it also makes any application which uses it non-portable
> to other servlet containers.
> 
> Another possibility would be to flag the session is dirty when getAttribute()
> is called - it would result in unnecessary saves since it assumes the attribute
> was modified even when it wasn't, but it would be safer. Maybe it's possible
> to use reflection to detect if an object has been modified? I've seen a DB
> persistence package which appears to do this, although I haven't examined
> that part of the code (ObjectBridge, aka OJB, on sourceforge).
> 

Someone has told me (haven't confirmed personally) that some app servers
treat a setAttribute() -- as opposed to getAttribute() -- as the signal to
set the internal "dirty" flag.  The idea is that, if your application
modifies the internal state of an existing session attribute, then you
should call session.setAttribute() again to notify the container.

I don't believe there is any general mechanism that a container can use to
tell whether the internal state of an application object has changed in a
way that is significant to the application.  The setAttribute() rule would
seem to be a reasonable alternative, because it lets the application tell
the container about changes - in a way that doesn't require servlet API
changes.


> Kief
> 

Craig



Re: Addition of 'dirty' field to Session interface

Posted by Kief Morris <ki...@bitbull.com>.
Jim Seach typed the following on 04:29 PM 8/7/2001 -0700
>> Selected setXXX methods in StandardSession will set the dirty bit to
>> true indicating that Session data has changed and it needs to be
>> saved
>> in the next save cycle by PersistentManager.
>
>But what happens if in one servlet you put an object in the session,
>then later, after the session has been saved, another request is
>handled by a different servlet that get's the object from the session
>and changes its state.
>
>In this case, you have to have the cooperation of the application
>developer to call setDirty(true) so you know something has changed.  

This doesn't seem like a good idea - not only is it prone to developer
error as you said, it also makes any application which uses it non-portable
to other servlet containers.

Another possibility would be to flag the session is dirty when getAttribute()
is called - it would result in unnecessary saves since it assumes the attribute
was modified even when it wasn't, but it would be safer. Maybe it's possible
to use reflection to detect if an object has been modified? I've seen a DB
persistence package which appears to do this, although I haven't examined
that part of the code (ObjectBridge, aka OJB, on sourceforge).

Kief





Re: Addition of 'dirty' field to Session interface

Posted by Jim Seach <jw...@yahoo.com>.
--- Vishy Kasar <vk...@borland.com> wrote:
> Hi,
> 
> In order to support persistent failover, we have written our own
> Store
> class that writes session data to DB of our choice. We decided to use
> maxIdleBackups as that will save the data periodically to disk
> without
> getting rid of it in memory.
> PersistentManagerBase.processMaxIdleBackups() writes the session data
> to
> DB at periodical intervals irrespective of session has changed or
> not.
> I think it will be very valuable addition to add getDirty() and
> setDirty(boolean) methods to the Session interface. When

Wouldn't this require a change to the Servlet API?  This is probably
not the right list for that :)

> PersistentManagerBase saves the session contents, it can set dirty
> bit
> to false and from then onwards save the session only if the bit is
> set
> to true.
> 
> Selected setXXX methods in StandardSession will set the dirty bit to
> true indicating that Session data has changed and it needs to be
> saved
> in the next save cycle by PersistentManager.

But what happens if in one servlet you put an object in the session,
then later, after the session has been saved, another request is
handled by a different servlet that get's the object from the session
and changes its state.

In this case, you have to have the cooperation of the application
developer to call setDirty(true) so you know something has changed.  

If you are going to rely on developers following some kind of
convention, it could probably be done without changes to the spec. 
What about asking them to call setAttribute("Dirty","True") whenever
they make a change?  Your PersistentManager could then remove the
attribute after a save. (not that I believe they would do this
consistently any more than they will call setDirty(true) )

Is there something I am missing?

Jim

> 
> Let me know what you guys think of this useful optimization. I can
> contribute the code if necessary.
> 
> --
> Cheers!
> 
> 
> 


__________________________________________________
Do You Yahoo!?
Make international calls for as low as $.04/minute with Yahoo! Messenger
http://phonecard.yahoo.com/