Class: Yes::Core::Authorization::LookupCache
- Inherits:
-
Object
- Object
- Yes::Core::Authorization::LookupCache
- Defined in:
- lib/yes/core/authorization/lookup_cache.rb
Overview
Scoped memoization for the read-only lookups an authorization pass repeats.
Authorizing a batch of commands resolves the same two things once per command: the principal data (which depends only on the request's auth data) and the authorized resource (which the commands of a batch commonly share). Both are pure reads, and a batch is authorized in full before any of its commands is executed, so no write can invalidate them while the pass is running.
Caching is only active inside LookupCache.with_scope. Outside one, LookupCache.fetch just yields, so callers keep their uncached behaviour unless they opt in. The store lives in ActiveSupport::IsolatedExecutionState, which keeps it per thread/fiber, and LookupCache.with_scope always clears it on the way out so nothing leaks into the next request.
Cached values are shared by every LookupCache.fetch for the same key, so callers must treat them as read-only.
Constant Summary collapse
- STORE_KEY =
:yes_core_authorization_lookup_cache
Class Method Summary collapse
-
.active? ⇒ Boolean
Whether a scope is currently open.
-
.fetch(key) { ... } ⇒ Object
Returns the value cached under key, computing it via the block on a miss.
-
.with_scope { ... } ⇒ Object
Runs the block with caching enabled, clearing the cache afterwards.
Class Method Details
.active? ⇒ Boolean
Returns whether a scope is currently open.
65 66 67 |
# File 'lib/yes/core/authorization/lookup_cache.rb', line 65 def active? ActiveSupport::IsolatedExecutionState.key?(STORE_KEY) end |
.fetch(key) { ... } ⇒ Object
Returns the value cached under key, computing it via the block on a miss. Without an open scope the block's value is returned uncached.
55 56 57 58 59 60 61 62 |
# File 'lib/yes/core/authorization/lookup_cache.rb', line 55 def fetch(key) return yield unless active? store = ActiveSupport::IsolatedExecutionState[STORE_KEY] return store[key] if store.key?(key) store[key] = yield end |
.with_scope { ... } ⇒ Object
Runs the block with caching enabled, clearing the cache afterwards. A nested scope reuses the cache of the outermost one and leaves clearing to it.
37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/yes/core/authorization/lookup_cache.rb', line 37 def with_scope return yield if active? ActiveSupport::IsolatedExecutionState[STORE_KEY] = {} begin yield ensure ActiveSupport::IsolatedExecutionState.delete(STORE_KEY) end end |