Skip to content
This repository was archived by the owner on Dec 14, 2021. It is now read-only.

Commit be6a661

Browse files
committed
Merge branch 'develop'
2 parents 1b1c68b + 7180744 commit be6a661

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1499
-284
lines changed

.gitlab-ci.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ cache:
1616

1717
tests:
1818
stage: test
19-
image: golang:1.13
19+
image: golang:1.14
2020
services:
2121
- thethingsnetwork/rabbitmq
2222
- redis
@@ -27,10 +27,11 @@ tests:
2727
script:
2828
- make deps
2929
- make test
30+
retry: 2
3031

3132
binaries:
3233
stage: build
33-
image: golang:1.13
34+
image: golang:1.14
3435
script:
3536
- mkdir release
3637
- export CI_BUILD_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)
@@ -48,7 +49,7 @@ sign:
4849
- master@thethingsnetwork/ttn
4950
- develop@thethingsnetwork/ttn
5051
stage: sign
51-
image: golang:1.13
52+
image: golang:1.14
5253
script:
5354
- pushd release
5455
- shasum -a 256 $(ls) > checksums

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ services:
88
- docker
99

1010
go:
11-
- "1.13.x"
11+
- "1.14.x"
1212

1313
env:
1414
global:

api/go.mod

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
module github.com/TheThingsNetwork/ttn/api
22

3-
go 1.11
3+
go 1.14
44

55
replace github.com/TheThingsNetwork/ttn/utils/errors => ../utils/errors
66

77
require (
8-
github.com/StackExchange/wmi v0.0.0-20181212234831-e0a55b97c705 // indirect
9-
github.com/TheThingsNetwork/api v0.0.0-20190516085542-c732802571cf
8+
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
9+
github.com/TheThingsNetwork/api v0.0.0-20200324103623-039923721bb6
1010
github.com/TheThingsNetwork/go-utils v0.0.0-20190516083235-bdd4967fab4e
1111
github.com/TheThingsNetwork/ttn/utils/errors v0.0.0-20190516081709-034d40b328bd
12-
github.com/apex/log v1.1.0
12+
github.com/apex/log v1.1.2
1313
github.com/go-ole/go-ole v1.2.4 // indirect
14+
github.com/grpc-ecosystem/go-grpc-middleware v1.2.0
1415
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
1516
github.com/juju/ratelimit v1.0.1
16-
github.com/mwitkow/go-grpc-middleware v1.0.0
17-
github.com/shirou/gopsutil v2.18.12+incompatible
18-
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 // indirect
19-
github.com/smartystreets/assertions v0.0.0-20190401211740-f487f9de1cd3
20-
golang.org/x/net v0.0.0-20190514140710-3ec191127204
21-
google.golang.org/grpc v1.20.1
17+
github.com/prometheus/client_golang v1.5.1 // indirect
18+
github.com/shirou/gopsutil v2.20.2+incompatible
19+
github.com/smartystreets/assertions v1.0.1
20+
golang.org/x/net v0.0.0-20200320220750-118fecf932d8
21+
google.golang.org/grpc v1.28.0
2222
)

api/go.sum

Lines changed: 171 additions & 21 deletions
Large diffs are not rendered by default.

api/pool/pool.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ import (
1616
"github.com/TheThingsNetwork/go-utils/grpc/rpclog"
1717
"github.com/TheThingsNetwork/go-utils/roots"
1818
"github.com/TheThingsNetwork/ttn/utils/errors"
19-
"github.com/grpc-ecosystem/go-grpc-prometheus"
20-
"github.com/mwitkow/go-grpc-middleware"
19+
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
20+
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
2121
"google.golang.org/grpc"
2222
"google.golang.org/grpc/credentials"
23+
"google.golang.org/grpc/keepalive"
2324
)
2425

2526
// RootCAs to use in API connections
@@ -65,11 +66,6 @@ func (c *conn) dial(ctx context.Context, opts ...grpc.DialOption) {
6566
}()
6667
}
6768

