Class: RubyLlmMesh::Cache::RedisStore
- Inherits:
-
Object
- Object
- RubyLlmMesh::Cache::RedisStore
- Defined in:
- lib/ruby_llm_mesh/cache/redis_store.rb
Overview
Redis-backed store for distributed semantic cache entries.
Requires the optional redis gem — soft-loaded only when configured.
Constant Summary collapse
- INDEX_KEY =
"ruby_llm_mesh:semantic_cache:index"- ENTRY_PREFIX =
"ruby_llm_mesh:semantic_cache:entry:"
Class Method Summary collapse
Instance Method Summary collapse
- #all ⇒ Object
- #clear! ⇒ Object
-
#initialize(url:) ⇒ RedisStore
constructor
A new instance of RedisStore.
- #size ⇒ Object
- #write(id:, prompt:, embedding:, payload:, ttl:) ⇒ Object
Constructor Details
#initialize(url:) ⇒ RedisStore
Returns a new instance of RedisStore.
25 26 27 28 29 30 31 32 33 |
# File 'lib/ruby_llm_mesh/cache/redis_store.rb', line 25 def initialize(url:) unless self.class.redis_available? raise ConfigurationError, "semantic cache backend :redis requires the optional `redis` gem — " \ "add `gem \"redis\"` to your Gemfile or omit redis_url to use memory store" end @redis = ::Redis.new(url: url) end |
Class Method Details
.redis_available? ⇒ Boolean
14 15 16 17 18 19 20 21 22 23 |
# File 'lib/ruby_llm_mesh/cache/redis_store.rb', line 14 def self.redis_available? return @redis_available if defined?(@redis_available) && !@redis_available.nil? begin require "redis" @redis_available = true rescue LoadError @redis_available = false end end |
Instance Method Details
#all ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/ruby_llm_mesh/cache/redis_store.rb', line 35 def all ids = @redis.smembers(INDEX_KEY) stale = [] entries = ids.filter_map do |id| raw = @redis.get("#{ENTRY_PREFIX}#{id}") unless raw stale << id next end data = JSON.parse(raw) MemoryStore::Entry.new( id: id, prompt: data["prompt"], embedding: data["embedding"], payload: data["payload"], expires_at: data["expires_at"] ? Time.at(data["expires_at"]) : nil ) rescue JSON::ParserError stale << id nil end cleanup_stale_index!(stale) entries end |
#clear! ⇒ Object
84 85 86 87 88 89 |
# File 'lib/ruby_llm_mesh/cache/redis_store.rb', line 84 def clear! ids = @redis.smembers(INDEX_KEY) keys = ids.map { |id| "#{ENTRY_PREFIX}#{id}" } @redis.del(*keys) if keys.any? @redis.del(INDEX_KEY) end |
#size ⇒ Object
91 92 93 |
# File 'lib/ruby_llm_mesh/cache/redis_store.rb', line 91 def size all.length end |
#write(id:, prompt:, embedding:, payload:, ttl:) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/ruby_llm_mesh/cache/redis_store.rb', line 61 def write(id:, prompt:, embedding:, payload:, ttl:) id ||= SecureRandom.uuid expires_at = ttl && ttl.positive? ? Time.now.to_i + ttl : nil data = JSON.generate( "prompt" => prompt, "embedding" => , "payload" => payload, "expires_at" => expires_at ) key = "#{ENTRY_PREFIX}#{id}" if ttl && ttl.positive? @redis.setex(key, ttl, data) else @redis.set(key, data) end begin @redis.sadd(INDEX_KEY, [id]) rescue ArgumentError, TypeError, Redis::CommandError @redis.sadd(INDEX_KEY, id) end true end |