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

feat: add experimental lock option with no-op default #731

Closed
wants to merge 1 commit into from

Conversation

hf
Copy link
Contributor

@hf hf commented Jul 12, 2023

Adds an @experimental lock option and uses it in _useSession. This can be used to test out different lock implementations before committing to a default one within this library.

It includes an implementation of a broadcastLock which can be used as a value to lock but is not done by default intentionally. This is an experimental API that is bound to have changes and potentially serious bugs. Once it has been well tested by the team and others it is likely to be promoted to the default option.

broadcastLock

Uses a BroadcastChannel to serialize access to a named critical section. The lock has three states: Acquiring, Backoff and Acquired.

When in the Acquiring state, a message is broadcast I will acquire the lock! and a timeout is started. If any message is received in this state, the lock immediately moves to the Backoff state. If no message is received, the lock moves to the Acquired state. It is assumed that if two messages are posted simultaneously at the channel, that both locks will receive the other's message.

When in the Backoff state, the lock sleeps for random amount of time before moving back in the Acquiring state. Each time it enters this state, it waits exponentially longer than the last time.

When in the Acquired state, the lock broadcasts I have the lock, please wait!. If any message is received on the channel, I have the lock! is broadcast immediately. The sender of the first I will acquire the lock! message received in this state will be sent the Go message after the operation is done which gives it priority over all other competing locks. This helps reduce the time needed for the locks to identify who should go next. Once the operation is done, the lock stops replying with I have the lock, please wait! messages on the channel.

Illustration of how broadcastLock works

src/GoTrueClient.ts Outdated Show resolved Hide resolved
@hf hf force-pushed the hf/use-lock branch 3 times, most recently from 18b64b0 to abce2ae Compare July 13, 2023 13:34
src/lib/locks.ts Outdated Show resolved Hide resolved
src/lib/locks.ts Show resolved Hide resolved
@hf hf force-pushed the hf/use-lock branch 5 times, most recently from 14c9acc to 0f3b9ad Compare July 13, 2023 16:54
'lock is already acquired, skipping for next tick'
)
} else {
console.error('Auto refresh tick failed with error. This is likely a transient error.', e)
Copy link
Contributor

@J0 J0 Jul 14, 2023

Choose a reason for hiding this comment

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

What would be the best way to advise a customer to debug this if they come back to us with an error? Wondering how we'd advise to support how to classify whether whether no action is needed vs it's something we should investigate

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's transient, but logging so it's not silent.

@hf
Copy link
Contributor Author

hf commented Jul 14, 2023

I will actually re-open with the broadcastLock in a new PR and just the locking code here.

@hf hf closed this Jul 14, 2023
@hf hf deleted the hf/use-lock branch July 14, 2023 13:26
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.

2 participants