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.



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

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.



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

def history
  @history
end

#resolutionObject

Returns the value of attribute resolution.



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

def resolution
  @resolution
end

#time_blocks_to_keepObject

Returns the value of attribute time_blocks_to_keep.



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

def time_blocks_to_keep
  @time_blocks_to_keep
end

Class Method Details

.redisObject



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

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

.redis_connection_optsObject



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

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



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

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

#delete_rate_limited_key(scope, id) ⇒ Object



81
82
83
84
# File 'lib/pause/redis/adapter.rb', line 81

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



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

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



86
87
88
# File 'lib/pause/redis/adapter.rb', line 86

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

#disabled?(scope) ⇒ Boolean

Returns:

  • (Boolean)


94
95
96
# File 'lib/pause/redis/adapter.rb', line 94

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

#enable(scope) ⇒ Object



90
91
92
# File 'lib/pause/redis/adapter.rb', line 90

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

#enabled?(scope) ⇒ Boolean

Returns:

  • (Boolean)


98
99
100
# File 'lib/pause/redis/adapter.rb', line 98

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

#expire_block_list(scope) ⇒ Object



102
103
104
# File 'lib/pause/redis/adapter.rb', line 102

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

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



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

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



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

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

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



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

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)


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

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



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

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

#with_multiObject

Override in subclasses to disable



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

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