You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Reinhard Poetz <re...@apache.org> on 2005/05/02 10:05:26 UTC

Continuation invalidation strategy

Today I've had a look at continuation invalidation. I found following code 
fragment in the ContinuationManagerImpl:

// REVISIT: This places only the "leaf" nodes in the expirations Sorted Set.
// do we really want to do this?
if (parent.getChildren().size() < 2) {
     expirations.remove(parent);
}

Is it right that this means that only if a leaf continuation expires, the 
continuations tree is walked up and parent continuations are checked whether 
they have expired?

If you have a long expiration time set, does it mean that the whole! tree is 
never checked for invalidation? (If you have a system with hundreds of users 
that are logged in that quickly leads to memory problems ...)


If I'm right I think of making the ContinuationsManagerImpl inheritable 
(currently some protected methods and constructors prevent this) so that the 
expiration strategy can be overriden. comments? objections?

-- 
Reinhard Pötz           Independent Consultant, Trainer & (IT)-Coach 

{Software Engineering, Open Source, Web Applications, Apache Cocoon}

                                        web(log): http://www.poetz.cc
--------------------------------------------------------------------


RE: Continuation invalidation strategy

Posted by Rajaneesh <ra...@slk-soft.com>.
How do I unsubscribe to this mailing list?

-----Original Message-----
From: Reinhard Poetz [mailto:reinhard@apache.org]
Sent: Tuesday, May 03, 2005 12:00 PM
To: dev@cocoon.apache.org
Subject: Re: Continuation invalidation strategy


Sylvain Wallez wrote:
> Leszek Gawron wrote:
>
>> Sylvain Wallez wrote:
>>
>>> Reinhard Poetz wrote:
>>
>>
>
> <snip/>
>
>>>> Are there any problems if a parent continuation is removed before
>>>> its children, except that the user can't jump back?
>>>
>>>
>>>
>>> The execution state of a continuation is dependent on it's parent
>>> state. So although we may trash parent webcontinuations (i.e. the
>>> enveloppe used by the continuation manager), we must ensure that a
>>> strong link exists with the parent state.
>>
>>
>> Looks like there is something I am not aware of. What 'state' do you
>> refer to. What would have happened if you just sent parent
>> continuation to null?
>
>
>
> The Rhino scope, which is a rather important piece of information :-)

The Rhino scope is still in the user's session and only deleted when the
session
is invalidated and shouldn't be affected by invalidating a continuation,
AFAIU.
Right?

--
Reinhard Pötz           Independent Consultant, Trainer & (IT)-Coach

{Software Engineering, Open Source, Web Applications, Apache Cocoon}

                                        web(log): http://www.poetz.cc
--------------------------------------------------------------------


Re: Continuation invalidation strategy

Posted by Reinhard Poetz <re...@apache.org>.
Sylvain Wallez wrote:
> Leszek Gawron wrote:
> 
>> Sylvain Wallez wrote:
>>
>>> Reinhard Poetz wrote:
>>
>>
> 
> <snip/>
> 
>>>> Are there any problems if a parent continuation is removed before 
>>>> its children, except that the user can't jump back?
>>>
>>>
>>>
>>> The execution state of a continuation is dependent on it's parent 
>>> state. So although we may trash parent webcontinuations (i.e. the 
>>> enveloppe used by the continuation manager), we must ensure that a 
>>> strong link exists with the parent state.
>>
>>
>> Looks like there is something I am not aware of. What 'state' do you 
>> refer to. What would have happened if you just sent parent 
>> continuation to null?
> 
> 
> 
> The Rhino scope, which is a rather important piece of information :-)

The Rhino scope is still in the user's session and only deleted when the session 
is invalidated and shouldn't be affected by invalidating a continuation, AFAIU. 
Right?

-- 
Reinhard Pötz           Independent Consultant, Trainer & (IT)-Coach 

{Software Engineering, Open Source, Web Applications, Apache Cocoon}

                                        web(log): http://www.poetz.cc
--------------------------------------------------------------------


Re: Continuation invalidation strategy

Posted by Sylvain Wallez <sy...@apache.org>.
Leszek Gawron wrote:

> Sylvain Wallez wrote:
>
>> Reinhard Poetz wrote:
>

<snip/>

>>> Are there any problems if a parent continuation is removed before 
>>> its children, except that the user can't jump back?
>>
>>
>> The execution state of a continuation is dependent on it's parent 
>> state. So although we may trash parent webcontinuations (i.e. the 
>> enveloppe used by the continuation manager), we must ensure that a 
>> strong link exists with the parent state.
>
> Looks like there is something I am not aware of. What 'state' do you 
> refer to. What would have happened if you just sent parent 
> continuation to null?


The Rhino scope, which is a rather important piece of information :-)

Sylvain

-- 
Sylvain Wallez                        Anyware Technologies
http://apache.org/~sylvain            http://anyware-tech.com
Apache Software Foundation Member     Research & Technology Director


Re: Continuation invalidation strategy

