Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ISPN-14119 Filter null from evicted entities for distributed queries #10396

Merged
merged 2 commits into from Oct 31, 2022

Conversation

fax4ever
Copy link
Contributor

Copy link
Member

@wburns wburns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the sound of the bug, my guess would be is the entry is in the index, the user runs the query which finds the reference id, and concurrently the entry is removed due to expiration and thus when it tries to read the referenced key it is no longer present.

I would suggest as a guaranteed way to reproduce this issue I would recommend using Mocks.blockingMock replacing the component that does the actual object lookup (if possible). This allows you to fire the query in one thread and wait until it gets to where it is looking up the entries and block the operation. Then you can increment the time service and expire the entry. Then let the query continue and it should face the issue every time you run it without having to do loops or sleeps.

public void test() throws Exception {
cache.put(1, new Game("Ultima IV: Quest of the Avatar", "It is the first in the \"Age of Enlightenment\" trilogy ..."));

Thread.sleep(3000);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use a controlled time service instead, to not have this sleep.
https://github.com/infinispan/infinispan/blob/main/query/src/test/java/org/infinispan/query/continuous/ContinuousQueryTest.java#L30

But please use the non deprecated ControlledTimeService.

}

@Test
public void test() throws Exception {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably have a few tests in here, testing running the query before it expires and after.

.set("name", "Game " + key)
.set("description", "This is the game " + i + "# of a series");

Thread.sleep(40);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not have any sleep calls in our tests, please use the time service as mentioned prior.

.set("name", "Game " + key)
.set("description", "This is the game " + i + "# of a series");

Thread.sleep(40);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not have any sleep calls in our tests, please use the time service as mentioned prior.

@fax4ever
Copy link
Contributor Author

Thanks for review @wburns!

From the sound of the bug, my guess would be is the entry is in the index, the user runs the query which finds the reference id, and concurrently the entry is removed due to expiration and thus when it tries to read the referenced key it is no longer present.

exactly!

I introduced the controlled time service and ran the query before and after the expiration.
I'm going to find if it possible to use the Mocks.blockingMock on entity loading phase.
I was asking myself if we should do that for all tests?

@wburns
Copy link
Member

wburns commented Oct 24, 2022

I introduced the controlled time service and ran the query before and after the expiration. I'm going to find if it possible to use the Mocks.blockingMock on entity loading phase. I was asking myself if we should do that for all tests?

Not sure what you mean by all tests. But I would say if you are using a test that has expiration, you should definitely use a controlled time service, so you don't have the tests take too long and you control the behavior at a much granular level and should be very easily repeatable.

Regarding blockingMock, that is only needed if there is a step in between. Does the test as you have it reproduce the issue every time it is invoked? Or does it fail rarely/intermittently? If so then we will want to inject the blockingMock to be sure to reproduce it easily enough.

@fax4ever
Copy link
Contributor Author

Does the test as you have it reproduce the issue every time it is invoked? Or does it fail rarely/intermittently? If so then we will want to inject the blockingMock to be sure to reproduce it easily enough.

I don't think so. Thus I think we can avoid using the blockingMock IIUC.

Thanks again @wburns
Is there anything else we can improve here?

@wburns
Copy link
Member

wburns commented Oct 28, 2022

Thanks again @wburns Is there anything else we can improve here?

Seems fine, I am just wondering why we don't have the query module test anymore. Seems a bit much with the rest test to test this specific bug. I am fine having both, but can we resurrect the old test you had as well?

@fax4ever
Copy link
Contributor Author

Thank @wburns.
The exception is raised only with the remote queries. In case of an embedded query a list containing some null value is returned. I added a test case for it. I think that it is good to have them both (embedded and remote). Updated the contribution.

@wburns wburns merged commit d39e0db into infinispan:main Oct 31, 2022
@wburns
Copy link
Member

wburns commented Oct 31, 2022

Integrated into main, thanks @fax4ever !

@fax4ever
Copy link
Contributor Author

thank you Will!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants