Welcome to mirror list, hosted at ThFree Co, Russian Federation.

rollout.go « rollout « internal - gitlab.com/gitlab-org/gitlab-pages.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: ec592c3874e8137b916136267625aca389732e30 (plain)
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
package rollout

import (
	"errors"
	"hash/fnv"
	"math/rand"
)

// Rollout returns true and no error when during this run something should
// happen for given actor according to the stickiness and likelyhood passed
// as a percentage value to this function. It returns false rollout and an
// error if the percentage value is negative or higher than 100.
func Rollout(actor string, percentage int, stickiness string) (bool, error) {
	if percentage < 0 || percentage > 100 {
		return false, errors.New("Rollout value should be between 0 and 100 inclusive")
	}

	if percentage == 0 {
		return false, nil
	}

	if percentage == 100 {
		return true, nil
	}

	switch stickiness {
	case "random":
		return random(percentage), nil
	default:
		return forActor(actor, percentage), nil
	}
}

// random guarantees no stickiness. For every call it will yield a random
// true/false based on the provided rollout percentage.
func random(percentage int) bool {
	return rand.Intn(100) < percentage
}

// forActor provides "stickines", i.e. guarantees that the same actor
// gets the same result every time. It also assures that an actor which is
// among the first 10% will also be among the first 20%.
func forActor(actor string, percentage int) bool {
	h := fnv.New32a()
	h.Write([]byte(actor))
	sum32 := h.Sum32()

	if sum32 == 0 {
		return false
	}

	return (sum32 % uint32(100)) < uint32(percentage)
}