Class: Vanity::Adapters::RedisAdapter

Inherits:
AbstractAdapter show all
Defined in:
lib/vanity/adapters/redis_adapter.rb

Overview

Redis adapter.

Since:

  • 1.4.0

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ RedisAdapter

Returns a new instance of RedisAdapter

Since:

  • 1.4.0



31
32
33
34
35
36
# File 'lib/vanity/adapters/redis_adapter.rb', line 31

def initialize(options)
  @options = options.clone
  @options[:db] ||= @options[:database] || (@options[:path] && @options.delete(:path).split("/")[1].to_i)
  @options[:thread_safe] = true
  connect!
end

Instance Attribute Details

#redisObject (readonly)

Since:

  • 1.4.0



29
30
31
# File 'lib/vanity/adapters/redis_adapter.rb', line 29

def redis
  @redis
end

Instance Method Details

#ab_add_conversion(experiment, alternative, identity, count = 1, implicit = false) ⇒ Object

Since:

  • 1.4.0



198
199
200
201
202
203
204
205
206
207
208
# File 'lib/vanity/adapters/redis_adapter.rb', line 198

def ab_add_conversion(experiment, alternative, identity, count = 1, implicit = false)
  call_redis_with_failover(experiment, alternative, identity, count, implicit) do
    if implicit
      @experiments.sadd "#{experiment}:alts:#{alternative}:participants", identity
    else
      participating = @experiments.sismember("#{experiment}:alts:#{alternative}:participants", identity)
    end
    @experiments.sadd "#{experiment}:alts:#{alternative}:converted", identity if implicit || participating
    @experiments.incrby "#{experiment}:alts:#{alternative}:conversions", count
  end
end

#ab_add_participant(experiment, alternative, identity) ⇒ Object

Since:

  • 1.4.0



168
169
170
171
172
# File 'lib/vanity/adapters/redis_adapter.rb', line 168

def ab_add_participant(experiment, alternative, identity)
  call_redis_with_failover(experiment, alternative, identity) do
    @experiments.sadd "#{experiment}:alts:#{alternative}:participants", identity
  end
end

#ab_assigned(experiment, identity) ⇒ Object

Returns the participant's seen alternative in this experiment, if it exists

Since:

  • 1.4.0



187
188
189
190
191
192
193
194
195
196
# File 'lib/vanity/adapters/redis_adapter.rb', line 187

def ab_assigned(experiment, identity)
  call_redis_with_failover do
    Vanity.playground.experiments[experiment].alternatives.each do |alternative|
      if @experiments.sismember "#{experiment}:alts:#{alternative.id}:participants", identity
        return alternative.id
      end
    end
    nil
  end
end

#ab_counts(experiment, alternative) ⇒ Object

Since:

  • 1.4.0



141
142
143
144
145
146
147
# File 'lib/vanity/adapters/redis_adapter.rb', line 141

def ab_counts(experiment, alternative)
  {
    :participants => @experiments.scard("#{experiment}:alts:#{alternative}:participants").to_i,
          :converted    => @experiments.scard("#{experiment}:alts:#{alternative}:converted").to_i,
    :conversions  => @experiments.get("#{experiment}:alts:#{alternative}:conversions").to_i
  }
end

#ab_get_outcome(experiment) ⇒ Object

Since:

  • 1.4.0



210
211
212
213
# File 'lib/vanity/adapters/redis_adapter.rb', line 210

def ab_get_outcome(experiment)
  alternative = @experiments.get("#{experiment}:outcome")
  alternative && alternative.to_i
end

#ab_not_showing(experiment, identity) ⇒ Object

Since:

  • 1.4.0



162
163
164
165
166
# File 'lib/vanity/adapters/redis_adapter.rb', line 162

def ab_not_showing(experiment, identity)
  call_redis_with_failover do
    @experiments.del "#{experiment}:participant:#{identity}:show"
  end
end

#ab_seen(experiment, identity, alternative_or_id) ⇒ Object

