Skip to content

Commit ff8b3e4

Browse files
committed
[FAB-2206]Make gossip discovery configurable
Change-Id: I98977440727e9ab8108fe94b3a1c0659e539ae85 Signed-off-by: grapebaba <[email protected]>
1 parent 351f1b8 commit ff8b3e4

File tree

4 files changed

+96
-31
lines changed

4 files changed

+96
-31
lines changed

gossip/discovery/discovery_impl.go

+37-18
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,22 @@ import (
2727
"github.com/hyperledger/fabric/gossip/util"
2828
proto "github.com/hyperledger/fabric/protos/gossip"
2929
"github.com/op/go-logging"
30+
"github.com/spf13/viper"
3031
)
3132

3233
const defaultHelloInterval = time.Duration(5) * time.Second
3334

34-
var aliveTimeInterval = defaultHelloInterval
35-
var aliveExpirationTimeout = 5 * aliveTimeInterval
36-
var aliveExpirationCheckInterval = time.Duration(aliveExpirationTimeout / 10)
37-
var reconnectInterval = aliveExpirationTimeout
35+
var aliveExpirationCheckInterval time.Duration
3836

39-
// SetAliveTimeInternal sets the alive time interval
40-
func SetAliveTimeInternal(interval time.Duration) {
41-
aliveTimeInterval = interval
37+
// SetAliveTimeInterval sets the alive time interval
38+
func SetAliveTimeInterval(interval time.Duration) {
39+
viper.Set("peer.gossip.aliveTimeInterval", interval)
4240
}
4341

44-
// SetExpirationTimeout sets the expiration timeout
45-
func SetExpirationTimeout(timeout time.Duration) {
46-
aliveExpirationTimeout = timeout
42+
// SetAliveExpirationTimeout sets the expiration timeout
43+
func SetAliveExpirationTimeout(timeout time.Duration) {
44+
viper.Set("peer.gossip.aliveExpirationTimeout", timeout)
45+
aliveExpirationCheckInterval = time.Duration(timeout / 10)
4746
}
4847

4948
// SetAliveExpirationCheckInterval sets the expiration check interval
@@ -53,7 +52,7 @@ func SetAliveExpirationCheckInterval(interval time.Duration) {
5352

5453
// SetReconnectInterval sets the reconnect interval
5554
func SetReconnectInterval(interval time.Duration) {
56-
reconnectInterval = interval
55+
viper.Set("peer.gossip.reconnectInterval", interval)
5756
}
5857

5958
type timestamp struct {
@@ -177,7 +176,7 @@ func (d *gossipDiscoveryImpl) connect2BootstrapPeers(endpoints []string) {
177176
}(endpoint)
178177
}
179178
wg.Wait()
180-
time.Sleep(reconnectInterval)
179+
time.Sleep(getReconnectInterval())
181180
}
182181
}
183182

@@ -482,8 +481,8 @@ func (d *gossipDiscoveryImpl) periodicalReconnectToDead() {
482481
}
483482

484483
wg.Wait()
485-
d.logger.Debug("Sleeping", reconnectInterval)
486-
time.Sleep(reconnectInterval)
484+
d.logger.Debug("Sleeping", getReconnectInterval())
485+
time.Sleep(getReconnectInterval())
487486
}
488487
}
489488

