forked from davyxu/cellnet
/
primitive.go
131 lines (92 loc) · 2.14 KB
/
primitive.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
124
125
126
127
128
129
130
131
package cellnet
import (
"log"
"sync"
)
var (
// Cell实例管理
cellMapGuard sync.RWMutex
cellMap map[CellID]*cell = make(map[CellID]*cell)
// CellID生成器
indexAccGuard sync.RWMutex
indexAcc int32
)
func genID() CellID {
indexAccGuard.Lock()
defer indexAccGuard.Unlock()
// TODO 处理翻越case
indexAcc++
return NewCellID(RegionID, indexAcc)
}
func findCell(id CellID) *cell {
cellMapGuard.RLock()
defer cellMapGuard.RUnlock()
if v, ok := cellMap[id]; ok {
return v
}
return nil
}
// CellID是否为本进程内的ID
func IsLocal(id CellID) bool {
return id.Region() == RegionID
}
// 为消息处理函数生成一个Cell, 返回CellID
func Spawn(callback func(CellID, interface{})) CellID {
id := genID()
if config.CellLog {
log.Println("[cellnet] #spawn", id.String(), GetStackInfoString(2))
}
c := &cell{
mailbox: make(chan interface{}, 8),
id: id,
}
cellMapGuard.Lock()
cellMap[id] = c
cellMapGuard.Unlock()
go func() {
for {
if data, ok := c.fetch(); ok {
callback(id, data)
} else {
break
}
}
}()
c.post(EventInit{})
return id
}
// 将制定内容发送到target的Cell中
func Send(target CellID, data interface{}) bool {
if target == 0 {
return false
}
if IsLocal(target) {
return SendLocal(target, data)
}
if expressDriver == nil {
log.Println("[cellnet] express func nil, target not send", target.String())
return false
}
if !expressDriver(target, data) {
log.Println("[cellnet] extern target not found: ", target.String())
return false
}
return true
}
// 将制定内容发送到本地的target的Cell中
func SendLocal(target CellID, data interface{}) bool {
if c := findCell(target); c != nil {
if config.CellLog {
log.Printf("[cellnet] #send %v %v %v", target.String(), ReflectContent(data), GetStackInfoString(2))
}
c.post(data)
return true
}
log.Println("[cellnet] target not found: ", target.String())
return false
}
var expressDriver func(CellID, interface{}) bool
// 设置快递驱动, 负责将给定内容跨进程送达
func SetExpressDriver(driver func(CellID, interface{}) bool) {
expressDriver = driver
}