Since:

  • 1.4.0



174
175
176
177
178
179
180
181
182
183
184
# File 'lib/vanity/adapters/redis_adapter.rb', line 174

def ab_seen(experiment, identity, alternative_or_id)
  with_ab_seen_deprecation(experiment, identity, alternative_or_id) do |expt, ident, alt_id|
    call_redis_with_failover(expt, ident, alt_id) do
      if @experiments.sismember "#{expt}:alts:#{alt_id}:participants", ident
        alt_id
      else
        nil
      end
    end
  end
end

#ab_set_outcome(experiment, alternative = 0) ⇒ Object

Since:

  • 1.4.0



215
216
217
# File 'lib/vanity/adapters/redis_adapter.rb', line 215

def ab_set_outcome(experiment, alternative = 0)
  @experiments.setnx "#{experiment}:outcome", alternative
end

#ab_show(experiment, identity, alternative) ⇒ Object

Since:

  • 1.4.0



149
150
151
152
153
# File 'lib/vanity/adapters/redis_adapter.rb', line 149

def ab_show(experiment, identity, alternative)
  call_redis_with_failover do
    @experiments.set("#{experiment}:participant:#{identity}:show", alternative)
  end
end

#ab_showing(experiment, identity) ⇒ Object

Since:

  • 1.4.0



155
156
157
158
159
160
# File 'lib/vanity/adapters/redis_adapter.rb', line 155

def ab_showing(experiment, identity)
  call_redis_with_failover do
    alternative = @experiments.get("#{experiment}:participant:#{identity}:show")
    alternative && alternative.to_i
  end
end

#active?Boolean

Returns:

  • (Boolean)

Since:

  • 1.4.0



38
39
40
# File 'lib/vanity/adapters/redis_adapter.rb', line 38

def active?
  !!@redis
end

#connect!Object

Since:

  • 1.4.0



54
55
56
57
58
# File 'lib/vanity/adapters/redis_adapter.rb', line 54

def connect!
  @redis = @options[:redis] || Redis.new(@options)
  @metrics = Redis::Namespace.new("vanity:metrics", :redis=>redis)
  @experiments = Redis::Namespace.new("vanity:experiments", :redis=>redis)
end

#destroy_experiment(experiment) ⇒ Object

Since:

  • 1.4.0



219
220
221
222
223
224
225
226
227
# File 'lib/vanity/adapters/redis_adapter.rb', line 219

def destroy_experiment(experiment)
  cursor = nil

  while cursor != "0" do
    cursor, keys = @experiments.scan(cursor || "0", match: "#{experiment}:*")

    @experiments.del(*keys) unless keys.empty?
  end
end

#destroy_metric(metric) ⇒ Object

Since:

  • 1.4.0



89
90
91
# File 'lib/vanity/adapters/redis_adapter.rb', line 89

def destroy_metric(metric)
  @metrics.del(*@metrics.keys("#{metric}:*"))
end

#disconnect!Object

Since:

  • 1.4.0



42
43
44
45
46
47
# File 'lib/vanity/adapters/redis_adapter.rb', line 42

def disconnect!
  if redis
    redis.disconnect!
  end
  @redis = nil
end

#experiment_persisted?(experiment) ⇒ Boolean

– Experiments –

Returns:

  • (Boolean)

Since:

  • 1.4.0



96
97
98
# File 'lib/vanity/adapters/redis_adapter.rb', line 96

def experiment_persisted?(experiment)
  !!@experiments.get("#{experiment}:created_at")
end

#flushdbObject

Since:

  • 1.4.0



64
65
66
# File 'lib/vanity/adapters/redis_adapter.rb', line 64

def flushdb
  @redis.flushdb
end

#get_experiment_completed_at(experiment) ⇒ Object

Since:

  • 1.4.0



115
116
117
118
# File 'lib/vanity/adapters/redis_adapter.rb', line 115