Posted by Leszek Gawron <lg...@mobilebox.pl>.
Sylvain Wallez wrote:
> Reinhard Poetz wrote:
> 
>> Leszek Gawron wrote:
>>
>>> Reinhard Poetz wrote:
>>>
>>>>
>>>> Today I've had a look at continuation invalidation. I found 
>>>> following code fragment in the ContinuationManagerImpl:
>>>>
>>>> // REVISIT: This places only the "leaf" nodes in the expirations 
>>>> Sorted Set.
>>>> // do we really want to do this?
>>>> if (parent.getChildren().size() < 2) {
>>>>     expirations.remove(parent);
>>>> }
>>>>
>>>> Is it right that this means that only if a leaf continuation 
>>>> expires, the continuations tree is walked up and parent 
>>>> continuations are checked whether they have expired?
>>>
>>>
>>>
>>> Yes, all children continuation have to expire for the parent to be 
>>> removed.
>>
>>
>>
>> Are there any problems if a parent continuation is removed before its 
>> children, except that the user can't jump back?
> 
> 
> 
> The execution state of a continuation is dependent on it's parent state. 
> So although we may trash parent webcontinuations (i.e. the enveloppe 
> used by the continuation manager), we must ensure that a strong link 
> exists with the parent state.
Looks like there is something I am not aware of. What 'state' do you 
refer to. What would have happened if you just sent parent continuation 
to null?

-- 
Leszek Gawron                                      lgawron@mobilebox.pl
IT Manager                                         MobileBox sp. z o.o.
+48 (61) 855 06 67                              http://www.mobilebox.pl
mobile: +48 (501) 720 812                       fax: +48 (61) 853 29 65

Re: Continuation invalidation strategy

Posted by Torsten Curdt <tc...@apache.org>.
>> But seriously: I tried to explain why you cannot
>> remove the parent continuation :-)
> 
> 
> some experiments showed me that it is possible to remove parent
> continuations in flowscript.

Hm... if the flowscript implementation only stores
modifications this should not be possible :-/

>> One optimization we could add is a maximum
>> continuations per session count. Like a sliding
>> window. So we don't rely on a fix expiration
>> time but additionally expire the oldest ones if
>> we run over a certain amount of continuations
>> per user.
>>
>> That would make the memory consumption a bit more
>> manageable.
> 
> 
> hmmm, I'm not sure if this really helps as only if the *whole*
> continautions tree (= when the last continuation is invalidated)
> referenced objects can be removed by the garbage collector.

Well, ...I fear that's the price you have to pay for
storing only state differences.

Just as a RT: in theory it should be able to mix
the approaches!

Think of it as a an AVI with keyframes. We could
from time to time use continuations that store the
full state. That way we don't have to wait for the
leaf node to expire. If you remove something from
the beginning of an AVI you need to make sure it
still starts with a keyframe. See what I mean?

...or even merging the states of multiple
continuations into one - but that would be hardcore!

cheers
--
Torsten

Re: Continuation invalidation strategy

Posted by Reinhard Poetz <re...@apache.org>.
Torsten Curdt wrote:
>>Looks like you're descibing current functionality :)
> 
> 
> ...well, then everything is ok! :-D
> 
> But seriously: I tried to explain why you cannot
> remove the parent continuation :-)

some experiments showed me that it is possible to remove parent continuations in 
flowscript. But profiling revealed that the benefit is negligible because 
continuaitons are very small objects. As said, the referenced objects are the 
problem as every new continuation tree references new objects  in the case an 
object is stored in a local variable.

I don't have a solution for this as I can't find a general rule when a tree can 
be invalidated, except after some time-out.

> One optimization we could add is a maximum
> continuations per session count. Like a sliding
> window. So we don't rely on a fix expiration
> time but additionally expire the oldest ones if
> we run over a certain amount of continuations
> per user.
> 
> That would make the memory consumption a bit more
> manageable.

hmmm, I'm not sure if this really helps as only if the *whole* continautions 
tree (= when the last continuation is invalidated) referenced objects can be 
removed by the garbage collector.

-- 
Reinhard Pötz           Independent Consultant, Trainer & (IT)-Coach 

{Software Engineering, Open Source, Web Applications, Apache Cocoon}

                                        web(log): http://www.poetz.cc
--------------------------------------------------------------------


Re: Continuation invalidation strategy

Posted by Torsten Curdt <tc...@apache.org>.
> Looks like you're descibing current functionality :)

...well, then everything is ok! :-D

But seriously: I tried to explain why you cannot
remove the parent continuation :-)

One optimization we could add is a maximum
continuations per session count. Like a sliding
window. So we don't rely on a fix expiration
time but additionally expire the oldest ones if
we run over a certain amount of continuations
per user.

That would make the memory consumption a bit more
manageable.

cheers
--
Torsten

Re: Continuation invalidation strategy

Posted by Leszek Gawron <lg...@mobilebox.pl>.
Torsten Curdt wrote:
>                   -o-
> 
> So IMO the invalidation (or better garbage
> collection) algorithm should work like this:
> 
> We have a janitor invalidating continuations
> that has not been used for a certain amount
> of time. They can be invalidated from flow
> directly. The interpreter will refuse to
> resume the flow from them.
> 
> If a leaf continuation is being invalidated
> it means that we need to walk from the leaf
> to the root. If all childs of the current node
> are marked invalidated it may be removed.
> Otherwise we stop the processing.
> 
> ...does that make sense?
Looks like you're descibing current functionality :)

-- 
Leszek Gawron                                      lgawron@mobilebox.pl
IT Manager                                         MobileBox sp. z o.o.
+48 (61) 855 06 67                              http://www.mobilebox.pl
mobile: +48 (501) 720 812                       fax: +48 (61) 853 29 65

Re: Continuation invalidation strategy

Posted by Torsten Curdt <tc...@apache.org>.
>> summing up: we have to keep whole continuation tree, right?

Well... not really we only need to carefully
distinguish between invalidation and removal.
There are two models of continuation trees:

