Skip to content

Commit def35fe

Browse files
authored
fix: Handle empty actions list and high-score tiebreaking (#59)
* empty actions handling and high score tiebreaking * bump version
1 parent 60f89bf commit def35fe

File tree

4 files changed

+10
-21
lines changed

4 files changed

+10
-21
lines changed

eppoclient/client.go

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -103,26 +103,21 @@ type BanditResult struct {
103103
func (ec *EppoClient) GetBanditAction(flagKey string, subjectKey string, subjectAttributes ContextAttributes, actions map[string]ContextAttributes, defaultVariation string) BanditResult {
104104
config := ec.configurationStore.getConfiguration()
105105

106-
isBanditFlag := config.isBanditFlag(flagKey)
107-
108-
if isBanditFlag && len(actions) == 0 {
109-
// No actions passed for a flag known to have an
110-
// active bandit, so we just return the default values
111-
// so that we don't log a variation or bandit
112-
// assignment.
113-
return BanditResult{
114-
Variation: defaultVariation,
115-
Action: nil,
116-
}
117-
}
118-
119106
// ignoring the error here as we can always proceed with default variation
120107
assignmentValue, _ := ec.getAssignment(config, flagKey, subjectKey, subjectAttributes.toGenericAttributes(), stringVariation)
121108
variation, ok := assignmentValue.(string)
122109
if !ok {
123110
variation = defaultVariation
124111
}
125112

113+
// If no acctions have been passed, we will return the variation, even if it is a bandit key
114+
if len(actions) == 0 {
115+
return BanditResult{
116+
Variation: variation,
117+
Action: nil,
118+
}
119+
}
120+
126121
banditVariation, ok := config.getBanditVariant(flagKey, variation)
127122
if !ok {
128123
return BanditResult{

eppoclient/configurationstore.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,6 @@ func (c *configuration) refreshBanditFlagAssociations() {
3131
c.banditFlagAssociations = associations
3232
}
3333

34-
// Return `true` if `flagKey` has associated bandits.
35-
func (c configuration) isBanditFlag(flagKey string) bool {
36-
_, ok := c.banditFlagAssociations[flagKey]
37-
return ok
38-
}
39-
4034
func (c configuration) getBanditVariant(flagKey, variation string) (result banditVariation, ok bool) {
4135
byVariation, ok := c.banditFlagAssociations[flagKey]
4236
if !ok {

eppoclient/evalbandits.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ func (model *banditModelData) evaluate(ctx banditEvaluationContext) banditEvalua
103103

104104
bestAction, bestScore := "", math.Inf(-1)
105105
for actionKey, score := range scores {
106-
if score > bestScore {
106+
if score > bestScore || (score == bestScore && actionKey < bestAction) {
107107
bestAction, bestScore = actionKey, score
108108
}
109109
}

eppoclient/initclient.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ package eppoclient
44

55
import "net/http"
66

7-
var __version__ = "5.1.0"
7+
var __version__ = "5.1.1"
88

99
// InitClient is required to start polling of experiments configurations and create
1010
// an instance of EppoClient, which could be used to get assignments information.

0 commit comments

Comments
 (0)