68-
// KeepAliveDialer is a dialer that adds a 10 second TCP KeepAlive
69-
func KeepAliveDialer(addr string, timeout time.Duration) (net.Conn, error) {
70-
return (&net.Dialer{Timeout: timeout, KeepAlive: 10 * time.Second}).Dial("tcp", addr)
71-
}
72-
7369
// DefaultDialOptions for connecting with servers
7470
var DefaultDialOptions = []grpc.DialOption{
7571
grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(
@@ -83,8 +79,11 @@ var DefaultDialOptions = []grpc.DialOption{
8379
restartstream.Interceptor(restartstream.DefaultSettings),
8480
rpclog.StreamClientInterceptor(nil),
8581
)),
86-
grpc.WithDialer(KeepAliveDialer),
87-
grpc.WithBlock(),
82+
grpc.WithKeepaliveParams(keepalive.ClientParameters{
83+
Time: 5 * time.Minute,
84+
Timeout: 10 * time.Second,
85+
PermitWithoutStream: false,
86+
}),
8887
}
8988

9089
// Global pool with connections

core/broker/broker.go

Lines changed: 57 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ type Broker interface {
2929
HandleDownlink(downlink *pb.DownlinkMessage) error
3030
HandleActivation(activation *pb.DeviceActivationRequest) (*pb.DeviceActivationResponse, error)
3131

32-
ActivateRouter(id string) (<-chan *pb.DownlinkMessage, error)
33-
DeactivateRouter(id string) error
32+
ActivateRouterDownlink(id string) (<-chan *pb.DownlinkMessage, error)
33+
DeactivateRouterDownlink(id string) error
3434
ActivateHandlerUplink(id string) (<-chan *pb.DeduplicatedUplinkMessage, error)
3535
DeactivateHandlerUplink(id string) error
3636
}
3737

