rollout.Create   A
last analyzed

Complexity

Conditions 3

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 6
nop 1
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 3
rs 10
c 0
b 0
f 0
1
package rollout
2
3
import "hash/crc32"
4
import "math"
5
import "sort"
6
7
// Feature struct keeps the main information of a feature as:
8
// identification, the percentage of users that will be affected and status
9
type Feature struct {
10
	Name       string
11
	Percentage float64
12
	Active     bool
13
	Whitelist  []string
14
}
15
16
// Rollout component struct
17
type Rollout struct {
18
	features map[string]Feature
19
}
20
21
// IsActive will check if a given user is active for a feature
22
func (r Rollout) IsActive(feature string, id string) bool {
23 1
	f, ok := r.features[feature]
24 1
	crc32q := crc32.MakeTable(0xEDB88320)
25 1
	crc32 := crc32.Checksum([]byte(id), crc32q)
26 1
	return checkWhitelist(f, id) || (ok && f.Percentage > math.Mod(float64(crc32), 100))
27
}
28
29
// IsFeatureActive checks if a feature is active
30
func (r Rollout) IsFeatureActive(feature string) bool {
31 1
	f, ok := r.features[feature]
32 1
	return ok && f.Active
33
}
34
35
// Activate active a feature
36
// if the feature does not exists the action is ignored
37
func (r *Rollout) Activate(feature string) {
38 1
	f, ok := r.features[feature]
39 1
	if ok {
40 1
		f.Active = true
41 1
		r.Set(f)
42
	}
43
}
44
45
// Deactivate deactivate a feature
46
// if the feature does not exists the action is ignored
47
func (r *Rollout) Deactivate(feature string) {
48 1
	f, ok := r.features[feature]
49 1
	if ok {
50 1
		f.Active = false
51 1
		r.Set(f)
52
	}
53
}
54
55
// Set upsert a feature inside rollout component
56
func (r *Rollout) Set(feature Feature) {
57 1
	r.features[feature.Name] = feature
58
}
59
60
// Create is function used to create a new Rollout
61
func Create(features []Feature) *Rollout {
62 1
	r := Rollout{}
63 1
	r.features = make(map[string]Feature)
64 1
	for _, v := range features {
65 1
		r.features[v.Name] = v
66
	}
67 1
	return &r
68
}
69
70
// Get a feature by name
71
func (r Rollout) Get(feature string) (Feature, bool) {
72 1
	f, ok := r.features[feature]
73 1
	return f, ok
74
}
75
76
// GetAll get all features
77
func (r Rollout) GetAll() []Feature {
78 1
	var features []Feature
79 1
	for _, el := range r.features {
80 1
		features = append(features, el)
81
	}
82 1
	sort.Slice(features, func(i, j int) bool { return features[i].Name < features[j].Name })
83 1
	return features
84
}
85
86
func checkWhitelist(feature Feature, id string) bool {
87 1
	for _, el := range feature.Whitelist {
88 1
		if el == id {
89 1
			return true
90
		}
91
	}
92 1
	return false
93
}
94