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

Switched to a more performant locking library #14

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

MarkCiliaVincenti
Copy link

Disclaimer: I am the author of the new library.

Public benchmarks running on GitHub show AsyncNonKeyedLocker to be considerably more performant; in tests NeoSmart.AsyncLock took 9.71x the time and allocated 7.42x the memory.

https://github.com/MarkCiliaVincenti/AsyncNonKeyedLockBenchmarks/actions/runs/7526873065/job/20485876144

@MarkCiliaVincenti
Copy link
Author

@tonysneed

@MarkCiliaVincenti
Copy link
Author

By the way there's a 6.4.2 version out since these PRs

@tonysneed
Copy link
Contributor

Running these tests with steps 2-4 results in a deadlock. Can you investigate?

public async Task SagaShouldCompleteToStep(int step)

@MarkCiliaVincenti
Copy link
Author

MarkCiliaVincenti commented Apr 22, 2024 via email

@MarkCiliaVincenti
Copy link
Author

Yes you are using lock reentrancy @tonysneed. Please look at the code now, but be careful as I'm seeing some CurrentStep--... is there a risk that it would enter twice with CurrentStep == 1? ConditionalLockAsync is a new feature and will only lock whilst the condition is true. Not real reentrancy but is often enough. Reentrancy and async code are at best challenging; some even claim impossible (https://itnext.io/reentrant-recursive-async-lock-is-impossible-in-c-e9593f4aa38a)

@MarkCiliaVincenti
Copy link
Author

Is it OK @tonysneed ?

@tonysneed
Copy link
Contributor

There are other tests failing due to deadlocks. Not sure how ConditionalLockAsync addresses reentrancy issues or whether the code needs to be refactored.

@MarkCiliaVincenti
Copy link
Author

It is always a good idea to refactor code to avoid reentrancy in async code. As I wrote before it is at least challenging. ConditionalLockAsync doesn't even try that. It's a simple 'if' statement... if the condition is true, it waits on the semaphore and if the condition is false it doesn't (i.e. enters immediately). That means you'd need to do the bookkeeping yourself and telling it yourself that it's a 'reentrancy'.

@MarkCiliaVincenti
Copy link
Author

@tonysneed I spent some time trying to understand how the code works but it's too complex and in essence I didn't understand what needs to be locked from what.

@tonysneed
Copy link
Contributor

Appreciate the info on the impracticality of reentrancy with synchronization using async await.

I'll create an issue to look into the need for synchronization on Saga.TransitionSagaStateAsync. In the meantime, I'll put this PR on hold.

@MarkCiliaVincenti
Copy link
Author

Played around with an experiment and got the tests to pass through the use of AsyncLocal, but I'd still try to avoid reentrancy as AsyncLocal could lead to problems.

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

Successfully merging this pull request may close these issues.

None yet

2 participants