-
Notifications
You must be signed in to change notification settings - Fork 1
/
rpc.go
99 lines (85 loc) · 1.86 KB
/
rpc.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
package api
import (
"container/list"
log "github.com/sirupsen/logrus"
"net"
"net/rpc"
"sync"
"time"
"github.com/fwtpe/owl-backend/modules/graph/g"
)
type conn_list struct {
sync.RWMutex
list *list.List
}
func (l *conn_list) insert(c net.Conn) *list.Element {
l.Lock()
defer l.Unlock()
return l.list.PushBack(c)
}
func (l *conn_list) remove(e *list.Element) net.Conn {
l.Lock()
defer l.Unlock()
return l.list.Remove(e).(net.Conn)
}
var Close_chan, Close_done_chan chan int
var connects conn_list
func init() {
Close_chan = make(chan int, 1)
Close_done_chan = make(chan int, 1)
connects = conn_list{list: list.New()}
}
func Start() {
if !g.Config().Rpc.Enabled {
log.Println("rpc.Start warning, not enabled")
return
}
addr := g.Config().Rpc.Listen
tcpAddr, err := net.ResolveTCPAddr("tcp", addr)
if err != nil {
log.Fatalf("rpc.Start error, net.ResolveTCPAddr failed, %s", err)
}
listener, err := net.ListenTCP("tcp", tcpAddr)
if err != nil {
log.Fatalf("rpc.Start error, listen %s failed, %s", addr, err)
} else {
log.Println("rpc.Start ok, listening on", addr)
}
rpc.Register(new(Graph))
go func() {
var tempDelay time.Duration // how long to sleep on accept failure
for {
conn, err := listener.Accept()
if err != nil {
if tempDelay == 0 {
tempDelay = 5 * time.Millisecond
} else {
tempDelay *= 2
}
if max := 1 * time.Second; tempDelay > max {
tempDelay = max
}
time.Sleep(tempDelay)
continue
}
tempDelay = 0
go func() {
e := connects.insert(conn)
defer connects.remove(e)
rpc.ServeConn(conn)
}()
}
}()
select {
case <-Close_chan:
log.Println("rpc, recv sigout and exiting...")
listener.Close()
Close_done_chan <- 1
connects.Lock()
for e := connects.list.Front(); e != nil; e = e.Next() {
e.Value.(net.Conn).Close()
}
connects.Unlock()
return
}
}