Skip to content

Commit

Permalink
[FABG-929] Use retry options from channel policy for selection (#36)
Browse files Browse the repository at this point in the history
The retry options for the Fabric selection service are now retrieved from the Discovery channel policies which are defined in the channel config. Also added default retry options in case the config file does not define any.

Signed-off-by: Bob Stasyszyn <Bob.Stasyszyn@securekey.com>
  • Loading branch information
bstasyszyn committed Dec 19, 2019
1 parent 6f74e78 commit f5bfb4c
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 21 deletions.
1 change: 0 additions & 1 deletion go.mod
Expand Up @@ -40,7 +40,6 @@ require (
github.com/stretchr/testify v1.3.0
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
golang.org/x/net v0.0.0-20190311183353-d8887717615a
google.golang.org/appengine v1.4.0 // indirect
google.golang.org/genproto v0.0.0-20190327125643-d831d65fe17d // indirect
google.golang.org/grpc v1.23.0
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
Expand Down
25 changes: 6 additions & 19 deletions pkg/client/common/selection/fabricselection/fabricselection.go
Expand Up @@ -29,7 +29,6 @@ import (
"github.com/hyperledger/fabric-sdk-go/pkg/util/concurrent/lazycache"
"github.com/hyperledger/fabric-sdk-go/pkg/util/concurrent/lazyref"
"github.com/pkg/errors"
grpcCodes "google.golang.org/grpc/codes"
)

const (
Expand All @@ -41,23 +40,6 @@ const (

var logger = logging.NewLogger(moduleName)

var retryableCodes = map[status.Group][]status.Code{
status.GRPCTransportStatus: {
status.Code(grpcCodes.Unavailable),
},
status.DiscoveryServerStatus: {
status.QueryEndorsers,
},
}

var defaultRetryOpts = retry.Opts{
Attempts: 6,
InitialBackoff: 500 * time.Millisecond,
MaxBackoff: 5 * time.Second,
BackoffFactor: 1.75,
RetryableCodes: retryableCodes,
}

// DiscoveryClient is the client to the discovery service
type DiscoveryClient interface {
Send(ctx context.Context, req *fabdiscovery.Request, targets ...fab.PeerConfig) ([]fabdiscovery.Response, error)
Expand All @@ -84,7 +66,8 @@ type Service struct {

// New creates a new dynamic selection service using Fabric's Discovery Service
func New(ctx contextAPI.Client, channelID string, discovery fab.DiscoveryService, opts ...coptions.Opt) (*Service, error) {
options := params{retryOpts: defaultRetryOpts}
options := params{retryOpts: getDefaultRetryOpts(ctx, channelID)}

coptions.Apply(&options, opts)

if options.refreshInterval == 0 {
Expand Down Expand Up @@ -355,6 +338,10 @@ func asPeer(ctx contextAPI.Client, endpoint *discclient.Peer) (fab.Peer, error)
}, nil
}

func getDefaultRetryOpts(ctx contextAPI.Client, channelID string) retry.Opts {
return ctx.EndpointConfig().ChannelConfig(channelID).Policies.Discovery.RetryOpts
}

type peerEndpoint struct {
fab.Peer
blockHeight uint64
Expand Down
4 changes: 4 additions & 0 deletions pkg/fab/default_channel_test.go
Expand Up @@ -35,6 +35,10 @@ func TestDefaultChannelWithDefaultChannelConfiguredAndNoMatchers(t *testing.T) {
assert.Equal(t, 3, chConfig.Policies.QueryChannelConfig.MaxTargets)
assert.Equal(t, 1, chConfig.Policies.Discovery.MinResponses)
assert.Equal(t, 3, chConfig.Policies.Discovery.MaxTargets)
assert.Equal(t, 2, chConfig.Policies.Discovery.RetryOpts.Attempts)
assert.Equal(t, 2*time.Second, chConfig.Policies.Discovery.RetryOpts.InitialBackoff)
assert.Equal(t, 7*time.Second, chConfig.Policies.Discovery.RetryOpts.MaxBackoff)
assert.Equal(t, 2, len(chConfig.Policies.Discovery.RetryOpts.RetryableCodes))

eventPolicies := chConfig.Policies.EventService
assert.Equalf(t, fab.BalancedStrategy, eventPolicies.ResolverStrategy, "Unexpected value for ResolverStrategy")
Expand Down
25 changes: 24 additions & 1 deletion pkg/fab/endpointconfig.go
Expand Up @@ -17,6 +17,7 @@ import (

"github.com/hyperledger/fabric-sdk-go/pkg/common/errors/multi"
"github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry"
"github.com/hyperledger/fabric-sdk-go/pkg/common/errors/status"
"github.com/hyperledger/fabric-sdk-go/pkg/common/logging"
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/core"
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab"
Expand All @@ -28,6 +29,7 @@ import (
"github.com/hyperledger/fabric-sdk-go/pkg/util/pathvar"
"github.com/mitchellh/mapstructure"
"github.com/pkg/errors"
grpcCodes "google.golang.org/grpc/codes"
)

var logger = logging.NewLogger("fabsdk/fab")
Expand Down Expand Up @@ -76,6 +78,23 @@ const (
)

var (
defaultDiscoveryRetryableCodes = map[status.Group][]status.Code{
status.GRPCTransportStatus: {
status.Code(grpcCodes.Unavailable),
},
status.DiscoveryServerStatus: {
status.QueryEndorsers,
},
}

defaultDiscoveryRetryOpts = retry.Opts{
Attempts: 6,
InitialBackoff: 500 * time.Millisecond,
MaxBackoff: 5 * time.Second,
BackoffFactor: 1.75,
RetryableCodes: defaultDiscoveryRetryableCodes,
}

defaultChannelPolicies = &ChannelPolicies{
QueryChannelConfig: QueryChannelConfigPolicy{
MaxTargets: defaultMaxTargets,
Expand All @@ -85,7 +104,7 @@ var (
Discovery: DiscoveryPolicy{
MaxTargets: defaultMaxTargets,
MinResponses: defaultMinResponses,
RetryOpts: retry.Opts{},
RetryOpts: defaultDiscoveryRetryOpts,
},
Selection: SelectionPolicy{
SortingStrategy: BlockHeightPriority,
Expand Down Expand Up @@ -997,6 +1016,10 @@ func (c *EndpointConfig) loadDefaultDiscoveryPolicy(policy *fab.DiscoveryPolicy)
if policy.MinResponses == 0 {
policy.MinResponses = defaultMinResponses
}

if len(policy.RetryOpts.RetryableCodes) == 0 {
policy.RetryOpts.RetryableCodes = defaultDiscoveryRetryableCodes
}
}

func (c *EndpointConfig) loadDefaultSelectionPolicy(policy *fab.SelectionPolicy) {
Expand Down

0 comments on commit f5bfb4c

Please sign in to comment.