-
Notifications
You must be signed in to change notification settings - Fork 0
/
scorer.go
84 lines (72 loc) · 1.54 KB
/
scorer.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
package main
import (
"log"
"math"
"strconv"
lua "github.com/yuin/gopher-lua"
)
type Scorer interface {
Score() float64
}
type DefaultScorer struct {
S *Server
}
func (ds *DefaultScorer) Score() float64 {
ping := float64(ds.S.Stat.AverageLatency())
lost := ds.S.Stat.DropRate()
return math.Pow((1-lost), 50) / ping
}
func NewDefaultScorer(server *Server) *DefaultScorer {
return &DefaultScorer{
S: server,
}
}
type LuaScorer struct {
L *lua.LState
S *Server
}
func NewLuaScorer(server *Server, filename string) (*LuaScorer, error) {
ls := new(LuaScorer)
ls.S = server
ls.L = lua.NewState()
err := ls.L.DoFile(filename)
if err != nil {
return nil, err
}
latency := func(L *lua.LState) int {
L.Push(lua.LNumber(ls.S.Stat.AverageLatency() / 1000000))
return 1
}
droprate := func(L *lua.LState) int {
L.Push(lua.LNumber(ls.S.Stat.DropRate()))
return 1
}
address := func(L *lua.LState) int {
L.Push(lua.LString(ls.S.Address))
return 1
}
ls.L.SetGlobal("averagelatency", ls.L.NewFunction(latency))
ls.L.SetGlobal("droprate", ls.L.NewFunction(droprate))
ls.L.SetGlobal("address", ls.L.NewFunction(address))
return ls, err
}
func (ls *LuaScorer) Score() float64 {
err := ls.L.CallByParam(lua.P{
Fn: ls.L.GetGlobal("score"),
NRet: 1,
Protect: true,
})
if err != nil {
log.Fatal(err)
}
ret := ls.L.Get(-1)
ls.L.Pop(1)
if ret.Type() != lua.LTNumber {
log.Fatal("scorer return value should be a Number")
}
f, err := strconv.ParseFloat(ret.String(), 64)
if err != nil {
log.Fatal(err)
}
return f
}