Skip to content

Commit

Permalink
add generic cache
Browse files Browse the repository at this point in the history
  • Loading branch information
JadeKharats authored and kickster97 committed Nov 27, 2024
1 parent cf00c87 commit d13cb95
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 0 deletions.
36 changes: 36 additions & 0 deletions spec/cache_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
require "./spec_helper"

describe LavinMQ::Cache do
cache = LavinMQ::Cache(String, String).new(1.seconds)

it "set key" do
cache.set("key1", "allow").should eq "allow"
end

it "get key" do
cache.set("keyget", "deny")
cache.get?("keyget").should eq "deny"
end

it "invalid cache after 10 second" do
cache.set("keyinvalid", "expired")
sleep(2.seconds)
cache.get?("keyinvalid").should be_nil
end

it "delete key" do
cache.set("keydelete", "deleted")
cache.delete("keydelete")
cache.get?("keydelete").should be_nil
end

it "cleanup expired entry" do
cache.set("clean1", "expired1")
cache.set("clean2", "expired2")
cache.set("clean3", "valid", 10.seconds)
sleep(2.seconds)
cache.get?("clean1").should be_nil
cache.get?("clean2").should be_nil
cache.get?("clean3").should eq "valid"
end
end
66 changes: 66 additions & 0 deletions src/lavinmq/cache.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
module LavinMQ
class CacheEntry(T)
getter value : T
getter expires_at : Time

def initialize(@value : T, ttl : Time::Span)
@expires_at = Time.utc + ttl
end

def expired? : Bool
Time.utc > @expires_at
end
end

class Cache(K, V)
def initialize(@default_ttl : Time::Span = 1.hour)
@mutex = Mutex.new
@data = Hash(K, CacheEntry(V)).new
end

def set(key : K, value : V, ttl : Time::Span = @default_ttl) : V
@mutex.synchronize do
@data[key] = CacheEntry.new(value, ttl)
value
end
end

def get?(key : K) : V?
@mutex.synchronize do
entry = @data[key]?
return nil unless entry

if entry.expired?
@data.delete(key)
nil
else
entry.value
end
end
end

def delete(key : K) : Bool
@mutex.synchronize do
@data.delete(key) ? true : false
end
end

def cleanup
@mutex.synchronize do
@data.reject! { |_, entry| entry.expired? }
end
end

def clear
@mutex.synchronize do
@data.clear
end
end

def size : Int32
@mutex.synchronize do
@data.size
end
end
end
end
1 change: 1 addition & 0 deletions src/lavinmq/server.cr
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require "./exchange"
require "./amqp/queue"
require "./parameter"
require "./config"
require "./cache"
require "./connection_info"
require "./proxy_protocol"
require "./client/client"
Expand Down

0 comments on commit d13cb95

Please sign in to comment.