Class: Rack::MiniProfiler::RedisStore

Inherits:
AbstractStore show all
Defined in:
lib/mini_profiler/storage/redis_store.rb

Constant Summary collapse

EXPIRES_IN_SECONDS =
60 * 60 * 24

Constants inherited from AbstractStore

AbstractStore::MAX_TOKEN_AGE

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = nil) ⇒ RedisStore

Returns a new instance of RedisStore.


11
12
13
14
15
16
# File 'lib/mini_profiler/storage/redis_store.rb', line 11

def initialize(args = nil)
  @args               = args || {}
  @prefix             = @args.delete(:prefix) || 'MPRedisStore'
  @redis_connection   = @args.delete(:connection)
  @expires_in_seconds = @args.delete(:expires_in) || EXPIRES_IN_SECONDS
end

Instance Attribute Details

#prefixObject (readonly)

Returns the value of attribute prefix


7
8
9
# File 'lib/mini_profiler/storage/redis_store.rb', line 7

def prefix
  @prefix
end

Instance Method Details

#allowed_tokensObject


83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/mini_profiler/storage/redis_store.rb', line 83

def allowed_tokens
  key1, key1_old, key2 = redis.mget("#{@prefix}-key1", "#{@prefix}-key1_old", "#{@prefix}-key2")

  if key1 && (key1.length == 32)
    return [key1, key2].compact
  end

  timeout = Rack::MiniProfiler::AbstractStore::MAX_TOKEN_AGE

  # TODO  this could be moved to lua to correct a concurrency flaw
  # it is not critical cause worse case some requests will miss profiling info

  # no key so go ahead and set it
  key1 = SecureRandom.hex

  if key1_old && (key1_old.length == 32)
    key2 = key1_old
    redis.setex "#{@prefix}-key2", timeout, key2
  else
    key2 = nil
  end

  redis.setex "#{@prefix}-key1", timeout, key1
  redis.setex "#{@prefix}-key1_old", timeout * 2, key1

  [key1, key2].compact
end

#diagnostics(user) ⇒ Object


66
67
68
69
70
71
72
# File 'lib/mini_profiler/storage/redis_store.rb', line 66

def diagnostics(user)
  client = (redis.respond_to? :_client) ? redis._client : redis.client
"Redis prefix: #{@prefix}
Redis location: #{client.host}:#{client.port} db: #{client.db}
unviewed_ids: #{get_unviewed_ids(user)}
"
end

#flush_tokensObject


74
75
76
# File 'lib/mini_profiler/storage/redis_store.rb', line 74

def flush_tokens
  redis.del("#{@prefix}-key1", "#{@prefix}-key1_old", "#{@prefix}-key2")
end

#get_unviewed_ids(user) ⇒ Object

Remove expired ids from the unviewed sorted set and return the remaining ids


60
61
62
63
64
# File 'lib/mini_profiler/storage/redis_store.rb', line 60

def get_unviewed_ids(user)
  key = user_key(user)
  redis.zremrangebyscore(key, '-inf', Process.clock_gettime(Process::CLOCK_MONOTONIC).to_i)
  redis.zrevrangebyscore(key, '+inf', '-inf')
end

#load(id) ⇒ Object


22
23
24
25
26
27
28
29
30
31
32
# File 'lib/mini_profiler/storage/redis_store.rb', line 22

def load(id)
  key = prefixed_id(id)
  raw = redis.get key
  begin
    Marshal::load(raw) if raw
  rescue
    # bad format, junk old data
    redis.del key
    nil
  end
end

#save(page_struct) ⇒ Object


18
19
20
# File 'lib/mini_profiler/storage/redis_store.rb', line 18

def save(page_struct)
  redis.setex prefixed_id(page_struct[:id]), @expires_in_seconds, Marshal::dump(page_struct)
end

#set_all_unviewed(user, ids) ⇒ Object


43
44
45
46
47
48
49
50
51
52
53
# File 'lib/mini_profiler/storage/redis_store.rb', line 43

def set_all_unviewed(user, ids)
  key = user_key(user)
  redis.del(key)
  ids.each do |id|
    if redis.exists(prefixed_id(id))
      expire_at = Process.clock_gettime(Process::CLOCK_MONOTONIC).to_i + redis.ttl(prefixed_id(id))
      redis.zadd(key, expire_at, id)
    end
  end
  redis.expire(key, @expires_in_seconds)
end

#set_unviewed(user, id) ⇒ Object


34
35
36
37
38
39
40
41
# File 'lib/mini_profiler/storage/redis_store.rb', line 34

def set_unviewed(user, id)
  key = user_key(user)
  if redis.exists(prefixed_id(id))
    expire_at = Process.clock_gettime(Process::CLOCK_MONOTONIC).to_i + redis.ttl(prefixed_id(id))
    redis.zadd(key, expire_at, id)
  end
  redis.expire(key, @expires_in_seconds)
end

#set_viewed(user, id) ⇒ Object


55
56
57
# File 'lib/mini_profiler/storage/redis_store.rb', line 55

def set_viewed(user, id)
  redis.zrem(user_key(user), id)
end

#simulate_expireObject

Only used for testing


79
80
81
# File 'lib/mini_profiler/storage/redis_store.rb', line 79

def simulate_expire
  redis.del("#{@prefix}-key1")
end