-
Notifications
You must be signed in to change notification settings - Fork 23
/
ensembler.go
123 lines (106 loc) · 5.09 KB
/
ensembler.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
114
115
116
117
118
119
120
121
122
123
package models
import (
"database/sql/driver"
"encoding/json"
)
// Ensembler contains the configuration for a post-processor for
// a Turing Router.
type Ensembler struct {
Model
Type EnsemblerType `json:"type" validate:"required"`
StandardConfig *EnsemblerStandardConfig `json:"standard_config"` // Ensembler config when Type is "standard"
DockerConfig *EnsemblerDockerConfig `json:"docker_config"` // Ensembler config when Type is "docker"
PyfuncConfig *EnsemblerPyfuncConfig `json:"pyfunc_config"` // Ensembler config when Type is "pyfunc"
}
// TableName returns the name of a table, where GORM should store/retrieve
// entities of this type. By default GORM uses the table name, that is
// a plural form of the type's name (i.e `Ensembler` -> `ensemblers`),
// and by implementing `TableName` method it is possible to override it.
func (*Ensembler) TableName() string {
return "ensembler_configs"
}
type EnsemblerType string
const (
EnsemblerStandardType EnsemblerType = "standard"
EnsemblerDockerType EnsemblerType = "docker"
EnsemblerPyFuncType EnsemblerType = "pyfunc"
)
type EnsemblerStandardConfig struct {
// LazyRouting dictates whether the routes should be called lazily, based on the results
// of the experiment engine. If true, the experiment engine will be called first and only
// the selected route will be invoked - this is more cost efficient. If false, the routing
// will be executed in parallel with the call to the experiment engine and therefore, faster
// e2e execution time.
LazyRouting bool `json:"lazy_routing"`
ExperimentMappings []ExperimentMapping `json:"experiment_mappings" validate:"dive"`
RouteNamePath string `json:"route_name_path"`
}
type EnsemblerDockerConfig struct {
Image string `json:"image" validate:"required"`
// Resource requests for ensembler container deployed
ResourceRequest *ResourceRequest `json:"resource_request" validate:"required"`
// Autoscaling policy for the ensembler
AutoscalingPolicy *AutoscalingPolicy `json:"autoscaling_policy" validate:"omitempty,dive"`
// URL path for the endpoint, e.g "/"
Endpoint string `json:"endpoint" validate:"required"`
// Request timeout in duration format e.g. 60s
Timeout string `json:"timeout" validate:"required"`
// Port number the container listens to for requests
Port int `json:"port" validate:"required"`
// Environment variables to set in the container
Env EnvVars `json:"env" validate:"required"`
// secret name in MLP containing service account key
ServiceAccount string `json:"service_account"`
}
type EnsemblerPyfuncConfig struct {
ProjectID *ID `json:"project_id" validate:"required"`
EnsemblerID *ID `json:"ensembler_id" validate:"required"`
// Resource requests for ensembler container deployed
ResourceRequest *ResourceRequest `json:"resource_request" validate:"required"`
// Autoscaling policy for the ensembler
AutoscalingPolicy *AutoscalingPolicy `json:"autoscaling_policy" validate:"omitempty,dive"`
// Request timeout in duration format e.g. 60s
Timeout string `json:"timeout" validate:"required"`
// Environment variables to set in the container
Env EnvVars `json:"env" validate:"required"`
}
type ExperimentMapping struct {
Experiment string `json:"experiment" validate:"required"` // Experiment name from the experiment engine
Treatment string `json:"treatment" validate:"required"` // Treatment name for the experiment
Route string `json:"route" validate:"required"` // Route ID to select for the experiment treatment
}
type EnsemblerRunnerType string
const (
EnsemblerRunnerTypeJob EnsemblerRunnerType = "job"
EnsemblerRunnerTypeService EnsemblerRunnerType = "service"
)
// Value implements sql.driver.Valuer interface so database tools like go-orm knows how to serialize the struct object
// for storage in the database
func (c EnsemblerStandardConfig) Value() (driver.Value, error) {
return json.Marshal(c)
}
// Scan implements sql.Scanner interface so database tools like go-orm knows how to de-serialize the struct object
// from the database
func (c *EnsemblerStandardConfig) Scan(value interface{}) error {
return json.Unmarshal(value.([]byte), &c)
}
// Value implements sql.driver.Valuer interface so database tools like go-orm knows how to serialize the struct object
// for storage in the database
func (c EnsemblerDockerConfig) Value() (driver.Value, error) {
return json.Marshal(c)
}
// Scan implements sql.Scanner interface so database tools like go-orm knows how to de-serialize the struct object
// from the database
func (c *EnsemblerDockerConfig) Scan(value interface{}) error {
return json.Unmarshal(value.([]byte), &c)
}
// Value implements sql.driver.Valuer interface so database tools like go-orm knows how to serialize the struct object
// for storage in the database
func (c EnsemblerPyfuncConfig) Value() (driver.Value, error) {
return json.Marshal(c)
}
// Scan implements sql.Scanner interface so database tools like go-orm knows how to de-serialize the struct object
// from the database
func (c *EnsemblerPyfuncConfig) Scan(value interface{}) error {
return json.Unmarshal(value.([]byte), &c)
}