-
Notifications
You must be signed in to change notification settings - Fork 8
/
runner.go
64 lines (52 loc) · 1.96 KB
/
runner.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
package segmenters
import (
"encoding/json"
"fmt"
"strings"
"sync"
_segmenters "github.com/caraml-dev/xp/common/segmenters"
)
type Runner interface {
GetName() string
Transform(name string, requestValues map[string]interface{}, experimentVariables []string) ([]*_segmenters.SegmenterValue, error)
}
var runnersLock sync.Mutex
// Runners contain all the registered segmenter runners by name.
var Runners = make(map[string]Factory)
// Factory creates a segmenter runner from the provided config.
//
// Config is a raw encoded JSON value. The segmenter runner implementation
// for each segmenter should provide a schema and example
// of the JSON value to explain the usage.
type Factory func(config json.RawMessage) (Runner, error)
// Register a segmenter runner with the provided name and factory function.
//
// For registration to be properly recorded, Register function should be called in the init
// phase of the Go execution. The init function is usually defined in the package where
// the segmenter runner is implemented. The name of the segmenter runners should be unique
// across all implementations. Registering multiple segmenter runners with the
// same name will return an error.
func Register(name string, factory Factory) error {
runnersLock.Lock()
defer runnersLock.Unlock()
name = strings.ToLower(name)
if _, found := Runners[name]; found {
return fmt.Errorf("segmenter runner %q was registered twice", name)
}
Runners[name] = factory
return nil
}
// Get a segmenter runner that has been registered.
//
// The segmenter runner will be initialized using the registered factory function with the provided config.
// Retrieving a segmenter runner that is not yet registered will return an error.
func Get(name string, config json.RawMessage) (Runner, error) {
runnersLock.Lock()
defer runnersLock.Unlock()
name = strings.ToLower(name)
m, ok := Runners[name]
if !ok {
return nil, fmt.Errorf("no segmenter runner found for name %s", name)
}
return m(config)
}