1. differential


                  C1
                  /\
                 /  \
                C2  C3
                /
               /
              C4

 C4 cannot live without C2 and C1
 C2 cannot live without C1
 C3 cannot live without C1

 The state is being constructed

  state = C4 + C2 + C1

 So although we can invalidate C1
 (which means no more child continuations
 may be created) it may still not be removed
 from the tree unless all childs are also
 marked invalid.

2. full


                  C1
                  /\
                 /  \
                C2  C3
                /
               /
              C4

 C1-C4 are self contained

 The state is being constructed

  state = C4

 Invalidation may remove the continuation
 from the tree immediatly. (of course we
 might up with a forrest then)

                  -o-

So IMO the invalidation (or better garbage
collection) algorithm should work like this:

We have a janitor invalidating continuations
that has not been used for a certain amount
of time. They can be invalidated from flow
directly. The interpreter will refuse to
resume the flow from them.

If a leaf continuation is being invalidated
it means that we need to walk from the leaf
to the root. If all childs of the current node
are marked invalidated it may be removed.
Otherwise we stop the processing.

...does that make sense?

cheers
--
Torsten

Re: Continuation invalidation strategy

Posted by Reinhard Poetz <re...@apache.org>.
Leszek Gawron wrote:
> Torsten Curdt wrote:
> 
>>> The execution state of a continuation is dependent on it's parent state.
>>
>>
>>
>> This is true for differential continuation where the
>> lexical information is split across the child axis.
>> (Which is currently not the case for javaflow)
>>
>>
>>> So although we may trash parent webcontinuations (i.e. the enveloppe
>>> used by the continuation manager), we must ensure that a strong link
>>> exists with the parent state.
>>
>>
>>
>> Right - in case only the modifications are kept in a continuation
>> the continuation tree must be kept complete all the time!
>>
>> Invalidation would then need to be a flag that needs to be checked
>> by interpreter or we remove the envelope object and keep only the
>> parent axis of the actual continuations.
> 
> summing up: we have to keep whole continuation tree, right?

No, I don't think so but it doesn't help much if you delete some of the 
continuations of a tree because a continuation object doesn't need much memory.

The problem is all objects that are references from within a continutions tree 
because only when the last! continuation of a tree is invalidated, all 
referenced objects can be removed by the garbage collector. This means that you 
have to be very careful with local! variables.

-- 
Reinhard Pötz           Independent Consultant, Trainer & (IT)-Coach 

{Software Engineering, Open Source, Web Applications, Apache Cocoon}

                                        web(log): http://www.poetz.cc
--------------------------------------------------------------------


Re: Continuation invalidation strategy

Posted by Leszek Gawron <lg...@mobilebox.pl>.
Torsten Curdt wrote:
>>The execution state of a continuation is dependent on it's parent state.
> 
> 
> This is true for differential continuation where the
> lexical information is split across the child axis.
> (Which is currently not the case for javaflow)
> 
> 
>>So although we may trash parent webcontinuations (i.e. the enveloppe
>>used by the continuation manager), we must ensure that a strong link
>>exists with the parent state.
> 
> 
> Right - in case only the modifications are kept in a continuation
> the continuation tree must be kept complete all the time!
> 
> Invalidation would then need to be a flag that needs to be checked
> by interpreter or we remove the envelope object and keep only the
> parent axis of the actual continuations.
summing up: we have to keep whole continuation tree, right?

-- 
Leszek Gawron                                      lgawron@mobilebox.pl
IT Manager                                         MobileBox sp. z o.o.
+48 (61) 855 06 67                              http://www.mobilebox.pl
mobile: +48 (501) 720 812                       fax: +48 (61) 853 29 65

Re: Continuation invalidation strategy

Posted by Torsten Curdt <tc...@apache.org>.
> The execution state of a continuation is dependent on it's parent state.

This is true for differential continuation where the
lexical information is split across the child axis.
(Which is currently not the case for javaflow)

> So although we may trash parent webcontinuations (i.e. the enveloppe
> used by the continuation manager), we must ensure that a strong link
> exists with the parent state.

Right - in case only the modifications are kept in a continuation
the continuation tree must be kept complete all the time!

Invalidation would then need to be a flag that needs to be checked
by interpreter or we remove the envelope object and keep only the
parent axis of the actual continuations.

cheers
--
Torsten


Re: Continuation invalidation strategy

Posted by Sylvain Wallez <sy...@apache.org>.
Reinhard Poetz wrote:

> Leszek Gawron wrote:
>
>> Reinhard Poetz wrote:
>>
>>>
>>> Today I've had a look at continuation invalidation. I found 
>>> following code fragment in the ContinuationManagerImpl:
>>>
>>> // REVISIT: This places only the "leaf" nodes in the expirations 
>>> Sorted Set.
>>> // do we really want to do this?
>>> if (parent.getChildren().size() < 2) {
>>>     expirations.remove(parent);
>>> }
>>>
>>> Is it right that this means that only if a leaf continuation 
>>> expires, the continuations tree is walked up and parent 
>>> continuations are checked whether they have expired?
>>
>>
>> Yes, all children continuation have to expire for the parent to be 
>> removed.
>
>
> Are there any problems if a parent continuation is removed before its 
> children, except that the user can't jump back?


The execution state of a continuation is dependent on it's parent state. 
So although we may trash parent webcontinuations (i.e. the enveloppe 
used by the continuation manager), we must ensure that a strong link 
exists with the parent state.

Sylvain

-- 
Sylvain Wallez                        Anyware Technologies
http://apache.org/~sylvain            http://anyware-tech.com
Apache Software Foundation Member     Research & Technology Director


