Class: Pause::Redis::Adapter

Inherits:
Object
  • Object
show all
Includes:
Helper::Timing
Defined in:
lib/pause/redis/adapter.rb

Overview

This class encapsulates Redis operations used by Pause

Direct Known Subclasses

ShardedAdapter

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Helper::Timing

#period_marker

Constructor Details

#initialize(config) ⇒ Adapter

Returns a new instance of Adapter.



24
25
26
27
28
# File 'lib/pause/redis/adapter.rb', line 24

def initialize(config)
  @resolution          = config.resolution
  @time_blocks_to_keep = config.history / @resolution
  @history             = config.history
end

Instance Attribute Details

#historyObject

Returns the value of attribute history.



22
23
24
# File 'lib/pause/redis/adapter.rb', line 22

def history
  @history
end

#resolutionObject

Returns the value of attribute resolution.



22
23
24
# File 'lib/pause/redis/adapter.rb', line 22

def resolution
  @resolution
end

#time_blocks_to_keepObject

Returns the value of attribute time_blocks_to_keep.



22
23
24
# File 'lib/pause/redis/adapter.rb', line 22

def time_blocks_to_keep
  @time_blocks_to_keep
end

Class Method Details

.redisObject



10
11
12
# File 'lib/pause/redis/adapter.rb', line 10

def redis
  @redis ||= ::Redis.new(redis_connection_opts)
end

.redis_connection_optsObject



14
15
16
17
18
# File 'lib/pause/redis/adapter.rb', line 14

def redis_connection_opts
  { host: Pause.config.redis_host,
    port: Pause.config.redis_port,
    db: Pause.config.redis_db }
end

Instance Method Details

#all_keys(scope) ⇒ Object



62
63
64
# File 'lib/pause/redis/adapter.rb', line 62

def all_keys(scope)
  keys(tracked_scope(scope))
end

#delete_rate_limited_key(scope, id) ⇒ Object



83
84
85
86
# File 'lib/pause/redis/adapter.rb', line 83

def delete_rate_limited_key(scope, id)
  delete_tracking_keys(scope, [id])
  redis.zrem rate_limited_list(scope), id
end

#delete_rate_limited_keys(scope) ⇒ Object

For a scope, delete the entire sorted set that holds the block list. Also delete the original tracking information, so we don’t immediately re-block the id



74
75
76
77
78
79
80
81
# File 'lib/pause/redis/adapter.rb', line 74

def delete_rate_limited_keys(scope)
  return 0 unless rate_limited_keys(scope).any?

  delete_tracking_keys(scope, rate_limited_keys(scope))
  redis.zremrangebyscore(rate_limited_list(scope), '-inf', '+inf').tap do |_count|
    redis.del rate_limited_list(scope)
  end
end

#disable(scope) ⇒ Object



88
89
90
# File 'lib/pause/redis/adapter.rb', line 88

def disable(scope)
  redis.set("internal:|#{scope}|:disabled", '1')
end

#disabled?(scope) ⇒ Boolean

Returns:

  • (Boolean)


96
97
98
# File 'lib/pause/redis/adapter.rb', line 96

def disabled?(scope)
  !enabled?(scope)
end

#enable(scope) ⇒ Object



92
93
94
# File 'lib/pause/redis/adapter.rb', line 92

def enable(scope)
  redis.del("internal:|#{scope}|:disabled")
end

#enabled?(scope) ⇒ Boolean

Returns:

  • (Boolean)


100
101
102
# File 'lib/pause/redis/adapter.rb', line 100

def enabled?(scope)
  redis.get("internal:|#{scope}|:disabled").nil?
end

#expire_block_list(scope) ⇒ Object



104
105
106
# File 'lib/pause/redis/adapter.rb', line 104

def expire_block_list(scope)
  redis.zremrangebyscore rate_limited_list(scope), '-inf', Time.now.to_i
end

#increment(scope, identifier, timestamp, count = 1) ⇒ Object



37
38
39
40
41
42
43
44
45
# File 'lib/pause/redis/adapter.rb', line 37

def increment(scope, identifier, timestamp, count = 1)
  k = tracked_key(scope, identifier)
  with_multi do |redis|
    redis.zincrby k, count, period_marker(resolution, timestamp)
    redis.expire k, history
  end

  truncate_set_for(k)
end

#key_history(scope, identifier) ⇒ Object



47
48
49
# File 'lib/pause/redis/adapter.rb', line 47

def key_history(scope, identifier)
  extract_set_elements(tracked_key(scope, identifier))
end

#rate_limit!(scope, identifier, block_ttl) ⇒ Object



51
52
53
54
55
# File 'lib/pause/redis/adapter.rb', line 51

def rate_limit!(scope, identifier, block_ttl)
  timestamp = Time.now.to_i + block_ttl
  redis.zadd rate_limited_list(scope), timestamp, identifier
  expire_block_list(scope)
end

#rate_limited?(scope, identifier) ⇒ Boolean

Returns:

  • (Boolean)


57
58
59
60
# File 'lib/pause/redis/adapter.rb', line 57

def rate_limited?(scope, identifier)
  blocked_until = redis.zscore(rate_limited_list(scope), identifier)
  !!blocked_until && blocked_until > Time.now.to_i
end

#rate_limited_keys(scope) ⇒ Object



66
67
68
# File 'lib/pause/redis/adapter.rb', line 66

def rate_limited_keys(scope)
  redis.zrangebyscore rate_limited_list(scope), Time.now.to_i, '+inf'
end

#with_multiObject

Override in subclasses to disable



31
32
33
34
35
# File 'lib/pause/redis/adapter.rb', line 31

def with_multi
  redis.multi do |redis|
    yield(redis) if block_given?
  end
end