Class: Parse::Cache::Pool
- Inherits:
-
Object
- Object
- Parse::Cache::Pool
- Defined in:
- lib/parse/cache/pool.rb
Overview
Moneta-compatible facade over a ConnectionPool of Moneta stores. The Faraday caching middleware only calls four methods on its store (‘[]`, `key?`, `delete`, `store`); this class checks out a backend for each of them via `@pool.with`.
Why a pool: a single Moneta-Redis store wraps one Redis connection. Under a multi-threaded Puma worker (or any concurrent caller), threads serialize on that connection’s mutex. A pool of N stores lets up to N cache calls run in parallel.
Note that a cache hit costs two checkouts (‘key?` then `[]`). That is accepted to keep behavior identical to a plain Moneta store; callers should size the pool with that in mind (default 5, which matches the Puma default thread count).
Instance Attribute Summary collapse
-
#pool ⇒ Object
readonly
The wrapped ConnectionPool instance.
Instance Method Summary collapse
- #[](key) ⇒ Object
-
#clear ⇒ Object
Clear the underlying backend.
-
#close ⇒ Object
Close all pooled backends.
-
#create(key, value, options = {}) ⇒ Object
Atomic SETNX-style write.
- #delete(key) ⇒ Object
-
#increment(key, amount = 1, options = {}) ⇒ Object
Atomic counter increment.
-
#initialize(size: 5, timeout: 5) { ... } ⇒ Pool
constructor
A new instance of Pool.
- #key?(key) ⇒ Boolean
- #store(key, value, options = {}) ⇒ Object
Constructor Details
#initialize(size: 5, timeout: 5) { ... } ⇒ Pool
Returns a new instance of Pool.
32 33 34 35 36 |
# File 'lib/parse/cache/pool.rb', line 32 def initialize(size: 5, timeout: 5, &block) raise ArgumentError, "Parse::Cache::Pool requires a block that builds a Moneta store" unless block_given? @pool = ConnectionPool.new(size: size, timeout: timeout, &block) @closed = false end |
Instance Attribute Details
#pool ⇒ Object (readonly)
The wrapped ConnectionPool instance.
25 26 27 |
# File 'lib/parse/cache/pool.rb', line 25 def pool @pool end |
Instance Method Details
#[](key) ⇒ Object
38 39 40 |
# File 'lib/parse/cache/pool.rb', line 38 def [](key) @pool.with { |store| store[key] } end |
#clear ⇒ Object
Clear the underlying backend. Pooled Moneta stores all point at the same Redis DB, so a single checkout suffices — issuing ‘clear` on one connection flushes the DB for every connection.
72 73 74 75 |
# File 'lib/parse/cache/pool.rb', line 72 def clear @pool.with { |store| store.clear if store.respond_to?(:clear) } self end |
#close ⇒ Object
Close all pooled backends. Safe to call multiple times — repeat calls are no-ops. ‘ConnectionPool#shutdown` raises `ConnectionPool::PoolShuttingDownError` on a second invocation, so we gate it with a `@closed` flag.
81 82 83 84 85 |
# File 'lib/parse/cache/pool.rb', line 81 def close return if @closed @closed = true @pool.shutdown { |store| store.close if store.respond_to?(:close) } end |
#create(key, value, options = {}) ⇒ Object
Atomic SETNX-style write. Required by ‘Parse::CreateLock` to acquire cross-process locks against Redis-backed stores. Forwards to the underlying Moneta store’s ‘#create`, which returns `true` only if the key was absent and is now set.
58 59 60 |
# File 'lib/parse/cache/pool.rb', line 58 def create(key, value, = {}) @pool.with { |store| store.create(key, value, ) } end |
#delete(key) ⇒ Object
46 47 48 |
# File 'lib/parse/cache/pool.rb', line 46 def delete(key) @pool.with { |store| store.delete(key) } end |
#increment(key, amount = 1, options = {}) ⇒ Object
Atomic counter increment. Forwarded for parity with Moneta so callers expecting the full Moneta surface (counters, rate limits) work transparently through the pool.
65 66 67 |
# File 'lib/parse/cache/pool.rb', line 65 def increment(key, amount = 1, = {}) @pool.with { |store| store.increment(key, amount, ) } end |
#key?(key) ⇒ Boolean
42 43 44 |
# File 'lib/parse/cache/pool.rb', line 42 def key?(key) @pool.with { |store| store.key?(key) } end |
#store(key, value, options = {}) ⇒ Object
50 51 52 |
# File 'lib/parse/cache/pool.rb', line 50 def store(key, value, = {}) @pool.with { |store| store.store(key, value, ) } end |