You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ignite.apache.org by Anton Kalashnikov <ka...@yandex.ru> on 2018/02/28 15:15:33 UTC

Race on IgniteAtomicLong#close

Hello Igniters.

During investigation flaky test IgniteClientDataStructuresTest.testAtomicLong. I found a issue and now I need your help because I don't have enough knowledge about IgniteAtomicLong.
I created the task for it - https://issues.apache.org/jira/browse/IGNITE-7845. And also I duplicate information below:

Given:

IgniteAtomicLong was created e.g. atomicLong = ignite.atomicLong("long1", 1L, true)

When:

IgniteAtomicLong was closed e.g. atomicLong.close()

Then:

If you try to get this value again - sometimes you will get null IgniteAtomicLong value and sometimes you will get not null IgniteAtomicLong value e.g. ignite.atomicLong("long1", 1L, false) sometimes null, sometimes not null

But if we will get not null value IgniteAtomicLong and we will call method "get" on it, we will have one of two exceptions IllegalStateException("Sequence was removed from cache: " + name) if it already marked as deleted, and IgniteException("Failed to find atomic long: " + name) if it sill no marked as deleted but already deleted from cache.

Expected:

IgniteAtomicLong value always should be null(or not?)

Why it's happend:

When we close IgniteAtomicLong we removing value from cache in transaction but removing from internal storage(dsMap) happen asynchroniously in DataStructuresEntryListener for all nodes include local node. And when we try get value after close we still sometimes able to get IgniteAtomicLong from internal local storage.


Solution(In my opinion):

I guess in common case we don't  need call Ignite#atomicLong  every time when we need value, but we should use IgniteAtomicLong object received after first call. And if it is true, we can remove receiving IgniteAtomicLong from local storage(dsMap) - this changes will fix problem

-- 
Best regards,
Anton Kalashnikov


Re: Race on IgniteAtomicLong#close

Posted by Anton Kalashnikov <ka...@yandex.ru>.
Thank you, Anton.

If it is expected behaviour I will fix test but anyway in my opinion this behaviour is not straight, I mean when you do same action and you getting differents result it is not good. At least, exception of missing value should be one. I don't have solution right now but I will think about it. But if you have any thoughts about it, please, share them.

Nevertheless my target was understand the problem and it was achived. Now I can fix the test.

-- 
Best regards,
Anton Kalashnikov