Re: Continuation invalidation strategy

Posted by Leszek Gawron <lg...@mobilebox.pl>.
Reinhard Poetz wrote:
> Leszek Gawron wrote:
> 
>> Reinhard Poetz wrote:
>>
>>>
>>> Today I've had a look at continuation invalidation. I found following 
>>> code fragment in the ContinuationManagerImpl:
>>>
>>> // REVISIT: This places only the "leaf" nodes in the expirations 
>>> Sorted Set.
>>> // do we really want to do this?
>>> if (parent.getChildren().size() < 2) {
>>>     expirations.remove(parent);
>>> }
>>>
>>> Is it right that this means that only if a leaf continuation expires, 
>>> the continuations tree is walked up and parent continuations are 
>>> checked whether they have expired?
>>
>>
>> Yes, all children continuation have to expire for the parent to be 
>> removed.
> 
> 
> Are there any problems if a parent continuation is removed before its 
> children, except that the user can't jump back?
> 
> 
None that I know of. I'll have a closer look at that.

-- 
Leszek Gawron                                      lgawron@mobilebox.pl
IT Manager                                         MobileBox sp. z o.o.
+48 (61) 855 06 67                              http://www.mobilebox.pl
mobile: +48 (501) 720 812                       fax: +48 (61) 853 29 65

Re: Continuation invalidation strategy

Posted by Reinhard Poetz <re...@apache.org>.
Leszek Gawron wrote:
> Reinhard Poetz wrote:
> 
>>
>> Today I've had a look at continuation invalidation. I found following 
>> code fragment in the ContinuationManagerImpl:
>>
>> // REVISIT: This places only the "leaf" nodes in the expirations 
>> Sorted Set.
>> // do we really want to do this?
>> if (parent.getChildren().size() < 2) {
>>     expirations.remove(parent);
>> }
>>
>> Is it right that this means that only if a leaf continuation expires, 
>> the continuations tree is walked up and parent continuations are 
>> checked whether they have expired?
> 
> Yes, all children continuation have to expire for the parent to be removed.

Are there any problems if a parent continuation is removed before its children, 
except that the user can't jump back?


-- 
Reinhard Pötz           Independent Consultant, Trainer & (IT)-Coach 

{Software Engineering, Open Source, Web Applications, Apache Cocoon}

                                        web(log): http://www.poetz.cc
--------------------------------------------------------------------


Re: Continuation invalidation strategy

Posted by Leszek Gawron <lg...@mobilebox.pl>.
Peter Hunsberger wrote:
> On 5/10/05, Leszek Gawron <lg...@mobilebox.pl> wrote:
> 
>>Peter Hunsberger wrote:
>>
>>>On 5/10/05, Leszek Gawron <lg...@mobilebox.pl> wrote:
>>>
>>>
>>>>Peter Hunsberger wrote:
>>>>
>>>>
>>>>>On 5/10/05, Leszek Gawron <lg...@mobilebox.pl> wrote:
>>>>>
> 
> 
> <snip/>
> 
>>>>>>Still HashMap has no interface other than iterator to get it's contents.
>>>>>>you can either iterate through hashMap.iterator() or
>>>>>>hashMap().keySet().iterator() - no difference, both are synced.
>>>>>>
>>>>>>any ideas?
>>>>>
>>>>>
>>>>>I've seen this problem with the 1.4.2_02 JDK, don't know if it exists
>>>>>elsewhere. The Sun docs claim syncrhonizing on the hashMap should
>>>>>solve the problem but it doesn't. The solution I came up with was to
>>>>>build an array instead of using an iterator, eg:
>>>>>
>>>>>               Object[] list = targetObjects.keySet().toArray();
>>>>>
>>>>>
>>>>>Peter Hunsberger
>>>>
>>>>I doubt it will work:
>>>>
>>>>AbstractCollection.toArray() is in fact the implementation for
>>>>HashMap.KeySet.toArray():
>>>>
>>>>   public Object[] toArray() {
>>>>      Object[] result = new Object[size()];
>>>>      Iterator e = iterator();
>>>>      for (int i=0; e.hasNext(); i++)
>>>>          result[i] = e.next();
>>>>      return result;
>>>>   }
>>>>
>>>>also uses iterator.
>>>
>>>
>>>Building the array and then walking it is different than using the
>>>iterator to walk the key set directly.  The exception comes when you
>>>touch an object in the key set that is accessed through the iterator.
>>>With the array, you're no longer using the iterator at the time you
>>>touch the object.  As a result you don't get the exception (not that
>>>you should have gotten it in the first place).
>>>
>>
>>I see. I'll change the code then.
>>
>>I do not know how memory intensive .toArray() in production environment
>>might be. There may be a lot of continuations to clear on session
>>invalidation.
> 
> 
> Yah,  I'd prefer not to do it this way either.  However, in my case I
> couldn't find any other way to work around the CME. 
Applied with a proper //TODO in code.

-- 
Leszek Gawron                                      lgawron@mobilebox.pl
IT Manager                                         MobileBox sp. z o.o.
+48 (61) 855 06 67                              http://www.mobilebox.pl
mobile: +48 (501) 720 812                       fax: +48 (61) 853 29 65

Re: Continuation invalidation strategy

Posted by Peter Hunsberger <pe...@gmail.com>.
On 5/10/05, Leszek Gawron <lg...@mobilebox.pl> wrote:
> Peter Hunsberger wrote:
> > On 5/10/05, Leszek Gawron <lg...@mobilebox.pl> wrote:
> >
> >>Peter Hunsberger wrote:
> >>
> >>>On 5/10/05, Leszek Gawron <lg...@mobilebox.pl> wrote:
> >>>

