Skip to content

chore(ad-hoc): remove AsyncSemaphore - #543

Merged
andrii-vysotskyi-cko merged 6 commits into
masterfrom
chore/remove-async-semaphore
Oct 27, 2026
Merged

andrii-vysotskyi-cko merged 6 commits into
masterfrom
chore/remove-async-semaphore

Conversation

@andrii-vysotskyi-cko

Copy link
Copy Markdown
Collaborator

Summary

AsyncSemaphore is flaky: signal() bumped the counter and resumed the oldest waiter in two steps, so a reentrant wait() could take the permit in between and leave the resumed waiter with a negative count. Instead of fixing it, this PR removes it and replaces each of the three usages with a structure that fits the call site.

  • ThrottledWebAuthenticationSessionDecorator serialises authentications through a task chain: each call awaits the previously enqueued task before running. Cancellation while queued is observed once the predecessor completes.
  • DefaultCustomerActionsService no longer holds concurrency state. Serialisation moved to a new SerialCustomerActionsServiceDecorator using the same chain, wired in ProcessOut. Its job is to protect the merchant's PO3DS2Service from overlapping fingerprint and challenge calls.
  • PONetcetera3DS2Service replaces both semaphores with an explicit state (idle, authenticating, ready, challenging, cleaning). Overlapping calls on an instance are rejected as a developer error, clean() during an in-flight operation is ignored with a warning, and a failed authentication tears down what it created and returns to idle. The static cross-instance guard is gone; the SDK's intolerance of concurrent use is documented instead.
  • AsyncSemaphore, AsyncSemaphoreSuspension, and their tests are deleted.

@andrii-vysotskyi-cko
andrii-vysotskyi-cko merged commit a3dcdeb into master Oct 27, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants