Class: WSDL::Cache
- Inherits:
-
Object
- Object
- WSDL::Cache
- Defined in:
- lib/wsdl/cache.rb
Overview
Thread-safe in-memory LRU cache for parsed WSDL definitions.
This cache is designed to avoid redundant HTTP requests and parsing when working with WSDL documents, especially in multithreaded environments. When a +max_entries+ limit is set, the least recently used entry is evicted to make room for new ones.
Uses double-checked locking so the global mutex is never held while the block executes. Concurrent requests for different keys compute in parallel. Under contention for the same uncached key, duplicate computation may occur but only the first result is stored — the block must be idempotent.
Instance Method Summary collapse
-
#clear ⇒ void
Removes all entries from the cache.
-
#delete(key) ⇒ Object?
Removes a specific entry from the cache.
-
#fetch(key) { ... } ⇒ Object
Fetches a value from the cache, or computes and stores it if not present.
-
#initialize(ttl: nil, max_entries: nil) ⇒ Cache
constructor
Creates a new Cache instance.
-
#key?(key) ⇒ Boolean
Checks if a key exists in the cache and hasn't expired.
-
#size ⇒ Integer
Returns the number of entries in the cache.
Constructor Details
#initialize(ttl: nil, max_entries: nil) ⇒ Cache
Creates a new Cache instance.
58 59 60 61 62 63 |
# File 'lib/wsdl/cache.rb', line 58 def initialize(ttl: nil, max_entries: nil) @store = {} @ttl = ttl @max_entries = max_entries @mutex = Mutex.new end |
Instance Method Details
#clear ⇒ void
This method returns an undefined value.
Removes all entries from the cache.
102 103 104 105 106 |
# File 'lib/wsdl/cache.rb', line 102 def clear @mutex.synchronize do @store.clear end end |
#delete(key) ⇒ Object?
Removes a specific entry from the cache.
132 133 134 135 136 137 |
# File 'lib/wsdl/cache.rb', line 132 def delete(key) @mutex.synchronize do entry = @store.delete(key) entry&.fetch(:value) end end |
#fetch(key) { ... } ⇒ Object
Fetches a value from the cache, or computes and stores it if not present.
If the key exists and hasn't expired, returns the cached value. Otherwise, yields to the block outside the lock, stores the result, and returns it. A second lock acquisition double-checks that another thread hasn't populated the entry in the meantime.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/wsdl/cache.rb', line 76 def fetch(key) # Fast path — return a cached, non-expired entry. @mutex.synchronize do entry = promote!(key) return entry[:value] if entry end # Compute outside the lock so concurrent misses for different keys # are not serialized against each other. value = yield # Store the result. Double-check: if another thread populated # the entry while we were computing, keep the earlier value. @mutex.synchronize do entry = promote!(key) return entry[:value] if entry evict_lru! if @max_entries && @store.size >= @max_entries @store[key] = { value:, timestamp: Time.now } value end end |
#key?(key) ⇒ Boolean
Checks if a key exists in the cache and hasn't expired.
121 122 123 124 125 126 |
# File 'lib/wsdl/cache.rb', line 121 def key?(key) @mutex.synchronize do entry = @store[key] !!(entry && !expired?(entry)) end end |
#size ⇒ Integer
Returns the number of entries in the cache.
111 112 113 114 115 |
# File 'lib/wsdl/cache.rb', line 111 def size @mutex.synchronize do @store.size end end |