@@ -531,7 +530,7 @@ func (d *gossipDiscoveryImpl) periodicalCheckAlive() {
531530
defer d.logger.Debug("Stopped")
532531

533532
for !d.toDie() {
534-
time.Sleep(aliveExpirationCheckInterval)
533+
time.Sleep(getAliveExpirationCheckInterval())
535534
dead := d.getDeadMembers()
536535
if len(dead) > 0 {
537536
d.logger.Debugf("Got %v dead members: %v", len(dead), dead)
@@ -581,7 +580,7 @@ func (d *gossipDiscoveryImpl) getDeadMembers() []common.PKIidType {
581580
dead := []common.PKIidType{}
582581
for id, last := range d.aliveLastTS {
583582
elapsedNonAliveTime := time.Since(last.lastSeen)
584-
if elapsedNonAliveTime.Nanoseconds() > aliveExpirationTimeout.Nanoseconds() {
583+
if elapsedNonAliveTime.Nanoseconds() > getAliveExpirationTimeout().Nanoseconds() {
585584
d.logger.Warning("Haven't heard from", id, "for", elapsedNonAliveTime)
586585
dead = append(dead, common.PKIidType(id))
587586
}
@@ -593,8 +592,8 @@ func (d *gossipDiscoveryImpl) periodicalSendAlive() {
593592
defer d.logger.Debug("Stopped")
594593

595594
for !d.toDie() {
596-
d.logger.Debug("Sleeping", aliveTimeInterval)
597-
time.Sleep(aliveTimeInterval)
595+
d.logger.Debug("Sleeping", getAliveTimeInterval())
596+
time.Sleep(getAliveTimeInterval())
598597
d.comm.Gossip(d.createAliveMessage())
599598
}
600599
}
@@ -803,3 +802,23 @@ func before(a *timestamp, b *proto.PeerTime) bool {
803802
return (uint64(a.incTime.UnixNano()) == b.IncNumber && a.seqNum < b.SeqNum) ||
804803
uint64(a.incTime.UnixNano()) < b.IncNumber
805804
}
805+
806+
func getAliveTimeInterval() time.Duration {
807+
return util.GetDurationOrDefault("peer.gossip.aliveTimeInterval", defaultHelloInterval)
808+
}
809+
810+
func getAliveExpirationTimeout() time.Duration {
811+
return util.GetDurationOrDefault("peer.gossip.aliveExpirationTimeout", 5*getAliveTimeInterval())
812+
}
813+
814+
func getAliveExpirationCheckInterval() time.Duration {
815+
if aliveExpirationCheckInterval != 0 {
816+
return aliveExpirationCheckInterval
817+
}
818+
819+
return time.Duration(getAliveExpirationTimeout() / 10)
820+
}
821+
822+
func getReconnectInterval() time.Duration {
823+
return util.GetDurationOrDefault("peer.gossip.reconnectInterval", getAliveExpirationTimeout())
824+
}

gossip/discovery/discovery_test.go

+51-10
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,30 @@ import (
2020
"fmt"
2121
"io"
2222
"net"
23+
"strings"
2324
"sync"
2425
"sync/atomic"
2526
"testing"
2627
"time"
2728

2829
"github.com/hyperledger/fabric/gossip/common"
2930
proto "github.com/hyperledger/fabric/protos/gossip"
31+
"github.com/spf13/viper"
3032
"github.com/stretchr/testify/assert"
3133
"golang.org/x/net/context"
3234
"google.golang.org/grpc"
3335
)
3436

3537
var timeout = time.Second * time.Duration(15)
3638

39+
func init() {
40+
aliveTimeInterval := time.Duration(time.Millisecond * 100)
41+
SetAliveTimeInterval(aliveTimeInterval)
42+
SetAliveExpirationTimeout(10 * aliveTimeInterval)
43+
SetAliveExpirationCheckInterval(aliveTimeInterval)
44+
SetReconnectInterval(10 * aliveTimeInterval)
45+
}
46+
3747
type dummyCommModule struct {
3848
id string
3949
presumeDead chan common.PKIidType
@@ -141,13 +151,6 @@ func (comm *dummyCommModule) CloseConn(peer *NetworkMember) {
141151
comm.conns[peer.Endpoint].Close()
142152
}
143153

144-
func init() {
145-
aliveTimeInterval = time.Duration(time.Millisecond * 100)
146-
aliveExpirationTimeout = 10 * aliveTimeInterval
147-
aliveExpirationCheckInterval = aliveTimeInterval
148-
reconnectInterval = aliveExpirationTimeout
149-
}
150-
151154
func (g *gossipInstance) GossipStream(stream proto.Gossip_GossipStreamServer) error {
152155
for {
153156
gMsg, err := stream.Recv()
@@ -348,12 +351,12 @@ func TestInitiateSync(t *testing.T) {
348351
if atomic.LoadInt32(&toDie) == int32(1) {
349352
return
350353
}
351-
time.Sleep(aliveExpirationTimeout / 3)
354+
time.Sleep(getAliveExpirationTimeout() / 3)
352355
inst.InitiateSync(9)
353356
}
354357
}()
355358
}
356-
time.Sleep(aliveExpirationTimeout * 4)
359+
time.Sleep(getAliveExpirationTimeout() * 4)
357360
assertMembership(t, instances, nodeNum-1)
358361
atomic.StoreInt32(&toDie, int32(1))
359362
stopInstances(t, instances)
@@ -472,7 +475,7 @@ func TestConvergence(t *testing.T) {
472475
}
473476

474477
assertMembership(t, instances, 3)
475-
connector := createDiscoveryInstance(4623, fmt.Sprintf("d13"), []string{bootPeer(4611), bootPeer(4615), bootPeer(4619)})
478+
connector := createDiscoveryInstance(4623, "d13", []string{bootPeer(4611), bootPeer(4615), bootPeer(4619)})
476479
instances = append(instances, connector)
477480
assertMembership(t, instances, 12)
478481
connector.Stop()
@@ -481,6 +484,44 @@ func TestConvergence(t *testing.T) {
481484
stopInstances(t, instances)
482485
}
483486

487+
func TestConfigFromFile(t *testing.T) {
488+
preAliveTimeInterval := getAliveTimeInterval()
489+
preAliveExpirationTimeout := getAliveExpirationTimeout()
490+
preAliveExpirationCheckInterval := getAliveExpirationCheckInterval()
491+
preReconnectInterval := getReconnectInterval()
492+
493+
// Recover the config values in order to avoid impacting other tests
494+
defer func() {
495+
SetAliveTimeInterval(preAliveTimeInterval)
496+
SetAliveExpirationTimeout(preAliveExpirationTimeout)
497+
SetAliveExpirationCheckInterval(preAliveExpirationCheckInterval)
498+
SetReconnectInterval(preReconnectInterval)
499+
}()
500+
501+
// Verify if using default values when config is missing
502+
viper.Reset()
503+
aliveExpirationCheckInterval = 0 * time.Second
504+
assert.Equal(t, time.Duration(5)*time.Second, getAliveTimeInterval())
505+
assert.Equal(t, time.Duration(25)*time.Second, getAliveExpirationTimeout())
506+
assert.Equal(t, time.Duration(25)*time.Second/10, getAliveExpirationCheckInterval())
507+
assert.Equal(t, time.Duration(25)*time.Second, getReconnectInterval())
508+
509+
//Verify reading the values from config file
510+
viper.Reset()
511+
aliveExpirationCheckInterval = 0 * time.Second
512+
viper.SetConfigName("core")
513+
viper.SetEnvPrefix("CORE")
514+
viper.AddConfigPath("./../../peer")
515+
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
516+
viper.AutomaticEnv()
517+
err := viper.ReadInConfig()
518+
assert.NoError(t, err)
519+
assert.Equal(t, time.Duration(5)*time.Second, getAliveTimeInterval())
520+
assert.Equal(t, time.Duration(25)*time.Second, getAliveExpirationTimeout())
521+
assert.Equal(t, time.Duration(25)*time.Second/10, getAliveExpirationCheckInterval())
522+
assert.Equal(t, time.Duration(25)*time.Second, getReconnectInterval())
523+
}
524+
484525
func waitUntilOrFail(t *testing.T, pred func() bool) {
485526
start := time.Now()
486527
limit := start.UnixNano() + timeout.Nanoseconds()

gossip/gossip/gossip_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ var testWG = sync.WaitGroup{}
4343

4444
func init() {
4545
aliveTimeInterval := time.Duration(1000) * time.Millisecond
46-
discovery.SetAliveTimeInternal(aliveTimeInterval)
46+
discovery.SetAliveTimeInterval(aliveTimeInterval)
4747
discovery.SetAliveExpirationCheckInterval(aliveTimeInterval)
48-
discovery.SetExpirationTimeout(aliveTimeInterval * 10)
48+
discovery.SetAliveExpirationTimeout(aliveTimeInterval * 10)
4949
discovery.SetReconnectInterval(aliveTimeInterval * 5)
5050

5151
testWG.Add(7)

peer/core.yaml

+6-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,12 @@ peer:
114114
requestWaitTime: 1s
115115
# Time to wait before pull engine ends pull (unit: second)
116116
responseWaitTime: 2s
117-
117+
# Alive check interval(unit: second)
118+
aliveTimeInterval: 5s
119+
# Alive expiration timeout(unit: second)
120+
aliveExpirationTimeout: 25s
121+
# Reconnect interval(unit: second)
122+
reconnectInterval: 25s
118123
# This is an endpoint that is published to peers outside of the organization.
119124
# If this isn't set, the peer will not be known to other organizations.
120125
externalEndpoint:

0 commit comments

Comments
 (0)