5
5
"fmt"
6
6
"io"
7
7
"strings"
8
- "sync"
9
8
"time"
10
9
11
10
"github.com/cloudwebrtc/nats-discovery/pkg/discovery"
@@ -26,34 +25,32 @@ type NodeItem struct {
26
25
27
26
type Registry struct {
28
27
nc * nats.Conn
29
- sub * nats.Subscription
30
- nodes map [string ]* NodeItem
31
28
ctx context.Context
32
29
cancel context.CancelFunc
33
- mutex sync. Mutex
30
+ expire int64
34
31
}
35
32
36
33
func (s * Registry ) Close () {
37
34
s .cancel ()
38
- s .sub .Unsubscribe ()
39
35
}
40
36
41
37
// NewService create a service instance
42
- func NewRegistry (nc * nats.Conn ) (* Registry , error ) {
38
+ func NewRegistry (nc * nats.Conn , expire int64 ) (* Registry , error ) {
43
39
s := & Registry {
44
- nc : nc ,
45
- nodes : make (map [string ]* NodeItem ),
40
+ nc : nc ,
41
+ expire : expire ,
42
+ }
43
+
44
+ if s .expire <= 0 {
45
+ s .expire = discovery .DefaultExpire
46
46
}
47
47
48
48
s .ctx , s .cancel = context .WithCancel (context .Background ())
49
49
return s , nil
50
50
}
51
51
52
- func (s * Registry ) checkExpires (now int64 , handleNodeAction func (action discovery.Action , node discovery.Node ) (bool , error )) error {
53
- s .mutex .Lock ()
54
- defer s .mutex .Unlock ()
55
-
56
- for key , item := range s .nodes {
52
+ func (s * Registry ) checkExpires (nodes map [string ]* NodeItem , now int64 , handleNodeAction func (action discovery.Action , node discovery.Node ) (bool , error )) error {
53
+ for key , item := range nodes {
57
54
if item .expire <= now {
58
55
discoverySubj := strings .ReplaceAll (item .subj , discovery .DefaultPublishPrefix , discovery .DefaultDiscoveryPrefix )
59
56
logger .Infof ("node.delete %v, %v" , discoverySubj , key )
@@ -70,50 +67,38 @@ func (s *Registry) checkExpires(now int64, handleNodeAction func(action discover
70
67
return nil
71
68
}
72
69
handleNodeAction (discovery .Delete , * item .node )
73
- delete (s . nodes , key )
70
+ delete (nodes , key )
74
71
}
75
72
}
76
73
return nil
77
74
}
78
75
79
- func (s * Registry ) GetNodes (service string ) ([]discovery.Node , error ) {
80
- s .mutex .Lock ()
81
- defer s .mutex .Unlock ()
82
- nodes := []discovery.Node {}
83
- for _ , item := range s .nodes {
84
- if item .node .Service == service || service == "*" {
85
- nodes = append (nodes , * item .node )
86
- }
87
- }
88
- return nodes , nil
89
- }
90
-
91
76
func (s * Registry ) Listen (
92
77
handleNodeAction func (action discovery.Action , node discovery.Node ) (bool , error ),
93
78
handleGetNodes func (service string , params map [string ]interface {}) ([]discovery.Node , error )) error {
94
- var err error
95
79
96
80
if handleNodeAction == nil || handleGetNodes == nil {
97
- err = fmt .Errorf ("Listen callback must be set for Registry.Listen" )
81
+ err : = fmt .Errorf ("Listen callback must be set for Registry.Listen" )
98
82
logger .Warnf ("Listen: err => %v" , err )
99
83
return err
100
84
}
101
85
102
86
subj := discovery .DefaultPublishPrefix + ".>"
103
87
msgCh := make (chan * nats.Msg )
104
88
105
- if s . sub , err = s .nc .Subscribe (subj , func (msg * nats.Msg ) {
89
+ sub , err : = s .nc .Subscribe (subj , func (msg * nats.Msg ) {
106
90
msgCh <- msg
107
- }); err != nil {
91
+ })
92
+
93
+ if err != nil {
108
94
return err
109
95
}
110
96
111
- logger .Infof ("Registry: listen prefix => %v" , subj )
97
+ logger .Infof ("Registry: listen subj prefix => %v" , subj )
112
98
113
- handleNatsMsg := func (msg * nats.Msg ) error {
114
- s .mutex .Lock ()
115
- defer s .mutex .Unlock ()
99
+ nodes := make (map [string ]* NodeItem )
116
100
101
+ handleNatsMsg := func (msg * nats.Msg ) error {
117
102
logger .Debugf ("handle storage key: %v" , msg .Subject )
118
103
var req discovery.Request
119
104
err := util .Unmarshal (msg .Data , & req )
@@ -128,7 +113,7 @@ func (s *Registry) Listen(
128
113
}
129
114
switch req .Action {
130
115
case discovery .Save :
131
- if _ , ok := s . nodes [nid ]; ! ok {
116
+ if _ , ok := nodes [nid ]; ! ok {
132
117
logger .Infof ("node.save" )
133
118
// accept or reject
134
119
if ok , err := handleNodeAction (req .Action , req .Node ); ! ok {
@@ -141,16 +126,16 @@ func (s *Registry) Listen(
141
126
discoverySubj := strings .ReplaceAll (msg .Subject , discovery .DefaultPublishPrefix , discovery .DefaultDiscoveryPrefix )
142
127
s .nc .Publish (discoverySubj , msg .Data )
143
128
144
- s . nodes [nid ] = & NodeItem {
145
- expire : time .Now ().Unix () + discovery . DefaultExpire ,
129
+ nodes [nid ] = & NodeItem {
130
+ expire : time .Now ().Unix () + s . expire ,
146
131
node : & req .Node ,
147
132
subj : msg .Subject ,
148
133
}
149
134
}
150
135
case discovery .Update :
151
- if node , ok := s . nodes [nid ]; ok {
136
+ if node , ok := nodes [nid ]; ok {
152
137
logger .Debugf ("node.update" )
153
- node .expire = time .Now ().Unix () + discovery . DefaultExpire
138
+ node .expire = time .Now ().Unix () + s . expire
154
139
if ok , err := handleNodeAction (req .Action , req .Node ); ! ok {
155
140
logger .Errorf ("aciont %v, rejected %v" , req .Action , err )
156
141
resp .Success = false
@@ -166,14 +151,14 @@ func (s *Registry) Listen(
166
151
}
167
152
discoverySubj := strings .ReplaceAll (msg .Subject , discovery .DefaultPublishPrefix , discovery .DefaultDiscoveryPrefix )
168
153
s .nc .Publish (discoverySubj , msg .Data )
169
- s . nodes [nid ] = & NodeItem {
170
- expire : time .Now ().Unix () + discovery . DefaultExpire ,
154
+ nodes [nid ] = & NodeItem {
155
+ expire : time .Now ().Unix () + s . expire ,
171
156
node : & req .Node ,
172
157
subj : msg .Subject ,
173
158
}
174
159
}
175
160
case discovery .Delete :
176
- if _ , ok := s . nodes [nid ]; ok {
161
+ if _ , ok := nodes [nid ]; ok {
177
162
logger .Infof ("node.delete" )
178
163
if ok , err := handleNodeAction (req .Action , req .Node ); ! ok {
179
164
logger .Errorf ("aciont %v, rejected %v" , req .Action , err )
@@ -184,14 +169,12 @@ func (s *Registry) Listen(
184
169
discoverySubj := strings .ReplaceAll (msg .Subject , discovery .DefaultPublishPrefix , discovery .DefaultDiscoveryPrefix )
185
170
s .nc .Publish (discoverySubj , msg .Data )
186
171
}
187
- delete (s . nodes , nid )
172
+ delete (nodes , nid )
188
173
case discovery .Get :
189
174
resp := & discovery.GetResponse {}
190
- s .mutex .Unlock ()
191
175
if nodes , err := handleGetNodes (req .Service , req .Params ); err == nil {
192
176
resp .Nodes = nodes
193
177
}
194
- s .mutex .Lock ()
195
178
data , err := util .Marshal (resp )
196
179
if err != nil {
197
180
logger .Errorf ("%v" , err )
@@ -209,12 +192,18 @@ func (s *Registry) Listen(
209
192
logger .Errorf ("%v" , err )
210
193
return err
211
194
}
195
+
212
196
s .nc .Publish (msg .Reply , data )
213
197
return nil
214
198
}
215
199
216
200
go func () error {
217
- defer close (msgCh )
201
+
202
+ defer func () {
203
+ sub .Unsubscribe ()
204
+ close (msgCh )
205
+ }()
206
+
218
207
now := time .Now ().Unix ()
219
208
t := time .NewTicker (time .Second * 1 )
220
209
for {
@@ -223,7 +212,7 @@ func (s *Registry) Listen(
223
212
return s .ctx .Err ()
224
213
case <- t .C :
225
214
now ++
226
- if err := s .checkExpires (now , handleNodeAction ); err != nil {
215
+ if err := s .checkExpires (nodes , now , handleNodeAction ); err != nil {
227
216
logger .Warnf ("checkExpires err: %v" , err )
228
217
return err
229
218
}
0 commit comments