-
Notifications
You must be signed in to change notification settings - Fork 50
/
router.go
104 lines (88 loc) · 2.01 KB
/
router.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
package proxy
import (
"log"
"net/http"
"sort"
"strings"
"sync"
)
type routerItem struct {
APIName string
BindPath string
Hander http.HandlerFunc
}
func newRouterItem(apiName string, bindPath string, hander http.HandlerFunc) *routerItem {
return &routerItem{
APIName: apiName,
BindPath: bindPath,
Hander: hander,
}
}
type routers struct {
BindMap map[string]*routerItem
BindPaths bindPathsStruct
rw sync.RWMutex
}
func newRouters() *routers {
return &routers{
BindMap: make(map[string]*routerItem),
BindPaths: make(bindPathsStruct, 0),
}
}
type bindPathsStruct []string
// Len len
func (bs bindPathsStruct) Len() int {
return len(bs)
}
// Less sort func
func (bs bindPathsStruct) Less(i, j int) bool {
return len(bs[i]) > len(bs[j])
}
func (bs bindPathsStruct) Swap(i, j int) {
bs[i], bs[j] = bs[j], bs[i]
}
func (rs *routers) String() string {
return strings.Join(rs.BindPaths, ",")
}
func (rs *routers) getRouterByReqPath(urlPath string) *routerItem {
rs.rw.RLock()
defer rs.rw.RUnlock()
for _, bindPath := range rs.BindPaths {
if bindPath != "" && strings.HasPrefix(urlPath, bindPath) {
return rs.BindMap[bindPath]
}
}
return nil
}
// Sort by name
func (rs *routers) Sort() {
rs.rw.Lock()
defer rs.rw.Unlock()
bindPaths := make(bindPathsStruct, 0, len(rs.BindMap))
for bindPath := range rs.BindMap {
bindPaths = append(bindPaths, bindPath)
}
sort.Sort(bindPaths)
rs.BindPaths = bindPaths
log.Println("routers_bind_path:", rs.String())
}
func (rs *routers) deleteRouterByPath(bindPath string) {
func() {
rs.rw.Lock()
defer rs.rw.Unlock()
if router, has := rs.BindMap[bindPath]; has {
log.Println("unbind router,apiName=", router.APIName, "bindPath=", bindPath)
delete(rs.BindMap, bindPath)
}
}()
rs.Sort()
}
func (rs *routers) bindRouter(bindPath string, router *routerItem) {
func() {
rs.rw.Lock()
defer rs.rw.Unlock()
rs.BindMap[bindPath] = router
log.Println("bind router,apiName=", router.APIName, "bindPath=", bindPath)
}()
rs.Sort()
}