-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathexperiment.go
113 lines (103 loc) · 3.64 KB
/
experiment.go
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
package growthbook
import "github.com/growthbook/growthbook-golang/internal/condition"
type ExperimentStatus string
const (
DraftStatus ExperimentStatus = "draft"
RunningStatus ExperimentStatus = "running"
StoppedStatus ExperimentStatus = "stopped"
)
// Experiment defines a single experiment.
type Experiment struct {
// The globally unique identifier for the experiment
Key string `json:"key"`
// The different variations to choose between
Variations []FeatureValue `json:"variations"`
// How to weight traffic between variations. Must add to 1.
Weights []float64 `json:"weights"`
// If set to false, always return the control (first variation)
Active *bool `json:"active"`
// What percent of users should be included in the experiment (between 0 and 1, inclusive)
Coverage *float64 `json:"coverage"`
// Array of ranges, one per variation
Ranges []BucketRange `json:"ranges"`
// Optional targeting condition
Condition condition.Base `json:"condition"`
// Each item defines a prerequisite where a condition must evaluate against a parent feature's value (identified by id).
ParentConditions []ParentCondition `json:"parentConditions"`
// Adds the experiment to a namespace
Namespace *Namespace `json:"namespace"`
// All users included in the experiment will be forced into the specific variation index
Force *int `json:"force"`
// What user attribute should be used to assign variations (defaults to id)
HashAttribute string `json:"hashAttribute"`
// When using sticky bucketing, can be used as a fallback to assign variations
FallbackAttribute string `json:"fallbackAttribute"`
// The hash version to use (default to 1)
HashVersion int `json:"hashVersion"`
// Meta info about the variations
Meta []VariationMeta `json:"meta"`
// Array of filters to apply
Filters []Filter `json:"filters"`
// The hash seed to use
Seed string `json:"seed"`
// Human-readable name for the experiment
Name string `json:"name"`
// Id of the current experiment phase
Phase string `json:"phase"`
// If true, sticky bucketing will be disabled for this experiment.
// (Note: sticky bucketing is only available if a StickyBucketingService is provided in the Context)
DisableStickyBucketing bool `json:"disableStickyBucketing"`
// An sticky bucket version number that can be used to force a re-bucketing of users (default to 0)
BucketVersion int `json:"bucketVersion"`
// Any users with a sticky bucket version less than this will be excluded from the experiment
MinBucketVersion int `json:"minBucketVersion"`
}
// NewExperiment creates an experiment with default settings: active,
// but all other fields empty.
func NewExperiment(key string) *Experiment {
return &Experiment{
Key: key,
}
}
func experimentFromFeatureRule(featureId string, rule *FeatureRule) *Experiment {
expKey := rule.Key
if expKey == "" {
expKey = featureId
}
exp := Experiment{
Key: expKey,
Variations: rule.Variations,
Coverage: rule.Coverage,
Weights: rule.Weights,
HashAttribute: rule.HashAttribute,
Namespace: rule.Namespace,
Meta: rule.Meta,
Ranges: rule.Ranges,
Name: rule.Name,
Phase: rule.Phase,
Seed: rule.Seed,
HashVersion: rule.HashVersion,
Filters: rule.Filters,
Condition: rule.Condition,
ParentConditions: rule.ParentConditions,
}
return &exp
}
func (e *Experiment) getCoverage() float64 {
if e.Coverage == nil {
return 1.0
}
return *e.Coverage
}
func (e *Experiment) getSeed() string {
if e.Seed == "" {
return e.Key
}
return e.Seed
}
func (e *Experiment) getActive() bool {
if e.Active == nil {
return true
}
return *e.Active
}