Class: Rollout

Inherits:
Object
  • Object
show all
Defined in:
lib/rollout.rb,
lib/rollout/feature.rb,
lib/rollout/version.rb

Defined Under Namespace

Classes: Feature

Constant Summary collapse

RAND_BASE =
(2**32 - 1) / 100.0
VERSION =
'2.4.6'

Instance Method Summary collapse

Constructor Details

#initialize(storage, opts = {}) ⇒ Rollout

Returns a new instance of Rollout.



12
13
14
15
16
# File 'lib/rollout.rb', line 12

def initialize(storage, opts = {})
  @storage = storage
  @options = opts
  @groups  = { all: ->(_user) { true } }
end

Instance Method Details

#activate(feature) ⇒ Object



18
19
20
21
22
# File 'lib/rollout.rb', line 18

def activate(feature)
  with_feature(feature) do |f|
    f.percentage = 100
  end
end

#activate_group(feature, group) ⇒ Object



45
46
47
48
49
# File 'lib/rollout.rb', line 45

def activate_group(feature, group)
  with_feature(feature) do |f|
    f.add_group(group)
  end
end

#activate_percentage(feature, percentage) ⇒ Object



106
107
108
109
110
# File 'lib/rollout.rb', line 106

def activate_percentage(feature, percentage)
  with_feature(feature) do |f|
    f.percentage = percentage
  end
end

#activate_user(feature, user) ⇒ Object



57
58
59
60
61
# File 'lib/rollout.rb', line 57

def activate_user(feature, user)
  with_feature(feature) do |f|
    f.add_user(user)
  end
end

#activate_users(feature, users) ⇒ Object



69
70
71
72
73
# File 'lib/rollout.rb', line 69

def activate_users(feature, users)
  with_feature(feature) do |f|
    users.each { |user| f.add_user(user) }
  end
end

#active?(feature, user = nil) ⇒ Boolean

Returns:

  • (Boolean)


92
93
94
95
# File 'lib/rollout.rb', line 92

def active?(feature, user = nil)
  feature = get(feature)
  feature.active?(self, user)
end

#active_features(user = nil) ⇒ Object



157
158
159
160
161
# File 'lib/rollout.rb', line 157

def active_features(user = nil)
  multi_get(*features).select do |f|
    f.active?(self, user)
  end.map(&:name)
end

#active_in_group?(group, user) ⇒ Boolean

Returns:

  • (Boolean)


118
119
120
121
# File 'lib/rollout.rb', line 118

def active_in_group?(group, user)
  f = @groups[group.to_sym]
  f&.call(user)
end

#clear!Object



163
164
165
166
167
168
169
170
# File 'lib/rollout.rb', line 163

def clear!
  features.each do |feature|
    with_feature(feature, &:clear)
    @storage.del(key(feature))
  end

  @storage.del(features_key)
end

#clear_feature_data(feature) ⇒ Object



134
135
136
137
138
# File 'lib/rollout.rb', line 134

def clear_feature_data(feature)
  with_feature(feature) do |f|
    f.data = {}
  end
end

#deactivate(feature) ⇒ Object



24
25
26
# File 'lib/rollout.rb', line 24

def deactivate(feature)
  with_feature(feature, &:clear)
end

#deactivate_group(feature, group) ⇒ Object



51
52
53
54
55
# File 'lib/rollout.rb', line 51

def deactivate_group(feature, group)
  with_feature(feature) do |f|
    f.remove_group(group)
  end
end

#deactivate_percentage(feature) ⇒ Object



112
113
114
115
116
# File 'lib/rollout.rb', line 112

def deactivate_percentage(feature)
  with_feature(feature) do |f|
    f.percentage = 0
  end
end

#deactivate_user(feature, user) ⇒ Object



63
64
65
66
67
# File 'lib/rollout.rb', line 63

def deactivate_user(feature, user)
  with_feature(feature) do |f|
    f.remove_user(user)
  end
end

#deactivate_users(feature, users) ⇒ Object



75
76
77
78
79
# File 'lib/rollout.rb', line 75

def deactivate_users(feature, users)
  with_feature(feature) do |f|
    users.each { |user| f.remove_user(user) }
  end
end

#define_group(group, &block) ⇒ Object



88
89
90
# File 'lib/rollout.rb', line 88

def define_group(group, &block)
  @groups[group.to_sym] = block
end

#delete(feature) ⇒ Object



28
29
30
31
32
33
# File 'lib/rollout.rb', line 28

def delete(feature)
  features = (@storage.get(features_key) || '').split(',')
  features.delete(feature.to_s)
  @storage.set(features_key, features.join(','))
  @storage.del(key(feature))
end

#exists?(feature) ⇒ Boolean

Returns:

  • (Boolean)


172
173
174
175
176
177
178
179
180
# File 'lib/rollout.rb', line 172

def exists?(feature)
  # since redis-rb v4.2, `#exists?` replaces `#exists` which now returns integer value instead of boolean
  # https://github.com/redis/redis-rb/pull/918
  if @storage.respond_to?(:exists?)
    @storage.exists?(key(feature))
  else
    @storage.exists(key(feature))
  end
end

#feature_states(user = nil) ⇒ Object



151
152
153
154
155
# File 'lib/rollout.rb', line 151

def feature_states(user = nil)
  multi_get(*features).each_with_object({}) do |f, hash|
    hash[f.name] = f.active?(self, user)
  end
end

#featuresObject



147
148
149
# File 'lib/rollout.rb', line 147

def features
  (@storage.get(features_key) || '').split(',').map(&:to_sym)
end

#get(feature) ⇒ Object



123
124
125
126
# File 'lib/rollout.rb', line 123

def get(feature)
  string = @storage.get(key(feature))
  Feature.new(feature, string, @options)
end

#inactive?(feature, user = nil) ⇒ Boolean

Returns:

  • (Boolean)


102
103
104
# File 'lib/rollout.rb', line 102

def inactive?(feature, user = nil)
  !active?(feature, user)
end

#multi_get(*features) ⇒ Object



140
141
142
143
144
145
# File 'lib/rollout.rb', line 140

def multi_get(*features)
  return [] if features.empty?

  feature_keys = features.map { |feature| key(feature) }
  @storage.mget(*feature_keys).map.with_index { |string, index| Feature.new(features[index], string, @options) }
end

#set(feature, desired_state) ⇒ Object



35
36
37
38
39
40
41
42
43
# File 'lib/rollout.rb', line 35

def set(feature, desired_state)
  with_feature(feature) do |f|
    if desired_state
      f.percentage = 100
    else
      f.clear
    end
  end
end

#set_feature_data(feature, data) ⇒ Object



128
129
130
131
132
# File 'lib/rollout.rb', line 128

def set_feature_data(feature, data)
  with_feature(feature) do |f|
    f.data.merge!(data) if data.is_a? Hash
  end
end

#set_users(feature, users) ⇒ Object



81
82
83
84
85
86
# File 'lib/rollout.rb', line 81

def set_users(feature, users)
  with_feature(feature) do |f|
    f.users = []
    users.each { |user| f.add_user(user) }
  end
end

#user_in_active_users?(feature, user = nil) ⇒ Boolean

Returns:

  • (Boolean)


97
98
99
100
# File 'lib/rollout.rb', line 97

def user_in_active_users?(feature, user = nil)
  feature = get(feature)
  feature.user_in_active_users?(user)
end