1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
# frozen_string_literal: true
class Rollout
class Feature
attr_accessor :groups, :users, :percentage, :data
attr_reader :name, :options
def initialize(name, string = nil, opts = {})
@options = opts
@name = name
if string
raw_percentage, raw_users, raw_groups, raw_data = string.split('|', 4)
@percentage = raw_percentage.to_f
@users = users_from_string(raw_users)
@groups = groups_from_string(raw_groups)
@data = raw_data.nil? || raw_data.strip.empty? ? {} : JSON.parse(raw_data)
else
clear
end
end
def serialize
"#{@percentage}|#{@users.to_a.join(',')}|#{@groups.to_a.join(',')}|#{serialize_data}"
end
def add_user(user)
id = user_id(user)
@users << id unless @users.include?(id)
end
def remove_user(user)
@users.delete(user_id(user))
end
def add_group(group)
@groups << group.to_sym unless @groups.include?(group.to_sym)
end
def remove_group(group)
@groups.delete(group.to_sym)
end
def clear
@groups = groups_from_string('')
@users = users_from_string('')
@percentage = 0
@data = {}
end
def active?(rollout, user)
if user
id = user_id(user)
user_in_percentage?(id) ||
user_in_active_users?(id) ||
user_in_active_group?(user, rollout)
else
@percentage == 100
end
end
def user_in_active_users?(user)
@users.include?(user_id(user))
end
def to_hash
{
percentage: @percentage,
groups: @groups,
users: @users,
data: @data,
}
end
private
def user_id(user)
if user.is_a?(Integer) || user.is_a?(String)
user.to_s
else
user.send(id_user_by).to_s
end
end
def id_user_by
@options[:id_user_by] || :id
end
def user_in_percentage?(user)
Zlib.crc32(user_id_for_percentage(user)) < RAND_BASE * @percentage
end
def user_id_for_percentage(user)
if @options[:randomize_percentage]
user_id(user).to_s + @name.to_s
else
user_id(user)
end
end
def user_in_active_group?(user, rollout)
@groups.any? do |g|
rollout.active_in_group?(g, user)
end
end
def serialize_data
return '' unless @data.is_a? Hash
@data.to_json
end
def users_from_string(raw_users)
users = (raw_users || '').split(',').map(&:to_s)
if @options[:use_sets]
users.to_set
else
users
end
end
def groups_from_string(raw_groups)
groups = (raw_groups || '').split(',').map(&:to_sym)
if @options[:use_sets]
groups.to_set
else
groups
end
end
end
end
|