Class: ActiveRecordApi::Request::TokenCache

Inherits:
Object
  • Object
show all
Includes:
ActiveAttr::Model
Defined in:
lib/active_record_api/request/token_cache.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#debugObject

Returns the value of attribute debug.



6
7
8
# File 'lib/active_record_api/request/token_cache.rb', line 6

def debug
  @debug
end

Instance Method Details

#acquire_lockObject



88
89
90
91
92
93
# File 'lib/active_record_api/request/token_cache.rb', line 88

def acquire_lock
  @redis_client.set 'auth_token_lock', unique_key, nx: true, ex: 8
  current_lock_value = @redis_client.get 'auth_token_lock'
  debug_log "#{current_lock_value} == #{unique_key}"
  current_lock_value == unique_key
end

#debug_log(message) ⇒ Object



84
85
86
# File 'lib/active_record_api/request/token_cache.rb', line 84

def debug_log(message)
  Rails.logger.info message if debug && defined? Rails
end

#fetch_token(token_proc) ⇒ Object



19
20
21
# File 'lib/active_record_api/request/token_cache.rb', line 19

def fetch_token(token_proc)
  retrieve_token_from_redis(token_proc)
end

#flushObject



8
9
10
11
12
13
14
15
16
17
# File 'lib/active_record_api/request/token_cache.rb', line 8

def flush
  return unless defined? AUTH_REDIS_POOL
  debug_log 'flushing token cache'
  AUTH_REDIS_POOL.with do |client|
    @redis_client = client
    @redis_client.del('auth_token')
    release_lock
  end
  debug_log 'token cache has been flushed'
end

#redis_sessionObject



67
68
69
70
71
72
73
74
# File 'lib/active_record_api/request/token_cache.rb', line 67

def redis_session
  if redis_session_impossible?
    debug_log 'Redis session environment variables not present.'
    return nil
  end

  @redis_session ||= Redis.new({ url: "redis://#{ENV['REDIS_SESSION_HOST']}", db: ENV['REDIS_SESSION'] })
end

#redis_session_impossible?Boolean

Returns:

  • (Boolean)


62
63
64
65
# File 'lib/active_record_api/request/token_cache.rb', line 62

def redis_session_impossible?
  return true unless defined? Redis
  ENV['REDIS_SESSION_HOST'].nil? || ENV['REDIS_SESSION'].nil?
end

#release_lockObject



95
96
97
# File 'lib/active_record_api/request/token_cache.rb', line 95

def release_lock
  @redis_client.del 'auth_token_lock'
end

#retrieve_token_from_redis(token_proc) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
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
60
# File 'lib/active_record_api/request/token_cache.rb', line 23

def retrieve_token_from_redis(token_proc)
  debug_log 'looking for token in cache'
  unless defined? AUTH_REDIS_POOL
    debug_log 'no auth redis pool. getting new token'
    token = token_proc.call
    raise "no token returned! #{token}" if token.nil?
    return token
  end
  AUTH_REDIS_POOL.with do |client|
    @redis_client = client
    @token = nil
    @retry = 0
    while @token.nil? && @retry < 5
      @token = @redis_client.get('auth_token')
      debug_log "retry ##{@retry}"
      debug_log "found token: #{@token}"
      @retry += 1
      if @token.nil? || session_missing_for?(@token)
        if acquire_lock
          begin
            debug_log 'acquired lock and fetching token for cache'
            @token = token_proc.call
            raise "no token returned! #{@token}" if @token.nil?
            @redis_client.set 'auth_token', @token
          ensure
            debug_log 'releasing lock'
            release_lock
          end
        else
          debug_log 'waiting for token to be cached'
          sleep 3
        end
      end
    end
  end
  raise "no token found after waiting #{@retry} times" if @token.nil?
  @token
end

#session_missing_for?(token) ⇒ Boolean

Returns:

  • (Boolean)


76
77
78
79
80
81
82
# File 'lib/active_record_api/request/token_cache.rb', line 76

def session_missing_for?(token)
  return false if redis_session.nil?
  session = (redis_session.send(:get, token) if redis_session.respond_to?(:get))
  debug_log("Session located for token #{token}") unless session.nil?
  debug_log("Session could not be located for token #{token}") if session.nil?
  session.nil?
end

#unique_keyObject



99
100
101
# File 'lib/active_record_api/request/token_cache.rb', line 99

def unique_key
  @unique_key ||= rand.to_s
end