<snip/>

> >>>
> >>>>Still HashMap has no interface other than iterator to get it's contents.
> >>>>you can either iterate through hashMap.iterator() or
> >>>>hashMap().keySet().iterator() - no difference, both are synced.
> >>>>
> >>>>any ideas?
> >>>
> >>>
> >>>I've seen this problem with the 1.4.2_02 JDK, don't know if it exists
> >>>elsewhere. The Sun docs claim syncrhonizing on the hashMap should
> >>>solve the problem but it doesn't. The solution I came up with was to
> >>>build an array instead of using an iterator, eg:
> >>>
> >>>                Object[] list = targetObjects.keySet().toArray();
> >>>
> >>>
> >>>Peter Hunsberger
> >>
> >>I doubt it will work:
> >>
> >>AbstractCollection.toArray() is in fact the implementation for
> >>HashMap.KeySet.toArray():
> >>
> >>    public Object[] toArray() {
> >>       Object[] result = new Object[size()];
> >>       Iterator e = iterator();
> >>       for (int i=0; e.hasNext(); i++)
> >>           result[i] = e.next();
> >>       return result;
> >>    }
> >>
> >>also uses iterator.
> >
> >
> > Building the array and then walking it is different than using the
> > iterator to walk the key set directly.  The exception comes when you
> > touch an object in the key set that is accessed through the iterator.
> > With the array, you're no longer using the iterator at the time you
> > touch the object.  As a result you don't get the exception (not that
> > you should have gotten it in the first place).
> >
> I see. I'll change the code then.
> 
> I do not know how memory intensive .toArray() in production environment
> might be. There may be a lot of continuations to clear on session
> invalidation.

Yah,  I'd prefer not to do it this way either.  However, in my case I
couldn't find any other way to work around the CME.  If you've got the
time and the patience you could always try creating a test case for
Sun and reporting the problem :-p...

-- 
Peter Hunsberger

Re: Continuation invalidation strategy

Posted by Leszek Gawron <lg...@mobilebox.pl>.
Peter Hunsberger wrote:
> On 5/10/05, Leszek Gawron <lg...@mobilebox.pl> wrote:
> 
>>Peter Hunsberger wrote:
>>
>>>On 5/10/05, Leszek Gawron <lg...@mobilebox.pl> wrote:
>>>
>>>
>>>>Vadim Gritsenko wrote:
>>>>
>>>>
>>>>>Leszek Gawron wrote:
>>>>>
>>>>>
>>>>>
>>>>>>Vadim Gritsenko wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>>>If you want to tinker with ContinuationsManagerImpl, take a look at:
>>>>>>> http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=111323704203839
>>>>>>
>>>>>>
>>>>>>Strange I missed that post ..
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>>Unsynchronized access to WebContinuationsHolder from
>>>>>>>invalidateContinuations() simultaneously with write access in
>>>>>>>generateContinuation() should reliably cause
>>>>>>>ConcurrentModificationException.
>>>>>>
>>>>>>
>>>>>>I do not quite get the problem. Doesn't it cause
>>>>>>ConcurrentModificationException now?
>>>>>
>>>>>
>>>>>It should - I've not seen it though.
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>>Other thing is how can invalidateContinuations and
>>>>>>generateContinuation be run concurrently. invalidateContinuations is
>>>>>>invoked only for expired sessions - how can new continuation be
>>>>>>generated for that session?
>>>>>
>>>>>
>>>>>Bad example then. Here is better one:
>>>>>
>>>>> invalidateContinuations() gets Iterator on continuationsHolder.holder
>>>>>map.
>>>>> invalidateContinuations() calls _invalidate()
>>>>> _invalidate() calls disposeContinuation()
>>>>> disposeContinuation() modifies continuationsHolder.holder map.
>>>>>
>>>>>After that,
>>>>>
>>>>> invalidateContinuations() calls next() and causes
>>>>>ConcurrentModificationException.
>>>>>
>>>>>Seems to me invalidateContinuations() should have while(!empty) loop
>>>>>instead of iterator.
>>>>
>>>>Still HashMap has no interface other than iterator to get it's contents.
>>>>you can either iterate through hashMap.iterator() or
>>>>hashMap().keySet().iterator() - no difference, both are synced.
>>>>
>>>>any ideas?
>>>
>>>
>>>I've seen this problem with the 1.4.2_02 JDK, don't know if it exists
>>>elsewhere. The Sun docs claim syncrhonizing on the hashMap should
>>>solve the problem but it doesn't. The solution I came up with was to
>>>build an array instead of using an iterator, eg:
>>>
>>>                Object[] list = targetObjects.keySet().toArray();
>>>
>>>
>>>Peter Hunsberger
>>
>>I doubt it will work:
>>
>>AbstractCollection.toArray() is in fact the implementation for
>>HashMap.KeySet.toArray():
>>
>>    public Object[] toArray() {
>>       Object[] result = new Object[size()];
>>       Iterator e = iterator();
>>       for (int i=0; e.hasNext(); i++)
>>           result[i] = e.next();
>>       return result;
>>    }
>>
>>also uses iterator.
> 
> 
> Building the array and then walking it is different than using the
> iterator to walk the key set directly.  The exception comes when you
> touch an object in the key set that is accessed through the iterator. 
> With the array, you're no longer using the iterator at the time you
> touch the object.  As a result you don't get the exception (not that
> you should have gotten it in the first place).
> 
I see. I'll change the code then.

