nice to know ;)
On 2/21/07, Peter Stavrinides <[EMAIL PROTECTED]> wrote:
>
> Andrea,
> You can do this If you create a state object that has an application
> scope... you can wire your session listener to it to add and remove the
> session id's.
>
> <state-object name="ApplicationManager" scope="application">
>
> Andrea Chiumenti wrote:
> > But session is user specific and you want to lock the record accross the
> > application, how whould you do this ?
> >
> > On 2/21/07, Robert Zeigler <[EMAIL PROTECTED]> wrote:
> >>
> >> Actually, no, if the browser dies, the record won't stay locked.
> >> The updating happens from the edit page; if the browser crashes,
> >> there's no edit page, so no updating, so the lock expires.
> >>
> >> Cheers,
> >>
> >> Robert
> >>
> >> On Feb 21, 2007, at 2/214:03 AM , Andrea Chiumenti wrote:
> >>
> >> > ... But if the browser dies for some reason (very frequent
> >> > especially with
> >> > MS products), then the record will remain locked, the only
> >> > possibility with
> >> > this solution would be to add a locking timeout with application
> >> > scope.
> >> >
> >> > On 2/21/07, Robert Zeigler <[EMAIL PROTECTED]> wrote:
> >> >>
> >> >> In my case, it was straightforward: the user is considered to be
> >> >> "still editing" if they have a browser window open to the edit page
> >> >> for the object in question; if they navigate away from that page,
> the
> >> >> system considers their edit session over.
> >> >>
> >> >> Robert
> >> >>
> >> >>
> >> >> On Feb 21, 2007, at 2/212:47 AM , Peter Stavrinides wrote:
> >> >>
> >> >> > Hi Robert
> >> >> >
> >> >> > I like your idea, "you say that periodic ajax calls are sent to
> the
> >> >> > server to inform of the fact that the user is still editing" how
> >> >> > exactly do you track if a user is still editing?
> >> >> >
> >> >> > Robert Zeigler wrote:
> >> >> >> The main problem with using a session timeout for the lock is
> that
> >> >> >> it doesn't allow you to detect events where a user starts to edit
> >> >> >> an object, does not finish, but remains active in the webapp; the
> >> >> >> session won't die, and neither will your lock. You have to
> >> >> >> incorporate time at least to some degree. I implemented similar
> >> >> >> functionality in an application recently, but used a bit of ajax
> >> >> >> magic to ensure that the lock was held for exactly as long as it
> >> >> >> needed to be and no longer (while the user is editing the object,
> >> >> >> periodic ajax calls are sent to the server to inform of the fact
> >> >> >> that the user is still editing; if the user saves, the lock is
> >> >> >> released; if the user moves to a different portion of the webapp
> >> >> >> without saving or canceling the lock, the lock expires since
> there
> >> >> >> are no more ajax calls to keep the lock valid)
> >> >> >>
> >> >> >> Robert
> >> >> >>
> >> >> >> On Feb 21, 2007, at 2/211:56 AM , Peter Stavrinides wrote:
> >> >> >>
> >> >> >>> I don't think the benefits justify the effort involved to
> >> >> >>> maintain all those timestamps, its a bit too complex. Perhaps
> its
> >> >> >>> better to stick to a single table as well... rather write the
> >> >> >>> session id into the database to checkout a customer record.
> >> >> >>>
> >> >> >>> Allow updates to a customer record if its not checked out, and
> >> >> >>> this way you have no worries about lock expiration etc.
> >> >> >>>
> >> >> >>> You should maintain an ASO that tracks all active sessions by
> >> >> >>> session id. Once a user queries for a customer record that has
> >> >> >>> been checked out, if the session ID still exists in the ASO,
> then
> >> >> >>> refuse update access and grant only read access, simple and
> >> >> >>> elegant. Once the user saves successfully release the lock in
> the
> >> >> >>> database. if a session is interrupted for whatever reason, then
> >> >> >>> using a session timeout of 20 or 30 minutes and a session
> >> >> >>> listener you clean up removing the session ID from the ASO and
> >> >> >>> database... so you are well covered. I am no guru like some of
> >> >> >>> these other guys, but this works for me and its nice and
> >> >> >>> simple... here is a brief implementation outline:
> >> >> >>>
> >> >> >>> public class ApplicationManager {
> >> >> >>>
> >> >> >>> /** variable to store the singleton ApplicationManager */
> >> >> >>> private static final ApplicationManager
> >> >> >>> applicationManagerInstance_ = new ApplicationManager();
> >> >> >>>
> >> >> >>> /** Hashtable containing visit history objects. <String,Visit>
> is
> >> >> >>> the sessionid and the Visit Object */
> >> >> >>> private static ConcurrentHashMap<String,Visit> visitHistory_ =
> >> >> >>> new ConcurrentHashMap<String,Visit>();
> >> >> >>>
> >> >> >>> /** @return the ApplicationManager instance */
> >> >> >>> public synchronized static ApplicationManager getInstance(){
> >> >> >>> return applicationManagerInstance_;
> >> >> >>> }
> >> >> >>>
> >> >> >>> }
> >> >> >>>
> >> >> >>> public class SessionMonitor implements HttpSessionListener {
> >> >> >>>
> >> >> >>> /** @see javax.servlet.http.HttpSessionListener#sessionDestroyed
> >> >> >>> (javax.servlet.http.HttpSessionEvent) */
> >> >> >>> public void sessionDestroyed(HttpSessionEvent event) {
> >> >> >>> String sid = event.getSession().getId();
> >> >> >>> ApplicationManager manager = ApplicationManager.getInstance();
> >> >> >>> manager.removeUserSession(sid);
> >> >> >>> }
> >> >> >>>
> >> >> >>>
> >> >> >>> Hivemodule.xml:
> >> >> >>>
> >> >> >>> <contribution configuration-
> >> >> id="tapestry.state.ApplicationObjects">
> >> >> >>> <state-object name="visit" scope="session">
> >> >> >>> <create-instance class="application.Visit"/>
> >> >> >>> </state-object>
> >> >> >>> </contribution>
> >> >> >>>
> >> >> >>> <contribution configuration-
> >> >> id="tapestry.state.ApplicationObjects">
> >> >> >>> <state-object name="ApplicationManager" scope="application">
> >> >> >>> <create-instance class="application.ApplicationManager"/>
> >> >> >>> </state-object>
> >> >> >>> </contribution>
> >> >> >>>
> >> >> >>> cheers,
> >> >> >>> Peter
> >> >> >>>
> >> >> >>> Murray Collingwood wrote:
> >> >> >>>> Wow - what a lot of responses.
> >> >> >>>>
> >> >> >>>> First a little more detail - use case (for example):
> >> >> >>>>
> >> >> >>>> Take a customer record, a basic record has previously been
> >> >> >>>> created and the
> >> >> >>>> customer has completed some forms so we are now wanting to
> >> >> >>>> complete all of the
> >> >> >>>> details about contact information, financial details, key
> >> >> >>>> assets, health
> >> >> >>>> information, etc, etc. The system relies on a number of
> >> >> >>>> classifications which
> >> >> >>>> need to be looked up, anyways, editing this record can take
> upto
> >> >> >>>> 20 minutes. The size of this record certainly justifies
> breaking
> >> >> >>>> it up into a number of
> >> >> >>>> smaller records stored in separate tables, however the same
> >> >> >>>> problem remains
> >> >> >>>> because the user wants to see all of this information on 1
> >> >> >>>> (scrollable) web
> >> >> >>>> page, we are still holding a lock on the information for the
> >> >> >>>> duration of the
> >> >> >>>> request.
> >> >> >>>>
> >> >> >>>> Potentially there are maybe 700 people who could be editing
> this
> >> >> >>>> record for
> >> >> >>>> different reasons. Accuracy of the information is critical - we
> >> >> >>>> don't want
> >> >> >>>> personal details being sent to a neighbour.
> >> >> >>>>
> >> >> >>>> The nature of the application means that users will be
> reviewing
> >> >> >>>> a record each
> >> >> >>>> year, and if any changes are made they are often made to the
> >> >> >>>> same record around
> >> >> >>>> the same time of the year - increasing the possibility of two
> >> >> >>>> people wanting to
> >> >> >>>> edit the record at the same time.
> >> >> >>>>
> >> >> >>>> Besides all of the above, the user has asked for exclusive
> >> >> >>>> editing of a record -
> >> >> >>>> such that other users can still read the existing record but
> >> >> >>>> nobody else can
> >> >> >>>> update the record while it is locked. The user understands the
> >> >> >>>> concept of
> >> >> >>>> networks issues and broken connections and therefore accepts a
> >> >> >>>> timeout condition
> >> >> >>>> on the lock of say 20 minutes.
> >> >> >>>>
> >> >> >>>> Next, how I will do this:
> >> >> >>>>
> >> >> >>>> 1. To establish a lock:
> >> >> >>>> a. I need a LOCK table: foreign-key, timestamp, userid
> >> >> >>>> b. In my Session I need a collection of timestamps
> >> >> >>>> c. Create a timestamp value - add it to my collection of
> >> >> timestamps
> >> >> >>>> d. Add a record to the LOCK table using my timestamp value
> >> >> >>>> e. Select from the lock table by foreign-key - if mine is the
> >> >> >>>> only record then
> >> >> >>>> read the record and begin editing, the lock was successful
> >> >> >>>>
> >> >> >>>> 2. Release the lock: (PS This is the difficult bit)
> >> >> >>>> a. Retrieve the LOCK records by foreign-key and userid,
> >> >> >>>> hopefully there should
> >> >> >>>> only be one.
> >> >> >>>> b. Check the timestamp value against my Session collection of
> >> >> >>>> timestamp values
> >> >> >>>> c. If the timestamp is in my collection then save the edited
> >> >> >>>> record and delete
> >> >> >>>> my LOCK record
> >> >> >>>> d. If the timestamp is not in my collection then the save has
> >> >> >>>> failed - tell the
> >> >> >>>> user gently
> >> >> >>>>
> >> >> >>>> 3. Dealing with an existing lock:
> >> >> >>>> a. While trying to establish a lock I find 2 LOCK records
> >> >> >>>> b. The latest record is mine, ignore that and look at the
> >> >> >>>> earlier record
> >> >> >>>> c. Look at the timestamp on the earlier record, if older than
> 20
> >> >> >>>> minutes then
> >> >> >>>> delete this record and continue as normal
> >> >> >>>> d. Look at the userid on the earlier record, if it is mine then
> >> >> >>>> delete it and
> >> >> >>>> continue as normal (assumes my browser died, rebooted my
> >> >> >>>> computer, whatever,
> >> >> >>>> it's very typical for people to go straight back to what they
> >> >> >>>> were doing when
> >> >> >>>> their system crashed)
> >> >> >>>> e. If the timestamp is less than 20 minutes old then delete my
> >> >> >>>> LOCK record and
> >> >> >>>> report to the user that the record is locked by another user
> >> >> >>>>
> >> >> >>>> 4. You may want a maintenance process that cleans up broken
> >> >> >>>> locks, automatically
> >> >> >>>> deleting locks with a timestamp older than 24 hours. You could
> >> >> >>>> schedule this
> >> >> >>>> nightly or weekly - it's not critical.
> >> >> >>>>
> >> >> >>>>
> >> >> >>>> Why the collection of timestamps?
> >> >> >>>>
> >> >> >>>> 1. It allows the user to use the back button on the browser,
> >> >> >>>> either during
> >> >> >>>> editing or after editing (if it didn't save correctly the first
> >> >> >>>> time).
> >> >> >>>>
> >> >> >>>> 2. They might need to edit a related record in a different
> table
> >> >> >>>> as part of
> >> >> >>>> updating the main record - by storing each timestamp in a
> >> >> >>>> session collection we
> >> >> >>>> don't need to maintain these timestamps on our forms.
> >> >> >>>>
> >> >> >>>>
> >> >> >>>> Why add the lock record first?
> >> >> >>>>
> >> >> >>>> To avoid sequence problems like:
> >> >> >>>> a: User 1 looks for lock on id=1 - none found
> >> >> >>>> b: User 2 looks for lock on id=1 - none found
> >> >> >>>> c: User 1 adds a lock record
> >> >> >>>> d: user 2 adds a lock record
> >> >> >>>> Now the worst possible outcome is:
> >> >> >>>> a: User 1 adds a lock record on id=1
> >> >> >>>> b: User 2 adds a lock record on id=1
> >> >> >>>> c: Both users read and find two records with short timestamps -
> >> >> >>>> they are both
> >> >> >>>> informed the record is in use and to try again later - both
> >> >> >>>> records are deleted.
> >> >> >>>>
> >> >> >>>>
> >> >> >>>> Finally - the weakness:
> >> >> >>>>
> >> >> >>>> 1. The lock this gives you is only guaranteed for 20 minutes.
> >> >> >>>> Once that time is
> >> >> >>>> up somebody else can overwrite your lock with their own. It is
> >> >> >>>> better to set
> >> >> >>>> this timeout higher rather than lower.
> >> >> >>>>
> >> >> >>>> 2. You can overwrite your own lock. A user could open two
> >> >> >>>> browsers and edit the
> >> >> >>>> same record in each, the latter save overwriting the first.
> >> >> >>>> Hmmm, I think this
> >> >> >>>> comes under 'user error'.
> >> >> >>>>
> >> >> >>>>
> >> >> >>>> I think that explains it fairly well.
> >> >> >>>>
> >> >> >>>> Cheers
> >> >> >>>> mc
> >> >> >>>>
> >> >> >>>>
> >> >> >>>>
> >> >> >>>>
> >> >> -------------------------------------------------------------------
> >> >> >>>> --
> >> >> >>>> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >> >> >>>> For additional commands, e-mail: [EMAIL PROTECTED]
> >> >> >>>>
> >> >> >>>>
> >> >> >>>
> >> >> >>> --Peter Stavrinides
> >> >> >>> Albourne Partners (Cyprus) Ltd
> >> >> >>> Tel: +357 22 750652
> >> >> >>> If you are not an intended recipient of this e-mail, please
> >> >> >>> notify the sender, delete it and do not read, act upon, print,
> >> >> >>> disclose, copy, retain or redistribute it. Please visit http://
> >> >> >>> www.albourne.com/email.html for important additional terms
> >> >> >>> relating to this e-mail.
> >> >> >>
> >> >> >>
> >> >> >>
> >> >>
> ---------------------------------------------------------------------
> >> >> >> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >> >> >> For additional commands, e-mail: [EMAIL PROTECTED]
> >> >> >>
> >> >> >
> >> >> > --
> >> >> > Peter Stavrinides
> >> >> > Albourne Partners (Cyprus) Ltd
> >> >> > Tel: +357 22 750652
> >> >> > If you are not an intended recipient of this e-mail, please notify
> >> >> > the sender, delete it and do not read, act upon, print, disclose,
> >> >> > copy, retain or redistribute it. Please visit http://
> >> >> > www.albourne.com/email.html for important additional terms
> relating
> >> >> > to this e-mail.
> >> >> >
> >> >> >
> >> >> >
> >> >>
> ---------------------------------------------------------------------
> >> >> > To unsubscribe, e-mail: [EMAIL PROTECTED]
> >> >> > For additional commands, e-mail: [EMAIL PROTECTED]
> >> >>
> >> >>
> >> >>
> ---------------------------------------------------------------------
> >> >> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >> >> For additional commands, e-mail: [EMAIL PROTECTED]
> >> >>
> >> >>
> >>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >> For additional commands, e-mail: [EMAIL PROTECTED]
> >>
> >>
> >
>
> --
> Peter Stavrinides
> Albourne Partners (Cyprus) Ltd
> Tel: +357 22 750652
>
> If you are not an intended recipient of this e-mail, please notify the
> sender, delete it and do not read, act upon, print, disclose, copy, retain
> or redistribute it. Please visit http://www.albourne.com/email.html for
> important additional terms relating to this e-mail.
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>