You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@ignite.apache.org by Evangelos Morakis <em...@gmail.com> on 2019/09/07 15:31:33 UTC

IgniteCache.invoke deadlock example

Dear igniters, 

I would like to elicit your expert 
advice in regards to how ignite differentiates 
on the use of a call to: 1)IgniteCompute.affinityRun(...)
and 
2)IgniteCache.invoke(...)

 as far as dead locks are concerned. According to the documentation the main difference is that method 2 above, operates within a lock. Specifically the doc quotes:
“EntryProcessors are executed atomically within a lock on the given cache key.”
Now it even comes with a warning that is meant to show how it is supposed to be used (or conversely NOT to be used):
“You should not access other keys from within the EntryProcessor logic as it may cause a deadlock.”
But this phrase “other keys” to what kind of keys does it refer to?  The remaining keys of the passed in cache?  For e.g. :
 Assume a persons cache...
Cache Person<String,Person> personsCache=...

personsCache.invoke("personKey", new EntryProcessor<String, Person, Void>() {

@Override public Object process(MutableEntry<String, Person> entry, Object... args) { 

Person person= entry.getValue(); entry.setValue(person.setOccupation(“foo”));
return null;
 } 
 });
In other words can someone provide an example based on the above dummy code  that would make invoke deadlock so that I could get an understanding of what the documentation refers to?

Thanks 

Evangelos Morakis


Re: IgniteCache.invoke deadlock example

Posted by Ilya Kasnacheev <il...@gmail.com>.
Hello!

Yes!

You should always lock keys in the same order (they are usually sorted for
that matter).

Regards,
-- 
Ilya Kasnacheev


вт, 10 сент. 2019 г. в 22:39, Evangelos Morakis <em...@gmail.com>:

> Hi Andrei,
> Thanks a lot for your reply. Relatively to the dummy code I provided I
> take it you mean the following ?
>
> Cache Person<String,Person> personsCache=...
>
> *THREAD 1*
>
> personsCache.invoke("*personKey1*", new EntryProcessor<String, Person, Void>() {
>
>
> @Override public Object process(MutableEntry<String, Person>entry, Object... args) {
>
>
> Person person= entry.getValue();
>
> entry.setValue(person.setOccupation(“foo”));
>
>
> *Some additional calculation here involving key* *personKey2 **<- - -some other key?*
>
>
> return null;
>
>  }
>
>  });
>
>
> *THREAD 2*
>
> personsCache.invoke("*personKey2*", new EntryProcessor<String, Person, Void>() {
>
>
> @Override public Object process(MutableEntry<String, Person>entry, Object... args) {
>
>
> Person person= entry.getValue();
>
> entry.setValue(person.setOccupation(“foo”));
>
>
> *Some additional calculation here involving key* *personKey1 <- - -some other key?*
>
>
> return null;
>
>  }
>
>  });
>
>
>  The 2 threads WILL deadlock in that situation.
>
> So, could those  keys of the person cache (for example) that I have marked
> above, be the ones that are designated in the documentation (and hence in
> your explanation as well) as “other keys” ?
>
> Thanks
> Evangelos Morakis
>
>
> On 9 Sep 2019, at 20:40, Andrei Aleksandrov <ae...@gmail.com>
> wrote:
>
> Hello,
>
> When you use the entry processor then you lock only provided key. So when
> you tries to work with *other keys* (different from provided one) that
> are being processed somewhere in other threads then deadlock is possible
> because other thread can take lock on these *other keys* and wait for
> provided one. Otherwise, entry processor will wait for these *other keys*.
> It's typical deadlock.
>
> Sorry, I will not provide the example but hopes that my explanation is
> clear.
>
> BR,
> Andrei
> 9/7/2019 6:31 PM, Evangelos Morakis пишет:
>
>
> Dear igniters,
>
> I would like to elicit your expert
> advice in regards to how ignite differentiates
> on the use of a call to: 1)IgniteCompute.affinityRun(...)
> and
> 2)IgniteCache.invoke(...)
>
>  as far as dead locks are concerned. According to the documentation the
> main difference is that method 2 above, operates within a lock.
> Specifically the doc quotes:
> “EntryProcessors are executed atomically within a lock on the given cache
> key.”
> Now it even comes with a warning that is meant to show how it is supposed
> to be used (or conversely NOT to be used):
> “You should not access *other keys* from within the EntryProcessor logic
> as it may cause a deadlock.”
> But this phrase “*other keys*” to what kind of keys does it refer to?
> The remaining keys of the passed in cache?  For e.g. :
>  Assume a persons cache...
> Cache Person<String,Person> personsCache=...
>
> personsCache.invoke("personKey", new EntryProcessor<String, Person, Void>() {
>
>  @Override
>     public Object process(MutableEntry<String, Person> entry, Object... args) {
>
>  Person person= entry.getValue();
>
>       entry.setValue(person.setOccupation(“foo”));
>
> return null;
>
>  }
>
>  });
>
> In other words can someone provide an example based on the above dummy
> code  that would make invoke deadlock so that I could get an understanding
> of what the documentation refers to?
>
> Thanks
>
> Evangelos Morakis
>
>

Re: IgniteCache.invoke deadlock example