I do not know how memory intensive .toArray() in production environment 
might be. There may be a lot of continuations to clear on session 
invalidation.

-- 
Leszek Gawron                                      lgawron@mobilebox.pl
IT Manager                                         MobileBox sp. z o.o.
+48 (61) 855 06 67                              http://www.mobilebox.pl
mobile: +48 (501) 720 812                       fax: +48 (61) 853 29 65

Re: Continuation invalidation strategy

Posted by Peter Hunsberger <pe...@gmail.com>.
On 5/10/05, Leszek Gawron <lg...@mobilebox.pl> wrote:
> Peter Hunsberger wrote:
> > On 5/10/05, Leszek Gawron <lg...@mobilebox.pl> wrote:
> >
> >>Vadim Gritsenko wrote:
> >>
> >>>Leszek Gawron wrote:
> >>>
> >>>
> >>>>Vadim Gritsenko wrote:
> >>>>
> >>>>
> >>>>>If you want to tinker with ContinuationsManagerImpl, take a look at:
> >>>>>  http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=111323704203839
> >>>>
> >>>>
> >>>>Strange I missed that post ..
> >>>>
> >>>>
> >>>>
> >>>>>Unsynchronized access to WebContinuationsHolder from
> >>>>>invalidateContinuations() simultaneously with write access in
> >>>>>generateContinuation() should reliably cause
> >>>>>ConcurrentModificationException.
> >>>>
> >>>>
> >>>>I do not quite get the problem. Doesn't it cause
> >>>>ConcurrentModificationException now?
> >>>
> >>>
> >>>It should - I've not seen it though.
> >>>
> >>>
> >>>
> >>>>Other thing is how can invalidateContinuations and
> >>>>generateContinuation be run concurrently. invalidateContinuations is
> >>>>invoked only for expired sessions - how can new continuation be
> >>>>generated for that session?
> >>>
> >>>
> >>>Bad example then. Here is better one:
> >>>
> >>>  invalidateContinuations() gets Iterator on continuationsHolder.holder
> >>>map.
> >>>  invalidateContinuations() calls _invalidate()
> >>>  _invalidate() calls disposeContinuation()
> >>>  disposeContinuation() modifies continuationsHolder.holder map.
> >>>
> >>>After that,
> >>>
> >>>  invalidateContinuations() calls next() and causes
> >>>ConcurrentModificationException.
> >>>
> >>>Seems to me invalidateContinuations() should have while(!empty) loop
> >>>instead of iterator.
> >>
> >>Still HashMap has no interface other than iterator to get it's contents.
> >>you can either iterate through hashMap.iterator() or
> >>hashMap().keySet().iterator() - no difference, both are synced.
> >>
> >>any ideas?
> >
> >
> > I've seen this problem with the 1.4.2_02 JDK, don't know if it exists
> > elsewhere. The Sun docs claim syncrhonizing on the hashMap should
> > solve the problem but it doesn't. The solution I came up with was to
> > build an array instead of using an iterator, eg:
> >
> >                 Object[] list = targetObjects.keySet().toArray();
> >
> >
> > Peter Hunsberger
> I doubt it will work:
> 
> AbstractCollection.toArray() is in fact the implementation for
> HashMap.KeySet.toArray():
> 
>     public Object[] toArray() {
>        Object[] result = new Object[size()];
>        Iterator e = iterator();
>        for (int i=0; e.hasNext(); i++)
>            result[i] = e.next();
>        return result;
>     }
> 
> also uses iterator.

Building the array and then walking it is different than using the
iterator to walk the key set directly.  The exception comes when you
touch an object in the key set that is accessed through the iterator. 
With the array, you're no longer using the iterator at the time you
touch the object.  As a result you don't get the exception (not that
you should have gotten it in the first place).

-- 
Peter Hunsberger

Re: Continuation invalidation strategy

Posted by Leszek Gawron <lg...@mobilebox.pl>.
Peter Hunsberger wrote:
> On 5/10/05, Leszek Gawron <lg...@mobilebox.pl> wrote:
> 
>>Vadim Gritsenko wrote:
>>
>>>Leszek Gawron wrote:
>>>
>>>
>>>>Vadim Gritsenko wrote:
>>>>
>>>>
>>>>>If you want to tinker with ContinuationsManagerImpl, take a look at:
>>>>>  http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=111323704203839
>>>>
>>>>
>>>>Strange I missed that post ..
>>>>
>>>>
>>>>
>>>>>Unsynchronized access to WebContinuationsHolder from
>>>>>invalidateContinuations() simultaneously with write access in
>>>>>generateContinuation() should reliably cause
>>>>>ConcurrentModificationException.
>>>>
>>>>
>>>>I do not quite get the problem. Doesn't it cause
>>>>ConcurrentModificationException now?
>>>
>>>
>>>It should - I've not seen it though.
>>>
>>>
>>>
>>>>Other thing is how can invalidateContinuations and
>>>>generateContinuation be run concurrently. invalidateContinuations is
>>>>invoked only for expired sessions - how can new continuation be
>>>>generated for that session?
>>>
>>>
>>>Bad example then. Here is better one:
>>>
>>>  invalidateContinuations() gets Iterator on continuationsHolder.holder
>>>map.
>>>  invalidateContinuations() calls _invalidate()
>>>  _invalidate() calls disposeContinuation()
>>>  disposeContinuation() modifies continuationsHolder.holder map.
>>>
>>>After that,
>>>
>>>  invalidateContinuations() calls next() and causes
>>>ConcurrentModificationException.
>>>
>>>Seems to me invalidateContinuations() should have while(!empty) loop
>>>instead of iterator.
>>
>>Still HashMap has no interface other than iterator to get it's contents.
>>you can either iterate through hashMap.iterator() or
>>hashMap().keySet().iterator() - no difference, both are synced.
>>
>>any ideas?
> 
> 
> I've seen this problem with the 1.4.2_02 JDK, don't know if it exists
> elsewhere. The Sun docs claim syncrhonizing on the hashMap should
> solve the problem but it doesn't. The solution I came up with was to
> build an array instead of using an iterator, eg:
> 
>                 Object[] list = targetObjects.keySet().toArray();
> 
> 
> Peter Hunsberger
I doubt it will work:

