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

Sleep in MultipleThreadsForceRefresh #55231

Merged
merged 2 commits into from
Apr 22, 2024
Merged

Sleep in MultipleThreadsForceRefresh #55231

merged 2 commits into from
Apr 22, 2024

Conversation

amcasey
Copy link
Member

@amcasey amcasey commented Apr 19, 2024

...to increase the likelihood of two threads racing to enter the critical section.

For #55227

...to increase the likelihood of two threads racing to enter the critical section.

Fixes dotnet#55227
@amcasey
Copy link
Member Author

amcasey commented Apr 19, 2024

FYI @BrennanConroy, the person most likely to be unhappy about the sleep. 😆

Copy link
Member

@BrennanConroy BrennanConroy left a comment

Choose a reason for hiding this comment

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

Not the biggest fan, but the only real way to make this test deterministic is to modify product code to make it more testable. We can see if this makes the test reliable enough (4 9's?) and re-think the code if it fails more often.

@amcasey
Copy link
Member Author

amcasey commented Apr 19, 2024

I'm not taking the blame for that e2e failure. 😝

@amcasey
Copy link
Member Author

amcasey commented Apr 19, 2024

I plan to azp run at least twice before merging.

@amcasey
Copy link
Member Author

amcasey commented Apr 22, 2024

/azp run

Copy link

Azure Pipelines successfully started running 3 pipeline(s).

@halter73
Copy link
Member

Any test that relies on a Thread.Sleep is immediately suspect. It's usually better to use something like a ManualResetSlim to unblock the thread only after you've confirmed the race you're trying to induce has occurred. That way you can make the max wait longer than 200 ms if need be but finish the test a lot faster than 200 ms in the majority of cases. You never know when other work might get preempted an outwait the Thread.Sleep no matter how long you make it.

I understand the urgency though. I've seen this test start failing pretty consistently on unrelated PRs like #55209. Can we combine this PR with #55228 which retries it and quarantine the test?

@amcasey
Copy link
Member Author

amcasey commented Apr 22, 2024

Any test that relies on a Thread.Sleep is immediately suspect. It's usually better to use something like a ManualResetSlim to unblock the thread only after you've confirmed the race you're trying to induce has occurred

Agreed, but neither @BrennanConroy nor I could figure out a way to do that without adding a dedicated test hook.

I don't think retrying makes sense once the test is quarantined, but I agree that quarantining should be part of this PR.

@halter73
Copy link
Member

Where would the dedicated test hook have to go?

@amcasey
Copy link
Member Author

amcasey commented Apr 22, 2024

Where would the dedicated test hook have to go?

Inside this lock.

@amcasey amcasey enabled auto-merge (squash) April 22, 2024 18:09
@halter73
Copy link
Member

Given that this is testing forceRefresh: true case, I'm not sure how important it is to test that in extremely rare cases, if a parallel thread is executing at exactly the same time (with the same DateTimeOffset.UtcNow.Ticks), you might get a cached value anyway. As long as the results are what we expect, it'd probably be fine if the parallel threads always make their own call to ICacheableKeyRingProvider.GetCacheableKeyRing(DateTimeOffset).

If this really is important, I think we should add a test hook, but otherwise I'd just delete the Times.AtMost(taskCount - 1) verification part of the test.

@amcasey
Copy link
Member Author

amcasey commented Apr 22, 2024

Given that this is testing forceRefresh: true case, I'm not sure how important it is to test that in extremely rare cases, if a parallel thread is executing at exactly the same time (with the same DateTimeOffset.UtcNow.Ticks), you might get a cached value anyway. As long as the results are what we expect, it'd probably be fine if the parallel threads always make their own call to ICacheableKeyRingProvider.GetCacheableKeyRing(DateTimeOffset).

I agree that the test adds little value and would be happy to delete it.

If this really is important, I think we should add a test hook, but otherwise I'd just delete the Times.AtMost(taskCount - 1) verification part of the test.

The rest of the functionality is covered by other tests.

Edit: #55290

@amcasey amcasey merged commit 22bf0d0 into dotnet:main Apr 22, 2024
26 checks passed
@dotnet-policy-service dotnet-policy-service bot added this to the 9.0-preview4 milestone Apr 22, 2024
@amcasey amcasey deleted the gh55227 branch April 22, 2024 20:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-dataprotection Includes: DataProtection
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants