Class: Tina4::CacheBackends::MongoBackend
- Inherits:
-
BaseBackend
- Object
- BaseBackend
- Tina4::CacheBackends::MongoBackend
- Defined in:
- lib/tina4/cache_backends/mongo_backend.rb
Overview
MongoDB backend backed by a TTL collection (parity with Python _MongoBackend). Requires the ‘mongo` gem — reuses the same connection style as the Mongo session handler. The cache lives in collection tina4_cache with a TTL index on expires_at. The database name is taken from the URL path (mongodb://host:27017/<db>) or defaults to tina4_cache.
Instance Method Summary collapse
- #available? ⇒ Boolean
- #clear ⇒ Object
- #delete(key) ⇒ Object
- #get(key) ⇒ Object
-
#initialize(url: "mongodb://localhost:27017", max_entries: 1000) ⇒ MongoBackend
constructor
A new instance of MongoBackend.
- #name ⇒ Object
- #set(key, value, ttl) ⇒ Object
- #stats ⇒ Object
Constructor Details
#initialize(url: "mongodb://localhost:27017", max_entries: 1000) ⇒ MongoBackend
Returns a new instance of MongoBackend.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/tina4/cache_backends/mongo_backend.rb', line 15 def initialize(url: "mongodb://localhost:27017", max_entries: 1000) @max_entries = max_entries @hits = 0 @misses = 0 @coll = nil begin require "mongo" Mongo::Logger.logger.level = Logger::FATAL if defined?(Mongo::Logger) db_name = database_from_url(url) client_opts = { server_selection_timeout: 5, database: db_name } # Credentials from env when not embedded in the URL (parity with DB layer). unless url.include?("@") mu = env_nonempty("TINA4_CACHE_USERNAME") mp = env_nonempty("TINA4_CACHE_PASSWORD") client_opts[:user] = mu if mu client_opts[:password] = mp if mp end client = Mongo::Client.new(url, **client_opts) @coll = client[:tina4_cache] @coll.indexes.create_one({ expires_at: 1 }, expire_after: 0) client.database.command(ping: 1) rescue LoadError, StandardError @coll = nil end end |
Instance Method Details
#available? ⇒ Boolean
41 42 43 |
# File 'lib/tina4/cache_backends/mongo_backend.rb', line 41 def available? !@coll.nil? end |
#clear ⇒ Object
91 92 93 94 95 96 97 98 99 100 |
# File 'lib/tina4/cache_backends/mongo_backend.rb', line 91 def clear @hits = 0 @misses = 0 return if @coll.nil? begin @coll.delete_many({}) rescue StandardError end end |
#delete(key) ⇒ Object
81 82 83 84 85 86 87 88 89 |
# File 'lib/tina4/cache_backends/mongo_backend.rb', line 81 def delete(key) return false if @coll.nil? begin @coll.delete_one(_id: key).deleted_count > 0 rescue StandardError false end end |
#get(key) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/tina4/cache_backends/mongo_backend.rb', line 45 def get(key) if @coll.nil? @misses += 1 return nil end begin doc = @coll.find(_id: key).first unless doc @misses += 1 return nil end exp = doc["expires_at"] if exp && exp < Time.now.utc @coll.delete_one(_id: key) @misses += 1 return nil end @hits += 1 JSON.parse(doc["value"]) rescue StandardError @misses += 1 nil end end |
#name ⇒ Object
113 114 115 |
# File 'lib/tina4/cache_backends/mongo_backend.rb', line 113 def name "mongodb" end |
#set(key, value, ttl) ⇒ Object
70 71 72 73 74 75 76 77 78 79 |
# File 'lib/tina4/cache_backends/mongo_backend.rb', line 70 def set(key, value, ttl) return if @coll.nil? begin doc = { _id: key, value: JSON.generate(value) } doc[:expires_at] = Time.now.utc + ttl if ttl > 0 @coll.replace_one({ _id: key }, doc, upsert: true) rescue StandardError end end |
#stats ⇒ Object
102 103 104 105 106 107 108 109 110 111 |
# File 'lib/tina4/cache_backends/mongo_backend.rb', line 102 def stats size = 0 unless @coll.nil? begin size = @coll.count_documents({}) rescue StandardError end end { hits: @hits, misses: @misses, size: size, backend: "mongodb" } end |