Module: Supabase::Rails::Web::RefreshCoordinator
- Defined in:
- lib/supabase/rails/web/refresh_coordinator.rb
Overview
In-process mutex pool keyed by ‘SHA256(refresh_token)`. Two threads holding the same refresh token cooperate on a single outbound `auth.refresh_session` call instead of racing.
Documented limitation: across clustered Puma workers (separate processes) two simultaneous requests for the same user can each acquire their own worker-local mutex and both refresh. In practice browsers serialize cookie-bearing requests; acceptable for v0.2 and revisitable if telemetry shows refresh contention.
Entries are reference-counted: the SHA256 -> Mutex entry is dropped when the last holder releases it, so the hash does not grow unboundedly in long-lived workers.
Class Method Summary collapse
- .digest(refresh_token) ⇒ Object
-
.entry_count ⇒ Object
Number of live (refcounted) entries — for tests / introspection.
-
.reset! ⇒ Object
Test-only escape hatch.
-
.synchronize(refresh_token) ⇒ Object
Yield the block while holding the per-token mutex.
Class Method Details
.digest(refresh_token) ⇒ Object
39 40 41 |
# File 'lib/supabase/rails/web/refresh_coordinator.rb', line 39 def digest(refresh_token) Digest::SHA256.hexdigest(refresh_token.to_s) end |
.entry_count ⇒ Object
Number of live (refcounted) entries — for tests / introspection.
44 45 46 |
# File 'lib/supabase/rails/web/refresh_coordinator.rb', line 44 def entry_count @entries_mutex.synchronize { @entries.size } end |
.reset! ⇒ Object
Test-only escape hatch. Forcibly drops every entry so a leaked mutex from a previous example can’t bleed into the next.
50 51 52 |
# File 'lib/supabase/rails/web/refresh_coordinator.rb', line 50 def reset! @entries_mutex.synchronize { @entries.clear } end |
.synchronize(refresh_token) ⇒ Object
Yield the block while holding the per-token mutex. Returns the block’s return value.
29 30 31 32 33 34 35 36 37 |
# File 'lib/supabase/rails/web/refresh_coordinator.rb', line 29 def synchronize(refresh_token) key = digest(refresh_token) mutex = checkout(key) begin mutex.synchronize { yield } ensure checkin(key) end end |