def get_experiment_completed_at(experiment)
  completed_at = @experiments.get("#{experiment}:completed_at")
  completed_at && Time.at(completed_at.to_i)
end

#get_experiment_created_at(experiment) ⇒ Object

Since:

  • 1.4.0



106
107
108
109
# File 'lib/vanity/adapters/redis_adapter.rb', line 106

def get_experiment_created_at(experiment)
  created_at = @experiments.get("#{experiment}:created_at")
  created_at && Time.at(created_at.to_i)
end

#get_metric_last_update_at(metric) ⇒ Object

– Metrics –

Since:

  • 1.4.0



70
71
72
73
# File 'lib/vanity/adapters/redis_adapter.rb', line 70

def get_metric_last_update_at(metric)
  last_update_at = @metrics.get("#{metric}:last_update_at")
  last_update_at && Time.at(last_update_at.to_i)
end

#is_experiment_completed?(experiment) ⇒ Boolean

Returns:

  • (Boolean)

Since:

  • 1.4.0



120
121
122
123
124
# File 'lib/vanity/adapters/redis_adapter.rb', line 120

def is_experiment_completed?(experiment)
  call_redis_with_failover do
    @experiments.exists("#{experiment}:completed_at")
  end
end

#is_experiment_enabled?(experiment) ⇒ Boolean

Returns:

  • (Boolean)

Since:

  • 1.4.0



132
133
134
135
136
137
138
139
# File 'lib/vanity/adapters/redis_adapter.rb', line 132

def is_experiment_enabled?(experiment)
  value = @experiments.get("#{experiment}:enabled")
  if Vanity.configuration.experiments_start_enabled
    value != 'false'
  else
    value == 'true'
  end
end

#metric_track(metric, timestamp, identity, values) ⇒ Object

Since:

  • 1.4.0



75
76
77
78
79
80
81
82
# File 'lib/vanity/adapters/redis_adapter.rb', line 75

def metric_track(metric, timestamp, identity, values)
  call_redis_with_failover(metric, timestamp, identity, values) do
    values.each_with_index do |v,i|
      @metrics.incrby "#{metric}:#{timestamp.to_date}:value:#{i}", v
    end
    @metrics.set("#{metric}:last_update_at", Time.now.to_i)
  end
end

#metric_values(metric, from, to) ⇒ Object

Since:

  • 1.4.0



84
85
86
87
# File 'lib/vanity/adapters/redis_adapter.rb', line 84

def metric_values(metric, from, to)
  single = @metrics.mget(*(from.to_date..to.to_date).map { |date| "#{metric}:#{date}:value:0" }) || []
  single.map { |v| [v.to_i] }
end

#reconnect!Object

Since:

  • 1.4.0



49
50
51
52
# File 'lib/vanity/adapters/redis_adapter.rb', line 49

def reconnect!
  disconnect!
  connect!
end

#set_experiment_completed_at(experiment, time) ⇒ Object

Since:

  • 1.4.0



111
112
113
# File 'lib/vanity/adapters/redis_adapter.rb', line 111

def set_experiment_completed_at(experiment, time)
  @experiments.setnx "#{experiment}:completed_at", time.to_i
end

#set_experiment_created_at(experiment, time) ⇒ Object

Since:

  • 1.4.0



100
101
102
103
104
# File 'lib/vanity/adapters/redis_adapter.rb', line 100

def set_experiment_created_at(experiment, time)
  call_redis_with_failover do
    @experiments.setnx "#{experiment}:created_at", time.to_i
  end
end

#set_experiment_enabled(experiment, enabled) ⇒ Object

Since:

  • 1.4.0



126
127
128
129
130
# File 'lib/vanity/adapters/redis_adapter.rb', line 126

def set_experiment_enabled(experiment, enabled)
  call_redis_with_failover do
    @experiments.set "#{experiment}:enabled", enabled
  end
end

#to_sObject

Since:

  • 1.4.0



60
61
62
# File 'lib/vanity/adapters/redis_adapter.rb', line 60

def to_s
  redis.id
end