Hi again Marco,

I though once again on this and maybe having a synchronized Graph
would be different than having a ConcurrentGraph, like
Collections.synchronizedMap() and ConcurrentHashMap, so my suggestion
is keeping the synchronized proxy as they are AND provide Concurrent*
version of actual graphs. I would implement these adapters in a proper
`concurrent` package. Does it make sense to you?

Feel free to fill an issue and assign to yourself if you want to work on it!

best,
-Simo

http://people.apache.org/~simonetripodi/
http://simonetripodi.livejournal.com/
http://twitter.com/simonetripodi
http://www.99soft.org/



On Sat, Mar 3, 2012 at 3:53 PM, Simone Tripodi <simonetrip...@apache.org> wrote:
> Hi Marco,
>
> yes I know it, what doesn't convince me is not the problem, but the
> solution. Have a look at Collections.* source code to see how  this
> problem is fixed in synchronizedMap.
>
> Anyway that confirms that maybe proxies are not the best to handle
> that situation - unless James has a solution (he's our proxy expert,
> just for the record) - and we have to manage read/write locks as James
> suggested - that it would be a nice addition
>
> -Simo
>
> http://people.apache.org/~simonetripodi/
> http://simonetripodi.livejournal.com/
> http://twitter.com/simonetripodi
> http://www.99soft.org/
>
>
>
> On Sat, Mar 3, 2012 at 3:29 PM, Marco Speranza <marcospera...@apache.org> 
> wrote:
>> Ciao
>>
>>
>>> rue, but *all* methods executions (synchronized and not) are
>>> performed inside the handler, contained in the proxy instance anyway.
>>>
>>> So an user cannot use the same "lock"  in order to synchronize a block
>>> like this:
>>
>> Let's give you an example.
>>
>> here is our handler implementation, and imagine that the 'lock' is not 
>> export outside:
>>
>> ===
>> synchronized ( this.lock )
>> {
>>        try
>>        {
>>                return method.invoke( checkedToBeSynchronized, args );
>>        }
>>        catch ( InvocationTargetException e )
>>        {
>>                throw e.getTargetException();
>>        }
>> }
>> ===
>>
>> here is a possible user implementation:
>>
>> - Main class create a synchronized graph instance:
>>
>>    MutableGraph g = CommonsGraph.synchronize( new UndirectMutableGraph.... );
>>
>> - Thread 1 loops over the vertices:
>> synchronized(g) {
>>    for ( BaseLabeledVertex v2 : g.getVertices() )
>>    {
>>        // do somethings
>>    }
>>  }
>>
>> - Thread 2, insert a new vertex:
>> for ( int i = start; i < end; i++ )
>> {
>>        BaseLabeledVertex v = new BaseLabeledVertex( valueOf( i ) );
>>        g.addVertex( v );
>> }
>>
>>
>> in that example thread, probably you would have a 
>> ConcurrentModificationException because:
>>
>> 1) Therad 1 uses a lock 'g' for the Iterator returned by g.getVertices()
>> 2) Thread 2 uses its own lock 'this.lock' stored into Handler class.
>>
>> in this situation our data structure is *not* thread safe.
>>
>> The only way to synchronize the data structure is that:
>>
>> -Thread 2:
>> for ( int i = start; i < end; i++ )
>> {
>>   synchronized(g) {
>>          BaseLabeledVertex v = new BaseLabeledVertex( valueOf( i ) );
>>          g.addVertex( v );
>>  }
>> }
>>
>> but this IMHO  is a wrong way to fix the problem, and moreover with this 
>> workaround we don't need to
>> use CommonGraph.synchronize() method, isn't it?
>>
>>
>>> I have not clear which benefit you want to obtain with that - looks at
>>> Collections#synchronized* methods and see that the separation of
>>> concerns in clear.
>>
>> you are right maybe use an external lock is not useful.
>>
>>
>>> Sure that we can, the only issue we have is that GroboUtils is not in
>>> the central repo, adding the external repository would make not easy
>>> having the component released.
>>
>> unfortunately GroboUtil was the only lib that I found yesterday. Any 
>> suggestions to some other libs?
>>
>> all the best  ;-)
>>
>> --
>> Marco Speranza <marcospera...@apache.org>
>> Google Code: http://code.google.com/u/marco.speranza79/
>>
>> Il giorno 03/mar/2012, alle ore 14:34, Simone Tripodi ha scritto:
>>
>>> Hola Marco,
>>>
>>>> my doubt is this:  opening a synchronized block into handler 
>>>> implementation on 'this',  in my opinion is not enough, because the method 
>>>> "CommonsGraph.synchronize()" returns a instance of the Proxy and not an 
>>>> instance of handler.
>>>
>>> true, but *all* methods executions (synchronized and not) are
>>> performed inside the handler, contained in the proxy instance anyway.
>>>
>>> So an user cannot use the same "lock"  in order to synchronize a block
>>> like this:
>>>
>>> ====
>>> Graph g = CommonsGraph.synchronize(g_);
>>>   ...
>>> synchronized(g) {
>>>     for ( BaseLabeledVertex v2 : g.getVertices() )
>>>     {
>>>         // do somethings
>>>     }
>>> }
>>> ====
>>>
>>> I am not sure we can do much more of what we've already done, for that
>>> situation: the snippet below mixes the *data structure*
>>> synchronization with the business logic performed outside.
>>>
>>>> So my idea is to open synchronized block inside handler implementation 
>>>> using the same Proxy instance that the method 'CommonsGraph.synchronize' 
>>>> will return.
>>>> Furthermore I'd like to modify the API by adding also the possibility for 
>>>> the user to use an your own lock, in that way
>>>>
>>>> CommonsGraph.synchronize( G graph, Object lock )
>>>
>>> I have not clear which benefit you want to obtain with that - looks at
>>> Collections#synchronized* methods and see that the separation of
>>> concerns in clear.
>>>
>>>> Finally only one question. I think that we should add some tests in order 
>>>> to check the correct implementation of our multithrading implementation.
>>>> Do you think that we can use an external library in test scope?
>>>
>>> Sure that we can, the only issue we have is that GroboUtils is not in
>>> the central repo, adding the external repository would make not easy
>>> having the component released.
>>>
>>> best,
>>> -Simo
>>>
>>> http://people.apache.org/~simonetripodi/
>>> http://simonetripodi.livejournal.com/
>>> http://twitter.com/simonetripodi
>>> http://www.99soft.org/
>>>
>>>
>>>
>>> On Sat, Mar 3, 2012 at 2:13 PM, Marco Speranza <marcospera...@apache.org> 
>>> wrote:
>>>> Morning Simo,
>>>>
>>>> my doubt is this:  opening a synchronized block into handler 
>>>> implementation on 'this',  in my opinion is not enough, because the method 
>>>> "CommonsGraph.synchronize()" returns a instance of the Proxy and not an 
>>>> instance of handler.
>>>> So an user cannot use the same "lock"  in order to synchronize a block 
>>>> like this:
>>>>
>>>> ====
>>>> Graph g = CommonsGraph.synchronize(g_);
>>>>    ...
>>>>  synchronized(g) {
>>>>      for ( BaseLabeledVertex v2 : g.getVertices() )
>>>>      {
>>>>          // do somethings
>>>>      }
>>>>  }
>>>> ====
>>>>
>>>> So my idea is to open synchronized block inside handler implementation 
>>>> using the same Proxy instance that the method 'CommonsGraph.synchronize' 
>>>> will return.
>>>> Furthermore I'd like to modify the API by adding also the possibility for 
>>>> the user to use an your own lock, in that way
>>>>
>>>> CommonsGraph.synchronize( G graph, Object lock )
>>>>
>>>> WDYT?
>>>>
>>>> Finally only one question. I think that we should add some tests in order 
>>>> to check the correct implementation of our multithrading implementation.
>>>> Do you think that we can use an external library in test scope?
>>>>
>>>>
>>>> have a nice day
>>>>
>>>>
>>>> --
>>>> Marco Speranza <marcospera...@apache.org>
>>>> Google Code: http://code.google.com/u/marco.speranza79/
>>>>
>>>> Il giorno 03/mar/2012, alle ore 13:50, Simone Tripodi ha scritto:
>>>>
>>>>> Good morning Marco,
>>>>>
>>>>> I had the chance to have a deeper look at your yesterday's night work
>>>>> and think your additions are good improvements - I just wonder if we
>>>>> can replace the lock object with the handler itself, referencing
>>>>> `this` instead.
>>>>>
>>>>> Thoughts?
>>>>>
>>>>> best and have a nice WE,
>>>>> -Simo
>>>>>
>>>>> http://people.apache.org/~simonetripodi/
>>>>> http://simonetripodi.livejournal.com/
>>>>> http://twitter.com/simonetripodi
>>>>> http://www.99soft.org/
>>>>>
>>>>>
>>>>>
>>>>> On Sat, Mar 3, 2012 at 1:56 AM, Simone Tripodi <simonetrip...@apache.org> 
>>>>> wrote:
>>>>>> I saw the commit, please read comments inline.
>>>>>> best,
>>>>>> -Simo
>>>>>>
>>>>>> http://people.apache.org/~simonetripodi/
>>>>>> http://simonetripodi.livejournal.com/
>>>>>> http://twitter.com/simonetripodi
>>>>>> http://www.99soft.org/
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Sat, Mar 3, 2012 at 1:40 AM, Marco Speranza 
>>>>>> <marcospera...@apache.org> wrote:
>>>>>>> Hi I fixed the problem using proxy/handler.
>>>>>>>
>>>>>>> I put also a couple of tests. For do that I insert a test scoped 
>>>>>>> dependency to a library net.sourceforge.groboutils.groboutils-core
>>>>>>>
>>>>>>> Ciao
>>>>>>>
>>>>>>> --
>>>>>>> Marco Speranza <marcospera...@apache.org>
>>>>>>> Google Code: http://code.google.com/u/marco.speranza79/
>>>>>>>
>>>>>>> Il giorno 03/mar/2012, alle ore 01:29, Simone Tripodi ha scritto:
>>>>>>>
>>>>>>>> yes, what I didn't understand is how you would like to manage the
>>>>>>>> iterators issue
>>>>>>>>
>>>>>>>> sorry for the brevity but tonight I am getting crazy with at least 3
>>>>>>>> other projects :D
>>>>>>>>
>>>>>>>> -Simo
>>>>>>>>
>>>>>>>> http://people.apache.org/~simonetripodi/
>>>>>>>> http://simonetripodi.livejournal.com/
>>>>>>>> http://twitter.com/simonetripodi
>>>>>>>> http://www.99soft.org/
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On Sat, Mar 3, 2012 at 1:16 AM, Marco Speranza 
>>>>>>>> <marcospera...@apache.org> wrote:
>>>>>>>>> I think that we have to use the same patter of java Collections: a 
>>>>>>>>> wrapper of Graph/MutableGraph that use a synchronize block.
>>>>>>>>>
>>>>>>>>> WDYT?
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Marco Speranza <marcospera...@apache.org>
>>>>>>>>> Google Code: http://code.google.com/u/marco.speranza79/
>>>>>>>>>
>>>>>>>>> Il giorno 03/mar/2012, alle ore 01:10, Simone Tripodi ha scritto:
>>>>>>>>>
>>>>>>>>>> OK now sounds better, thanks - how would you intend to fix it?
>>>>>>>>>> TIA,
>>>>>>>>>> -Simo
>>>>>>>>>>
>>>>>>>>>> http://people.apache.org/~simonetripodi/
>>>>>>>>>> http://simonetripodi.livejournal.com/
>>>>>>>>>> http://twitter.com/simonetripodi
>>>>>>>>>> http://www.99soft.org/
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Sat, Mar 3, 2012 at 1:01 AM, Marco Speranza 
>>>>>>>>>> <marcospera...@apache.org> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>> furthermore there is another problem: with handler is not 
>>>>>>>>>>>>> possible to use correctly synchronization block like this
>>>>>>>>>>>>>
>>>>>>>>>>>>> ====
>>>>>>>>>>>>> Graph g = CommonsGraph.synchronize(g_);
>>>>>>>>>>>>>     ...
>>>>>>>>>>>>>  synchronized(g) {
>>>>>>>>>>>>>       for ( BaseLabeledVertex v2 : g.getVertices() )
>>>>>>>>>>>>>       {
>>>>>>>>>>>>>           // do somethings
>>>>>>>>>>>>>       }
>>>>>>>>>>>>>  }
>>>>>>>>>>>>> ====
>>>>>>>>>>>>
>>>>>>>>>>>> sorry I don't understand what you meant/intend to do
>>>>>>>>>>>
>>>>>>>>>>> I'm trying to explain better. the method getVertices return an 
>>>>>>>>>>> Iterator. In a multi-thread environment you have to ensure that 
>>>>>>>>>>> during the 'for' execution the [graph] data structure remains  
>>>>>>>>>>> consistent.
>>>>>>>>>>> Also for java collection is the same 
>>>>>>>>>>> [http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#synchronizedCollection(java.util.Collection)]
>>>>>>>>>>>
>>>>>>>>>>> So if we use a proxy/handler there is no way to "export" the 
>>>>>>>>>>> mutex/lock variable used into handler class.
>>>>>>>>>>>
>>>>>>>>>>> In  our CommonsGraph the variable this.lock is private and is non 
>>>>>>>>>>> possible to export out of the method, so the user can not utilize 
>>>>>>>>>>> the lock to synchronize his block.
>>>>>>>>>>>
>>>>>>>>>>> ===
>>>>>>>>>>>        public Object invoke( Object proxy, Method method, Object[] 
>>>>>>>>>>> args )
>>>>>>>>>>>            throws Throwable
>>>>>>>>>>>        {
>>>>>>>>>>>            if ( synchronizedMethods.contains( method ) )
>>>>>>>>>>>            {
>>>>>>>>>>>                try
>>>>>>>>>>>                {
>>>>>>>>>>>                    synchronized ( this.lock )
>>>>>>>>>>>                    {
>>>>>>>>>>>                        return method.invoke( synchronizedMethods, 
>>>>>>>>>>> args );
>>>>>>>>>>>                    }
>>>>>>>>>>>                }
>>>>>>>>>>>                catch ( InvocationTargetException e )
>>>>>>>>>>>                {
>>>>>>>>>>>                    throw e.getTargetException();
>>>>>>>>>>>                }
>>>>>>>>>>>            }
>>>>>>>>>>>            return method.invoke( synchronizedMethods, args );
>>>>>>>>>>>        }
>>>>>>>>>>> ===
>>>>>>>>>>>
>>>>>>>>>>> ciao
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> Marco Speranza <marcospera...@apache.org>
>>>>>>>>>>> Google Code: http://code.google.com/u/marco.speranza79/
>>>>>>>>>>>
>>>>>>>>>>> Il giorno 03/mar/2012, alle ore 00:45, Simone Tripodi ha scritto:
>>>>>>>>>>>
>>>>>>>>>>>>> furthermore there is another problem: with handler is not 
>>>>>>>>>>>>> possible to use correctly synchronization block like this
>>>>>>>>>>>>>
>>>>>>>>>>>>> ====
>>>>>>>>>>>>> Graph g = CommonsGraph.synchronize(g_);
>>>>>>>>>>>>>     ...
>>>>>>>>>>>>>  synchronized(g) {
>>>>>>>>>>>>>       for ( BaseLabeledVertex v2 : g.getVertices() )
>>>>>>>>>>>>>       {
>>>>>>>>>>>>>           // do somethings
>>>>>>>>>>>>>       }
>>>>>>>>>>>>>  }
>>>>>>>>>>>>> ====
>>>>>>>>>>>>
>>>>>>>>>>>> sorry I don't understand what you meant/intend to do
>>>>>>>>>>>>
>>>>>>>>>>>>> I really think that a synchronized wrapper it's the best solution.
>>>>>>>>>>>>>
>>>>>>>>>>>>> WDYT?
>>>>>>>>>>>>
>>>>>>>>>>>> they sucks because we have to keep them updated while , but if 
>>>>>>>>>>>> there
>>>>>>>>>>>> are not alternatives...
>>>>>>>>>>>> -Simo
>>>>>>>>>>>>
>>>>>>>>>>>> http://people.apache.org/~simonetripodi/
>>>>>>>>>>>> http://simonetripodi.livejournal.com/
>>>>>>>>>>>> http://twitter.com/simonetripodi
>>>>>>>>>>>> http://www.99soft.org/
>>>>>>>>>>>>
>>>>>>>>>>>> ---------------------------------------------------------------------
>>>>>>>>>>>> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
>>>>>>>>>>>> For additional commands, e-mail: dev-h...@commons.apache.org
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> ---------------------------------------------------------------------
>>>>>>>>>>> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
>>>>>>>>>>> For additional commands, e-mail: dev-h...@commons.apache.org
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> ---------------------------------------------------------------------
>>>>>>>>>> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
>>>>>>>>>> For additional commands, e-mail: dev-h...@commons.apache.org
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> ---------------------------------------------------------------------
>>>>>>>>> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
>>>>>>>>> For additional commands, e-mail: dev-h...@commons.apache.org
>>>>>>>>>
>>>>>>>>
>>>>>>>> ---------------------------------------------------------------------
>>>>>>>> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
>>>>>>>> For additional commands, e-mail: dev-h...@commons.apache.org
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> ---------------------------------------------------------------------
>>>>>>> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
>>>>>>> For additional commands, e-mail: dev-h...@commons.apache.org
>>>>>>>
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
>>>>> For additional commands, e-mail: dev-h...@commons.apache.org
>>>>>
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
>>>> For additional commands, e-mail: dev-h...@commons.apache.org
>>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
>>> For additional commands, e-mail: dev-h...@commons.apache.org
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
>> For additional commands, e-mail: dev-h...@commons.apache.org
>>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org

Reply via email to