3838
func NewBroker(timeout time.Duration) Broker {
3939
return &broker{
40-
routers: make(map[string]chan *pb.DownlinkMessage),
40+
routers: make(map[string]*router),
4141
handlers: make(map[string]*handler),
4242
uplinkDeduplicator: NewDeduplicator(timeout),
4343
activationDeduplicator: NewDeduplicator(timeout),
@@ -52,7 +52,7 @@ func (b *broker) SetNetworkServer(addr, cert, token string) {
5252

5353
type broker struct {
5454
*component.Component
55-
routers map[string]chan *pb.DownlinkMessage
55+
routers map[string]*router
5656
routersLock sync.RWMutex
5757
handlers map[string]*handler
5858
handlersLock sync.RWMutex
@@ -141,41 +141,64 @@ func (b *broker) Init(c *component.Component) error {
141141

142142
func (b *broker) Shutdown() {}
143143

144-
func (b *broker) ActivateRouter(id string) (<-chan *pb.DownlinkMessage, error) {
144+
type router struct {
145+
downlinkConns int
146+
downlink chan *pb.DownlinkMessage
147+
sync.Mutex
148+
}
149+
150+
func (b *broker) getRouter(id string) *router {
145151
b.routersLock.Lock()
146152
defer b.routersLock.Unlock()
147153
if existing, ok := b.routers[id]; ok {
148-
return existing, errors.NewErrInternal(fmt.Sprintf("Router %s already active", id))
154+
return existing
155+
}
156+
b.routers[id] = new(router)
157+
return b.routers[id]
158+
}
159+
160+
func (b *broker) ActivateRouterDownlink(id string) (<-chan *pb.DownlinkMessage, error) {
161+
rtr := b.getRouter(id)
162+
rtr.Lock()
163+
defer rtr.Unlock()
164+
if rtr.downlink == nil {
165+
rtr.downlink = make(chan *pb.DownlinkMessage)
149166
}
150-
b.routers[id] = make(chan *pb.DownlinkMessage)
167+
rtr.downlinkConns++
151168
connectedRouters.Inc()
152-
return b.routers[id], nil
169+
return rtr.downlink, nil
153170
}
154171

155-
func (b *broker) DeactivateRouter(id string) error {
156-
b.routersLock.Lock()
157-
defer b.routersLock.Unlock()
158-
if channel, ok := b.routers[id]; ok {
159-
close(channel)
160-
delete(b.routers, id)
161-
connectedRouters.Dec()
162-
return nil
172+
func (b *broker) DeactivateRouterDownlink(id string) error {
173+
rtr := b.getRouter(id)
174+
rtr.Lock()
175+
defer rtr.Unlock()
176+
if rtr.downlinkConns == 0 {
177+
return errors.NewErrInternal(fmt.Sprintf("Router %s not active", id))
163178
}
164-
return errors.NewErrInternal(fmt.Sprintf("Router %s not active", id))
179+
connectedRouters.Dec()
180+
rtr.downlinkConns--
181+
if rtr.downlinkConns == 0 {
182+
close(rtr.downlink)
183+
rtr.downlink = nil
184+
}
185+
return nil
165186
}
166187

167-
func (b *broker) getRouter(id string) (chan<- *pb.DownlinkMessage, error) {
168-
b.routersLock.RLock()
169-
defer b.routersLock.RUnlock()
170-
if router, ok := b.routers[id]; ok {
171-
return router, nil
188+
func (b *broker) getRouterDownlink(id string) (chan<- *pb.DownlinkMessage, error) {
189+
rtr := b.getRouter(id)
190+
rtr.Lock()
191+
defer rtr.Unlock()
192+
if rtr.downlink == nil {
193+
return nil, errors.NewErrInternal(fmt.Sprintf("Router %s not active", id))
172194
}
173-
return nil, errors.NewErrInternal(fmt.Sprintf("Router %s not active", id))
195+
return rtr.downlink, nil
174196
}
175197

176198
type handler struct {
177-
conn *grpc.ClientConn
178-
uplink chan *pb.DeduplicatedUplinkMessage
199+
conn *grpc.ClientConn
200+
uplinkConns int
201+
uplink chan *pb.DeduplicatedUplinkMessage
179202
sync.Mutex
180203
}
181204

@@ -193,10 +216,10 @@ func (b *broker) ActivateHandlerUplink(id string) (<-chan *pb.DeduplicatedUplink
193216
hdl := b.getHandler(id)
194217
hdl.Lock()
195218
defer hdl.Unlock()
196-
if hdl.uplink != nil {
197-
return hdl.uplink, errors.NewErrInternal(fmt.Sprintf("Handler %s already active", id))
219+
if hdl.uplink == nil {
220+
hdl.uplink = make(chan *pb.DeduplicatedUplinkMessage)
198221
}
199-
hdl.uplink = make(chan *pb.DeduplicatedUplinkMessage)
222+
hdl.uplinkConns++
200223
connectedHandlers.Inc()
201224
return hdl.uplink, nil
202225
}
@@ -205,12 +228,15 @@ func (b *broker) DeactivateHandlerUplink(id string) error {
205228
hdl := b.getHandler(id)
206229
hdl.Lock()
207230
defer hdl.Unlock()
208-
if hdl.uplink == nil {
231+
if hdl.uplinkConns == 0 {
209232
return errors.NewErrInternal(fmt.Sprintf("Handler %s not active", id))
210233
}
211-
close(hdl.uplink)
212-
hdl.uplink = nil
213234
connectedHandlers.Dec()
235+
hdl.uplinkConns--
236+
if hdl.uplinkConns == 0 {
237+
close(hdl.uplink)
238+
hdl.uplink = nil
239+
}
214240
return nil
215241
}
216242

core/broker/broker_test.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,18 +75,19 @@ func TestActivateDeactivateRouter(t *testing.T) {
7575
a := New(t)
7676

7777
b := &broker{
78-
routers: make(map[string]chan *pb.DownlinkMessage),
78+
routers: make(map[string]*router),
7979
}
8080

81-
err := b.DeactivateRouter("RouterID")
81+
err := b.DeactivateRouterDownlink("RouterID")
8282
a.So(err, ShouldNotBeNil)
8383

84-
ch, err := b.ActivateRouter("RouterID")
84+
ch, err := b.ActivateRouterDownlink("RouterID")
8585
a.So(err, ShouldBeNil)
8686
a.So(ch, ShouldNotBeNil)
8787

88-
_, err = b.ActivateRouter("RouterID")
89-
a.So(err, ShouldNotBeNil)
88+
otherCH, err := b.ActivateRouterDownlink("RouterID")
89+
a.So(err, ShouldBeNil)
90+
a.So(otherCH, ShouldEqual, ch)
9091

9192
var wg sync.WaitGroup
9293
wg.Add(1)
@@ -96,7 +97,10 @@ func TestActivateDeactivateRouter(t *testing.T) {
9697
wg.Done()
9798
}()
9899

99-
err = b.DeactivateRouter("RouterID")
100+
err = b.DeactivateRouterDownlink("RouterID")
101+
a.So(err, ShouldBeNil)
102+
103+
err = b.DeactivateRouterDownlink("RouterID")
100104
a.So(err, ShouldBeNil)
101105

102106
wg.Wait()
@@ -116,8 +120,9 @@ func TestActivateDeactivateHandler(t *testing.T) {
116120
a.So(err, ShouldBeNil)
117121
a.So(ch, ShouldNotBeNil)
118122

119-
_, err = b.ActivateHandlerUplink("HandlerID")
120-
a.So(err, ShouldNotBeNil)
123+
otherCH, err := b.ActivateHandlerUplink("HandlerID")
124+
a.So(err, ShouldBeNil)
125+
a.So(otherCH, ShouldEqual, ch)
121126

122127
var wg sync.WaitGroup
123128
wg.Add(1)
@@ -130,5 +135,8 @@ func TestActivateDeactivateHandler(t *testing.T) {
130135
err = b.DeactivateHandlerUplink("HandlerID")
131136
a.So(err, ShouldBeNil)
132137

138+
err = b.DeactivateHandlerUplink("HandlerID")
139+
a.So(err, ShouldBeNil)
140+
133141
wg.Wait()
134142
}

core/broker/downlink.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func (b *broker) HandleDownlink(downlink *pb.DownlinkMessage) error {
5555
}
5656
ctx = ctx.WithField("RouterID", routerID)
5757

58-
router, err := b.getRouter(routerID)
58+
router, err := b.getRouterDownlink(routerID)
5959
if err != nil {
6060
return err
6161
}

core/broker/downlink_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ func TestDownlink(t *testing.T) {
2828
Monitor: monitorclient.NewMonitorClient(),
2929
},
3030
ns: &mockNetworkServer{},
31-
routers: map[string]chan *pb.DownlinkMessage{
32-
"routerID": dlch,
31+
routers: map[string]*router{
32+
"routerID": &router{downlinkConns: 1, downlink: dlch},
3333
},
3434
}
3535
b.InitStatus()

core/broker/server.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ func (b *brokerRPC) associateRouter(md metadata.MD) (chan *pb.UplinkMessage, <-c
3030
if err != nil {
3131
return nil, nil, nil, err
3232
}
33-
down, err := b.broker.ActivateRouter(router.ID)
33+
down, err := b.broker.ActivateRouterDownlink(router.ID)
3434
if err != nil {
3535
return nil, nil, nil, err
3636
}
3737

3838
up := make(chan *pb.UplinkMessage, 1)
3939

4040
cancel := func() {
41-
b.broker.DeactivateRouter(router.ID)
41+
b.broker.DeactivateRouterDownlink(router.ID)
4242
}
4343

4444
go func() {

core/broker/uplink_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ func TestDeduplicateUplink(t *testing.T) {
161161
uplink4 := &pb.UplinkMessage{Payload: payload, GatewayMetadata: gateway.RxMetadata{SNR: 7.8}, ProtocolMetadata: protocolMetadata}
162162

163163
b := getTestBroker(t)
164-
b.uplinkDeduplicator = NewDeduplicator(20 * time.Millisecond).(*deduplicator)
164+
b.uplinkDeduplicator = NewDeduplicator(200 * time.Millisecond).(*deduplicator)
165165

166166
var wg sync.WaitGroup
167167
wg.Add(1)
@@ -172,12 +172,12 @@ func TestDeduplicateUplink(t *testing.T) {
172172
wg.Done()
173173
}()
174174

175-
<-time.After(10 * time.Millisecond)
175+
<-time.After(100 * time.Millisecond)
176176

177177
a.So(b.deduplicateUplink(uplink2), ShouldBeNil)
178178
a.So(b.deduplicateUplink(uplink3), ShouldBeNil)
179179

180-
<-time.After(50 * time.Millisecond)
180+
<-time.After(500 * time.Millisecond)
181181

182182
a.So(b.deduplicateUplink(uplink4), ShouldNotBeNil)
183183

0 commit comments

Comments
 (0)