IgniteCache.invoke deadlock example

classic Classic list List threaded Threaded
4 messages Options
emorakis emorakis
Reply | Threaded
Open this post in threaded view
|

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

aealexsandrov aealexsandrov
Reply | Threaded
Open this post in threaded view
|

Re: IgniteCache.invoke deadlock example

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

emorakis emorakis
Reply | Threaded
Open this post in threaded view
|

Re: IgniteCache.invoke deadlock example

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>entryObject... 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>entryObject... 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 <[hidden email]> 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

ilya.kasnacheev ilya.kasnacheev
Reply | Threaded
Open this post in threaded view
|

Re: IgniteCache.invoke deadlock example

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 <[hidden email]>:
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>entryObject... 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>entryObject... 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 <[hidden email]> 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