01.03.2018, 00:33, "Anton Vinogradov" <av...@apache.org>:
> Anton,
>
> dsMap allows you to share any datastructure between local node's threads
> without requesting it using retryTopologySafe method (which is heavy).
>
> T dataStructure = cast(dsMap.get(key), cls);
>
> if (dataStructure != null)
>     return dataStructure;
>
> return retryTopologySafe( ...
>
> I see no problems at current behavour since you'll never gain obsolete
> value.
> You'll gain null once continuous query update dsMap.
>
> Looks like problem with test, not with atomicLong implementation.
> After datastructure closing you should be ready to see non null value some
> time, but any get method on this value should cause exception.
>
> 2018-02-28 18:15 GMT+03:00 Anton Kalashnikov <ka...@yandex.ru>:
>
>>  Hello Igniters.
>>
>>  During investigation flaky test IgniteClientDataStructuresTest.testAtomicLong.
>>  I found a issue and now I need your help because I don't have enough
>>  knowledge about IgniteAtomicLong.
>>  I created the task for it - https://issues.apache.org/
>>  jira/browse/IGNITE-7845. And also I duplicate information below:
>>
>>  Given:
>>
>>  IgniteAtomicLong was created e.g. atomicLong = ignite.atomicLong("long1",
>>  1L, true)
>>
>>  When:
>>
>>  IgniteAtomicLong was closed e.g. atomicLong.close()
>>
>>  Then:
>>
>>  If you try to get this value again - sometimes you will get null
>>  IgniteAtomicLong value and sometimes you will get not null IgniteAtomicLong
>>  value e.g. ignite.atomicLong("long1", 1L, false) sometimes null, sometimes
>>  not null
>>
>>  But if we will get not null value IgniteAtomicLong and we will call method
>>  "get" on it, we will have one of two exceptions IllegalStateException("Sequence
>>  was removed from cache: " + name) if it already marked as deleted, and
>>  IgniteException("Failed to find atomic long: " + name) if it sill no marked
>>  as deleted but already deleted from cache.
>>
>>  Expected:
>>
>>  IgniteAtomicLong value always should be null(or not?)
>>
>>  Why it's happend:
>>
>>  When we close IgniteAtomicLong we removing value from cache in transaction
>>  but removing from internal storage(dsMap) happen asynchroniously in
>>  DataStructuresEntryListener for all nodes include local node. And when we
>>  try get value after close we still sometimes able to get IgniteAtomicLong
>>  from internal local storage.
>>
>>  Solution(In my opinion):
>>
>>  I guess in common case we don't need call Ignite#atomicLong every time
>>  when we need value, but we should use IgniteAtomicLong object received
>>  after first call. And if it is true, we can remove receiving
>>  IgniteAtomicLong from local storage(dsMap) - this changes will fix problem
>>
>>  --
>>  Best regards,
>>  Anton Kalashnikov

Re: Race on IgniteAtomicLong#close

Posted by Anton Vinogradov <av...@apache.org>.
Anton,

dsMap allows you to share any datastructure between local node's threads
without requesting it using retryTopologySafe method (which is heavy).

T dataStructure = cast(dsMap.get(key), cls);

if (dataStructure != null)
    return dataStructure;

return retryTopologySafe( ...

I see no problems at current behavour since you'll never gain obsolete
value.
You'll gain null once continuous query update dsMap.

Looks like problem with test, not with atomicLong implementation.
After datastructure closing you should be ready to see non null value some
time, but any get method on this value should cause exception.

2018-02-28 18:15 GMT+03:00 Anton Kalashnikov <ka...@yandex.ru>:

> Hello Igniters.
>
> During investigation flaky test IgniteClientDataStructuresTest.testAtomicLong.
> I found a issue and now I need your help because I don't have enough
> knowledge about IgniteAtomicLong.
> I created the task for it - https://issues.apache.org/
> jira/browse/IGNITE-7845. And also I duplicate information below:
>
> Given:
>
> IgniteAtomicLong was created e.g. atomicLong = ignite.atomicLong("long1",
> 1L, true)
>
> When:
>
> IgniteAtomicLong was closed e.g. atomicLong.close()
>
> Then:
>
> If you try to get this value again - sometimes you will get null
> IgniteAtomicLong value and sometimes you will get not null IgniteAtomicLong
> value e.g. ignite.atomicLong("long1", 1L, false) sometimes null, sometimes
> not null
>
> But if we will get not null value IgniteAtomicLong and we will call method
> "get" on it, we will have one of two exceptions IllegalStateException("Sequence
> was removed from cache: " + name) if it already marked as deleted, and
> IgniteException("Failed to find atomic long: " + name) if it sill no marked
> as deleted but already deleted from cache.
>
> Expected:
>
> IgniteAtomicLong value always should be null(or not?)
>
> Why it's happend:
>
> When we close IgniteAtomicLong we removing value from cache in transaction
> but removing from internal storage(dsMap) happen asynchroniously in
> DataStructuresEntryListener for all nodes include local node. And when we
> try get value after close we still sometimes able to get IgniteAtomicLong
> from internal local storage.
>
>
> Solution(In my opinion):
>
> I guess in common case we don't  need call Ignite#atomicLong  every time
> when we need value, but we should use IgniteAtomicLong object received
> after first call. And if it is true, we can remove receiving
> IgniteAtomicLong from local storage(dsMap) - this changes will fix problem
>
> --
> Best regards,
> Anton Kalashnikov
>
>