-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathserver.go
More file actions
110 lines (102 loc) · 3.14 KB
/
server.go
File metadata and controls
110 lines (102 loc) · 3.14 KB
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
package server
import (
"github.com/garyburd/redigo/redis"
"github.com/microbay/server/backends"
"github.com/microbay/server/core"
"github.com/microbay/server/plugin"
//"github.com/fvbock/endless" ----> Hot reloads
log "github.com/Sirupsen/logrus"
"github.com/gocraft/web"
"github.com/spf13/viper"
"net/http"
)
var Config API
var redisPool *redis.Pool
// Creates Root and resources routes and starts listening
func Start() {
log.Debug("server::Start")
Config = loadConfig()
redisPool = connectRedis()
defer redisPool.Close()
bootstrapRoutes(Config.Resources)
bootstrapLoadBalancer(Config.Resources)
bootstrapPlugins(Config.Resources)
rootRouter := web.New(Context{}).
Middleware((*Context).LoggerMiddleware).
Middleware(web.ShowErrorsMiddleware).
Middleware((*Context).RedisMiddleware).
Middleware((*Context).ConfigMiddleware).
Middleware((*Context).RootMiddleware).
Middleware((*Context).ResourceConfigMiddleware).
Middleware((*Context).PluginMiddleware).
Middleware((*Context).BalancedProxy)
log.Info(Config.Name, " listening on ", viper.GetString("host"), " in ", viper.Get("env"), " mode")
err := http.ListenAndServe(viper.GetString("host"), rootRouter)
if err != nil {
log.Fatal("Failed to start server ", err)
}
}
func connectRedis() *redis.Pool {
log.Debug("server::connectRedis")
return &redis.Pool{
MaxIdle: 80,
MaxActive: 12000, // max number of connections
Dial: func() (redis.Conn, error) {
c, err := redis.Dial("tcp", viper.GetString("redis_host"))
if err != nil {
log.Fatal(err.Error())
}
return c, err
},
}
}
func bootstrapRoutes(resources []*Resource) {
log.Debug("server::bootstrapRoutes")
for _, resource := range resources {
regex, keys := core.PathToRegex(resource.Path)
resource.Regex = regex
resource.Keys = keys
}
}
func bootstrapPlugins(resources []*Resource) {
log.Debug("server::bootstrapPlugins")
for i := 0; i < len(resources); i++ {
activePlugins := resources[i].Plugins
plugins := make([]plugin.Interface, 0)
for j := 0; j < len(activePlugins); j++ {
n := activePlugins[j]
if _, ok := n["id"]; ok != true {
log.Fatal("Plugin configs need and id")
}
if p, err := plugin.New(n["id"].(string)); err != nil {
log.Fatal(activePlugins[j], " plugin failed to bootstrap: ", err)
} else {
n["path"] = resources[i].Path
if rp, err := p.Bootstrap(&plugin.Config{redisPool, n}); err != nil {
log.Fatal(err)
} else {
plugins = append(plugins, rp)
}
}
}
resources[i].Middleware = plugins
}
}
// Creates linked list (golang Ring) from weighted micros array per resource
func bootstrapLoadBalancer(resources []*Resource) {
log.Debug("server::bootstrapLoadBalancer")
for i := 0; i < len(resources); i++ {
resources[i].Backends = make(map[string]backends.Backends)
for batchKey := range resources[i].Micros {
micros := resources[i].Micros[batchKey]
flattenedMicros := make([]string, 0)
for j := 0; j < len(micros); j++ {
for n := 0; n < micros[j].Weight; n++ {
flattenedMicros = append(flattenedMicros, micros[j].URL)
}
}
h := backends.Build("round-robin", flattenedMicros)
resources[i].Backends[batchKey] = h
}
}
}