AbstractCollection.toArray() is in fact the implementation for 
HashMap.KeySet.toArray():

     public Object[] toArray() {
	Object[] result = new Object[size()];
	Iterator e = iterator();
	for (int i=0; e.hasNext(); i++)
	    result[i] = e.next();
	return result;
     }

also uses iterator.

-- 
Leszek Gawron                                      lgawron@mobilebox.pl
IT Manager                                         MobileBox sp. z o.o.
+48 (61) 855 06 67                              http://www.mobilebox.pl
mobile: +48 (501) 720 812                       fax: +48 (61) 853 29 65

Re: Continuation invalidation strategy

Posted by Peter Hunsberger <pe...@gmail.com>.
On 5/10/05, Leszek Gawron <lg...@mobilebox.pl> wrote:
> Vadim Gritsenko wrote:
> > Leszek Gawron wrote:
> >
> >> Vadim Gritsenko wrote:
> >>
> >>> If you want to tinker with ContinuationsManagerImpl, take a look at:
> >>>   http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=111323704203839
> >>
> >>
> >> Strange I missed that post ..
> >>
> >>
> >>> Unsynchronized access to WebContinuationsHolder from
> >>> invalidateContinuations() simultaneously with write access in
> >>> generateContinuation() should reliably cause
> >>> ConcurrentModificationException.
> >>
> >>
> >> I do not quite get the problem. Doesn't it cause
> >> ConcurrentModificationException now?
> >
> >
> > It should - I've not seen it though.
> >
> >
> >> Other thing is how can invalidateContinuations and
> >> generateContinuation be run concurrently. invalidateContinuations is
> >> invoked only for expired sessions - how can new continuation be
> >> generated for that session?
> >
> >
> > Bad example then. Here is better one:
> >
> >   invalidateContinuations() gets Iterator on continuationsHolder.holder
> > map.
> >   invalidateContinuations() calls _invalidate()
> >   _invalidate() calls disposeContinuation()
> >   disposeContinuation() modifies continuationsHolder.holder map.
> >
> > After that,
> >
> >   invalidateContinuations() calls next() and causes
> > ConcurrentModificationException.
> >
> > Seems to me invalidateContinuations() should have while(!empty) loop
> > instead of iterator.
> Still HashMap has no interface other than iterator to get it's contents.
> you can either iterate through hashMap.iterator() or
> hashMap().keySet().iterator() - no difference, both are synced.
> 
> any ideas?

I've seen this problem with the 1.4.2_02 JDK, don't know if it exists
elsewhere. The Sun docs claim syncrhonizing on the hashMap should
solve the problem but it doesn't. The solution I came up with was to
build an array instead of using an iterator, eg:

                Object[] list = targetObjects.keySet().toArray();


Peter Hunsberger

Re: Continuation invalidation strategy

Posted by Leszek Gawron <lg...@mobilebox.pl>.
Vadim Gritsenko wrote:
> Leszek Gawron wrote:
> 
>> Vadim Gritsenko wrote:
>>
>>> If you want to tinker with ContinuationsManagerImpl, take a look at:
>>>   http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=111323704203839
>>
>>
>> Strange I missed that post ..
>>
>>
>>> Unsynchronized access to WebContinuationsHolder from 
>>> invalidateContinuations() simultaneously with write access in 
>>> generateContinuation() should reliably cause 
>>> ConcurrentModificationException.
>>
>>
>> I do not quite get the problem. Doesn't it cause 
>> ConcurrentModificationException now?
> 
> 
> It should - I've not seen it though.
> 
> 
>> Other thing is how can invalidateContinuations and 
>> generateContinuation be run concurrently. invalidateContinuations is 
>> invoked only for expired sessions - how can new continuation be 
>> generated for that session?
> 
> 
> Bad example then. Here is better one:
> 
>   invalidateContinuations() gets Iterator on continuationsHolder.holder 
> map.
>   invalidateContinuations() calls _invalidate()
>   _invalidate() calls disposeContinuation()
>   disposeContinuation() modifies continuationsHolder.holder map.
> 
> After that,
> 
>   invalidateContinuations() calls next() and causes 
> ConcurrentModificationException.
> 
> Seems to me invalidateContinuations() should have while(!empty) loop 
> instead of iterator.
Still HashMap has no interface other than iterator to get it's contents.
you can either iterate through hashMap.iterator() or 
hashMap().keySet().iterator() - no difference, both are synced.

any ideas?

-- 
Leszek Gawron                                      lgawron@mobilebox.pl
IT Manager                                         MobileBox sp. z o.o.
+48 (61) 855 06 67                              http://www.mobilebox.pl
mobile: +48 (501) 720 812                       fax: +48 (61) 853 29 65

Re: Continuation invalidation strategy