Posted by Evangelos Morakis <em...@gmail.com>.
Hi Andrei, 
Thanks a lot for your reply. Relatively to the dummy code I provided I take it you mean the following ? 

Cache Person<String,Person> personsCache=...
 
THREAD 1
personsCache.invoke("personKey1", new EntryProcessor<String, Person, Void>() {

@Override public Object process(MutableEntry<String, Person>entry, Object... args) { 

Person person= entry.getValue();
entry.setValue(person.setOccupation(“foo”));

Some additional calculation here involving key personKey2 <- - -some other key?

return null;
 } 
 });
 
THREAD 2
personsCache.invoke("personKey2", new EntryProcessor<String, Person, Void>() {

@Override public Object process(MutableEntry<String, Person>entry, Object... args) { 

Person person= entry.getValue();
entry.setValue(person.setOccupation(“foo”));

Some additional calculation here involving key personKey1 <- - -some other key?

return null;
 } 
 });

 The 2 threads WILL deadlock in that situation. 

So, could those  keys of the person cache (for example) that I have marked above, be the ones that are designated in the documentation (and hence in your explanation as well) as “other keys” ? 

Thanks
Evangelos Morakis


> On 9 Sep 2019, at 20:40, Andrei Aleksandrov <ae...@gmail.com> wrote:
> 
> Hello,
> 
> When you use the entry processor then you lock only provided key. So when you tries to work with other keys (different from provided one) that are being processed somewhere in other threads then deadlock is possible because other thread can take lock on these other keys and wait for provided one. Otherwise, entry processor will wait for these other keys. It's typical deadlock.
> 
> Sorry, I will not provide the example but hopes that my explanation is clear.
> 
> BR,
> Andrei
> 
> 9/7/2019 6:31 PM, Evangelos Morakis пишет:
>> 
>> Dear igniters, 
>> 
>> I would like to elicit your expert 
>> advice in regards to how ignite differentiates 
>> on the use of a call to: 1)IgniteCompute.affinityRun(...)
>> and 
>> 2)IgniteCache.invoke(...)
>> 
>>  as far as dead locks are concerned. According to the documentation the main difference is that method 2 above, operates within a lock. Specifically the doc quotes:
>> “EntryProcessors are executed atomically within a lock on the given cache key.”
>> Now it even comes with a warning that is meant to show how it is supposed to be used (or conversely NOT to be used):
>> “You should not access other keys from within the EntryProcessor logic as it may cause a deadlock.”
>> But this phrase “other keys” to what kind of keys does it refer to?  The remaining keys of the passed in cache?  For e.g. :
>>  Assume a persons cache...
>> Cache Person<String,Person> personsCache=...
>> 
>> personsCache.invoke("personKey", new EntryProcessor<String, Person, Void>() {
>> @Override public Object process(MutableEntry<String, Person> entry, Object... args) { 
>> Person person= entry.getValue(); entry.setValue(person.setOccupation(“foo”));
>> return null;
>>  } 
>>  });
>> In other words can someone provide an example based on the above dummy code  that would make invoke deadlock so that I could get an understanding of what the documentation refers to?
>> 
>> Thanks 
>> 
>> Evangelos Morakis
>> 

Re: IgniteCache.invoke deadlock example

Posted by Andrei Aleksandrov <ae...@gmail.com>.
Hello,

When you use the entry processor then you lock only provided key. So 
when you tries to work with *other keys* (different from provided one) 
that are being processed somewhere in other threads then deadlock is 
possible because other thread can take lock on these *other keys* and 
wait for provided one. Otherwise, entry processor will wait for these 
*other keys*. It's typical deadlock.

Sorry, I will not provide the example but hopes that my explanation is 
clear.

BR,
Andrei

9/7/2019 6:31 PM, Evangelos Morakis пишет:
>
> Dear igniters,
>
> I would like to elicit your expert
> advice in regards to how ignite differentiates
> on the use of a call to: 1)|IgniteCompute.affinityRun(...)|
> and
> |2)IgniteCache.invoke(...)|
> |
> |
> | as far as dead locks are concerned. According to the documentation 
> the main difference is that method 2 above, operates within a lock. 
> Specifically the doc quotes:|
> |“EntryProcessors| are executed atomically within a lock on the given 
> cache key.”
> Now it even comes with a warning that is meant to show how it is 
> supposed to be used (or conversely NOT to be used):
> “You should not access *other keys* from within the 
> |EntryProcessor| logic as it may cause a deadlock.”
> But this phrase “*other keys*” to what kind of keys does it refer to? 
>  The remaining keys of the passed in cache?  For e.g. :
>  Assume a persons cache...
> Cache Person<String,Person> personsCache=...
>
> |personsCache.invoke("personKey", new EntryProcessor<String, Person, 
> Void>() {|
> ||
> |@Override public Object process(MutableEntry<String, Person> entry, 
> Object... args) { |
> ||
> |Person person= entry.getValue(); 
> entry.setValue(person.setOccupation(“foo”));|
> |return null;|
> | } |
> | });|
> In other words can someone provide an example based on the above dummy 
> code  that would make invoke deadlock so that I could get an 
> understanding of what the documentation refers to?
>
> Thanks
>
> Evangelos Morakis
>