Posted by Vadim Gritsenko <va...@reverycodes.com>.
Leszek Gawron wrote:
> Vadim Gritsenko wrote:
> 
>> If you want to tinker with ContinuationsManagerImpl, take a look at:
>>   http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=111323704203839
> 
> Strange I missed that post ..
> 
>
>> Unsynchronized access to WebContinuationsHolder from 
>> invalidateContinuations() simultaneously with write access in 
>> generateContinuation() should reliably cause 
>> ConcurrentModificationException.
> 
> I do not quite get the problem. Doesn't it cause 
> ConcurrentModificationException now?

It should - I've not seen it though.


> Other thing is how can invalidateContinuations and generateContinuation 
> be run concurrently. invalidateContinuations is invoked only for expired 
> sessions - how can new continuation be generated for that session?

Bad example then. Here is better one:

   invalidateContinuations() gets Iterator on continuationsHolder.holder map.
   invalidateContinuations() calls _invalidate()
   _invalidate() calls disposeContinuation()
   disposeContinuation() modifies continuationsHolder.holder map.

After that,

   invalidateContinuations() calls next() and causes 
ConcurrentModificationException.

Seems to me invalidateContinuations() should have while(!empty) loop instead of 
iterator.

Vadim

Re: Continuation invalidation strategy

Posted by Leszek Gawron <lg...@mobilebox.pl>.
Vadim Gritsenko wrote:
> Leszek Gawron wrote:
> 
>> Reinhard Poetz wrote:
>>
>>> If I'm right I think of making the ContinuationsManagerImpl 
>>> inheritable (currently some protected methods and constructors 
>>> prevent this) so that the expiration strategy can be overriden. 
>>> comments? objections?
> 
> 
> No problem here.
> 
> 
>> we should change the default behaviour I think. I do not see a single 
>> advantage of this approach (apart from quite straightforward 
>> implementation).
> 
> 
> Please leave default implementation intact - if you want, make new 
> additions configurable.
> 
> If you want to tinker with ContinuationsManagerImpl, take a look at:
>   http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=111323704203839
Strange I missed that post ..

> 
> Unsynchronized access to WebContinuationsHolder from 
> invalidateContinuations() simultaneously with write access in 
> generateContinuation() should reliably cause 
> ConcurrentModificationException.

I do not quite get the problem. Doesn't it cause 
ConcurrentModificationException now?

Other thing is how can invalidateContinuations and generateContinuation 
be run concurrently. invalidateContinuations is invoked only for expired 
sessions - how can new continuation be generated for that session?

-- 
Leszek Gawron                                      lgawron@mobilebox.pl
IT Manager                                         MobileBox sp. z o.o.
+48 (61) 855 06 67                              http://www.mobilebox.pl
mobile: +48 (501) 720 812                       fax: +48 (61) 853 29 65

Re: Continuation invalidation strategy

Posted by Vadim Gritsenko <va...@reverycodes.com>.
Leszek Gawron wrote:
> Reinhard Poetz wrote:
> 
>> If I'm right I think of making the ContinuationsManagerImpl 
>> inheritable (currently some protected methods and constructors prevent 
>> this) so that the expiration strategy can be overriden. comments? 
>> objections?

No problem here.


> we should change the default behaviour I think. I do not see a single 
> advantage of this approach (apart from quite straightforward 
> implementation).

Please leave default implementation intact - if you want, make new additions 
configurable.

If you want to tinker with ContinuationsManagerImpl, take a look at:
   http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=111323704203839

Unsynchronized access to WebContinuationsHolder from invalidateContinuations() 
simultaneously with write access in generateContinuation() should reliably cause 
ConcurrentModificationException.

Vadim

Re: Continuation invalidation strategy

Posted by Leszek Gawron <lg...@mobilebox.pl>.
Reinhard Poetz wrote:
> 
> Today I've had a look at continuation invalidation. I found following 
> code fragment in the ContinuationManagerImpl:
> 
> // REVISIT: This places only the "leaf" nodes in the expirations Sorted 
> Set.
> // do we really want to do this?
> if (parent.getChildren().size() < 2) {
>     expirations.remove(parent);
> }
> 
> Is it right that this means that only if a leaf continuation expires, 
> the continuations tree is walked up and parent continuations are checked 
> whether they have expired?
Yes, all children continuation have to expire for the parent to be removed.

> If you have a long expiration time set, does it mean that the whole! 
> tree is never checked for invalidation? (If you have a system with 
> hundreds of users that are logged in that quickly leads to memory 
> problems ...)
And if you design your application in the way that one continuation tree 
is used for the whole session it will be removed from memory one hour 
(by default) after user logs out.

> If I'm right I think of making the ContinuationsManagerImpl inheritable 
> (currently some protected methods and constructors prevent this) so that 
> the expiration strategy can be overriden. comments? objections?
we should change the default behaviour I think. I do not see a single 
advantage of this approach (apart from quite straightforward 
implementation).

Question is: what behaviour do we expect?

The easiest implementation would be:
1. detach all leaves
2. attach leaves as roots
3. invalidate parent continuation
4. optionally: recurse the check for parent's parent.

we may skip 4. but then continuation count might grow faster than they 
are harvested. I am not currently aware how this affects the feature of 
storing continuations in session.

As I am quite fresh on ContinuationsManager details so I may change the 
implementation.

-- 
Leszek Gawron                                      lgawron@mobilebox.pl
IT Manager                                         MobileBox sp. z o.o.
+48 (61) 855 06 67                              http://www.mobilebox.pl
mobile: +48 (501) 720 812                       fax: +48 (61) 853 29 65