Skip to content
This repository was archived by the owner on Apr 25, 2025. It is now read-only.

Commit 063fd0b

Browse files
committed
[FAB-8571] request context by higherlevel clients
- higher level clients to create request context for lower level clients - higher level clients to create parent request context for multiple lower level operations - added timeout options in higher level ledger client functions QueryInfo,QueryBlockByHash,QueryBlock, QueryTransaction,QueryConfig - InfraProvider CreateChannelTransactor function signature changed - Transactor() removed from channel service - ChannelConfig Query() function signature changed - new timeout types added peer.timeout.response and global.timeout.resmgmt TODO: - overall and low level timeout override options for high level operation. Change-Id: I1e0284c7e8fc7e2bc855ca603d5b2bc10de65410 Signed-off-by: Sudesh Shetty <sudesh.shetty@securekey.com>
1 parent 6075794 commit 063fd0b

Some content is hidden

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

59 files changed

+774
-352
lines changed

pkg/client/channel/chclient.go

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ SPDX-License-Identifier: Apache-2.0
88
package channel
99

1010
import (
11+
reqContext "context"
1112
"time"
1213

1314
"github.com/hyperledger/fabric-sdk-go/pkg/client/channel/invoke"
1415
"github.com/hyperledger/fabric-sdk-go/pkg/client/common/discovery"
1516
"github.com/hyperledger/fabric-sdk-go/pkg/client/common/discovery/greylist"
1617
"github.com/hyperledger/fabric-sdk-go/pkg/common/context"
18+
contextImpl "github.com/hyperledger/fabric-sdk-go/pkg/context"
1719
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/core"
1820
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/fab"
1921
"github.com/hyperledger/fabric-sdk-go/pkg/errors/multi"
@@ -37,7 +39,6 @@ const (
3739
type Client struct {
3840
context context.Channel
3941
membership fab.ChannelMembership
40-
transactor fab.Transactor
4142
eventService fab.EventService
4243
greylist *greylist.Filter
4344
discoveryFilter fab.TargetFilter
@@ -82,19 +83,13 @@ func New(channelProvider context.ChannelProvider, opts ...ClientOption) (*Client
8283
return nil, errors.WithMessage(err, "event service creation failed")
8384
}
8485

85-
transactor, err := channelContext.ChannelService().Transactor()
86-
if err != nil {
87-
return nil, errors.WithMessage(err, "transactor creation failed")
88-
}
89-
9086
membership, err := channelContext.ChannelService().Membership()
9187
if err != nil {
9288
return nil, errors.WithMessage(err, "membership creation failed")
9389
}
9490

9591
channelClient := Client{
9692
membership: membership,
97-
transactor: transactor,
9893
eventService: eventService,
9994
greylist: greylistProvider,
10095
}
@@ -133,8 +128,11 @@ func (cc *Client) InvokeHandler(handler invoke.Handler, request Request, options
133128
return Response{}, err
134129
}
135130

131+
reqCtx, cancel := cc.createReqContext(&txnOpts)
132+
defer cancel()
133+
136134
//Prepare context objects for handler
137-
requestContext, clientContext, err := cc.prepareHandlerContexts(request, txnOpts)
135+
requestContext, clientContext, err := cc.prepareHandlerContexts(reqCtx, request, txnOpts)
138136
if err != nil {
139137
return Response{}, err
140138
}
@@ -180,18 +178,39 @@ func (cc *Client) resolveRetry(ctx *invoke.RequestContext, o requestOptions) boo
180178
return false
181179
}
182180

181+
//createReqContext creates req context for invoke handler
182+
func (cc *Client) createReqContext(txnOpts *requestOptions) (reqContext.Context, reqContext.CancelFunc) {
183+
184+
//Setting default timeouts when not provided
185+
if txnOpts.Timeout == 0 {
186+
txnOpts.Timeout = cc.context.Config().Timeout(core.Execute)
187+
if txnOpts.Timeout == 0 {
188+
//If still zero, then set default handler timeout
189+
txnOpts.Timeout = defaultHandlerTimeout
190+
}
191+
}
192+
193+
return contextImpl.NewRequest(cc.context, contextImpl.WithTimeout(txnOpts.Timeout))
194+
}
195+
183196
//prepareHandlerContexts prepares context objects for handlers
184-
func (cc *Client) prepareHandlerContexts(request Request, o requestOptions) (*invoke.RequestContext, *invoke.ClientContext, error) {
197+
func (cc *Client) prepareHandlerContexts(reqCtx reqContext.Context, request Request, o requestOptions) (*invoke.RequestContext, *invoke.ClientContext, error) {
185198

186199
if request.ChaincodeID == "" || request.Fcn == "" {
187200
return nil, nil, errors.New("ChaincodeID and Fcn are required")
188201
}
189202

203+
chConfig := cc.context.ChannelService().ChannelConfig()
204+
transactor, err := cc.context.InfraProvider().CreateChannelTransactor(reqCtx, chConfig)
205+
if err != nil {
206+
return nil, nil, errors.WithMessage(err, "failed to create transactor")
207+
}
208+
190209
clientContext := &invoke.ClientContext{
191210
Selection: cc.context.SelectionService(),
192211
Discovery: cc.context.DiscoveryService(),
193212
Membership: cc.membership,
194-
Transactor: cc.transactor,
213+
Transactor: transactor,
195214
EventService: cc.eventService,
196215
}
197216

@@ -202,15 +221,6 @@ func (cc *Client) prepareHandlerContexts(request Request, o requestOptions) (*in
202221
RetryHandler: retry.New(o.Retry),
203222
}
204223

205-
if requestContext.Opts.Timeout == 0 {
206-
to := cc.context.Config().Timeout(core.Execute)
207-
if to == 0 {
208-
requestContext.Opts.Timeout = defaultHandlerTimeout
209-
} else {
210-
requestContext.Opts.Timeout = to
211-
}
212-
}
213-
214224
return requestContext, clientContext, nil
215225
}
216226

pkg/client/channel/chclient_test.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -503,13 +503,6 @@ func setupTestChannelService(ctx context.Client, orderers []fab.Orderer) (fab.Ch
503503
return nil, errors.WithMessage(err, "mock channel service creation failed")
504504
}
505505

506-
transactor := txnmocks.MockTransactor{
507-
Ctx: ctx,
508-
ChannelID: channelID,
509-
Orderers: orderers,
510-
}
511-
chService.(*fcmocks.MockChannelService).SetTransactor(&transactor)
512-
513506
return chService, nil
514507
}
515508

@@ -528,6 +521,14 @@ func setupCustomTestContext(t *testing.T, selectionService fab.SelectionService,
528521
orderers = []fab.Orderer{orderer}
529522
}
530523

524+
transactor := txnmocks.MockTransactor{
525+
Ctx: ctx,
526+
ChannelID: channelID,
527+
Orderers: orderers,
528+
}
529+
530+
ctx.InfraProvider().(*fcmocks.MockInfraProvider).SetCustomTransactor(&transactor)
531+
531532
testChannelSvc, err := setupTestChannelService(ctx, orderers)
532533
assert.Nil(t, err, "Got error %s", err)
533534

pkg/client/common/mocks/mocktransactor.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ SPDX-License-Identifier: Apache-2.0
77
package mocks
88

99
import (
10+
"time"
11+
1012
"github.com/hyperledger/fabric-sdk-go/pkg/common/context"
13+
contextImpl "github.com/hyperledger/fabric-sdk-go/pkg/context"
1114
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/fab"
1215
"github.com/hyperledger/fabric-sdk-go/pkg/fab/txn"
1316
"github.com/pkg/errors"
@@ -32,7 +35,9 @@ func (t *MockTransactor) CreateTransactionHeader() (fab.TransactionHeader, error
3235

3336
// SendTransactionProposal sends a TransactionProposal to the target peers.
3437
func (t *MockTransactor) SendTransactionProposal(proposal *fab.TransactionProposal, targets []fab.ProposalProcessor) ([]*fab.TransactionProposalResponse, error) {
35-
return txn.SendProposal(t.Ctx, proposal, targets)
38+
rqtx, cancel := contextImpl.NewRequest(t.Ctx, contextImpl.WithTimeout(10*time.Second))
39+
defer cancel()
40+
return txn.SendProposal(rqtx, proposal, targets)
3641
}
3742

3843
// CreateTransaction create a transaction with proposal response.
@@ -42,5 +47,7 @@ func (t *MockTransactor) CreateTransaction(request fab.TransactionRequest) (*fab
4247

4348
// SendTransaction send a transaction to the chain’s orderer service (one or more orderer endpoints) for consensus and committing to the ledger.
4449
func (t *MockTransactor) SendTransaction(tx *fab.Transaction) (*fab.TransactionResponse, error) {
45-
return txn.Send(t.Ctx, tx, t.Orderers)
50+
rqtx, cancel := contextImpl.NewRequest(t.Ctx, contextImpl.WithTimeout(10*time.Second))
51+
defer cancel()
52+
return txn.Send(rqtx, tx, t.Orderers)
4653
}

pkg/client/ledger/ledger.go

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ SPDX-License-Identifier: Apache-2.0
88
package ledger
99

1010
import (
11+
reqContext "context"
1112
"math/rand"
1213
"time"
1314

@@ -18,6 +19,8 @@ import (
1819
"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/common"
1920
pb "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/peer"
2021

22+
contextImpl "github.com/hyperledger/fabric-sdk-go/pkg/context"
23+
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/core"
2124
"github.com/hyperledger/fabric-sdk-go/pkg/fab/channel"
2225
"github.com/hyperledger/fabric-sdk-go/pkg/logging"
2326
"github.com/pkg/errors"
@@ -35,9 +38,9 @@ const (
3538
// An application that requires interaction with multiple channels should create a separate
3639
// instance of the ledger client for each channel. Ledger client supports specific queries only.
3740
type Client struct {
38-
context context.Channel
39-
filter TargetFilter
40-
ledger *channel.Ledger
41+
ctx context.Channel
42+
filter TargetFilter
43+
ledger *channel.Ledger
4144
}
4245

4346
// MSPFilter is default filter
@@ -58,14 +61,14 @@ func New(channelProvider context.ChannelProvider, opts ...ClientOption) (*Client
5861
return nil, err
5962
}
6063

61-
ledger, err := channel.NewLedger(channelContext, channelContext.ChannelID())
64+
ledger, err := channel.NewLedger(channelContext.ChannelID())
6265
if err != nil {
6366
return nil, err
6467
}
6568

6669
ledgerClient := Client{
67-
context: channelContext,
68-
ledger: ledger,
70+
ctx: channelContext,
71+
ledger: ledger,
6972
}
7073

7174
for _, opt := range opts {
@@ -103,7 +106,10 @@ func (c *Client) QueryInfo(options ...RequestOption) (*fab.BlockchainInfoRespons
103106
return nil, errors.WithMessage(err, "failed to determine target peers for QueryBlockByHash")
104107
}
105108

106-
responses, err := c.ledger.QueryInfo(peersToTxnProcessors(targets))
109+
reqCtx, cancel := c.createRequestContext(opts)
110+
defer cancel()
111+
112+
responses, err := c.ledger.QueryInfo(reqCtx, peersToTxnProcessors(targets))
107113
if err != nil && len(responses) == 0 {
108114
return nil, errors.WithMessage(err, "Failed to QueryBlockByHash")
109115
}
@@ -146,7 +152,10 @@ func (c *Client) QueryBlockByHash(blockHash []byte, options ...RequestOption) (*
146152
return nil, errors.WithMessage(err, "failed to determine target peers for QueryBlockByHash")
147153
}
148154

149-
responses, err := c.ledger.QueryBlockByHash(blockHash, peersToTxnProcessors(targets))
155+
reqCtx, cancel := c.createRequestContext(opts)
156+
defer cancel()
157+
158+
responses, err := c.ledger.QueryBlockByHash(reqCtx, blockHash, peersToTxnProcessors(targets))
150159
if err != nil && len(responses) == 0 {
151160
return nil, errors.WithMessage(err, "Failed to QueryBlockByHash")
152161
}
@@ -187,7 +196,10 @@ func (c *Client) QueryBlock(blockNumber int, options ...RequestOption) (*common.
187196
return nil, errors.WithMessage(err, "failed to determine target peers for QueryBlock")
188197
}
189198

190-
responses, err := c.ledger.QueryBlock(blockNumber, peersToTxnProcessors(targets))
199+
reqCtx, cancel := c.createRequestContext(opts)
200+
defer cancel()
201+
202+
responses, err := c.ledger.QueryBlock(reqCtx, blockNumber, peersToTxnProcessors(targets))
191203
if err != nil && len(responses) == 0 {
192204
return nil, errors.WithMessage(err, "Failed to QueryBlock")
193205
}
@@ -229,7 +241,10 @@ func (c *Client) QueryTransaction(transactionID fab.TransactionID, options ...Re
229241
return nil, errors.WithMessage(err, "failed to determine target peers for QueryTransaction")
230242
}
231243

232-
responses, err := c.ledger.QueryTransaction(transactionID, peersToTxnProcessors(targets))
244+
reqCtx, cancel := c.createRequestContext(opts)
245+
defer cancel()
246+
247+
responses, err := c.ledger.QueryTransaction(reqCtx, transactionID, peersToTxnProcessors(targets))
233248
if err != nil && len(responses) == 0 {
234249
return nil, errors.WithMessage(err, "Failed to QueryTransaction")
235250
}
@@ -269,20 +284,23 @@ func (c *Client) QueryConfig(options ...RequestOption) (fab.ChannelCfg, error) {
269284
return nil, errors.WithMessage(err, "failed to determine target peers for QueryConfig")
270285
}
271286

272-
channelConfig, err := chconfig.New(c.context, c.context.ChannelID(), chconfig.WithPeers(targets), chconfig.WithMinResponses(opts.MinTargets))
287+
channelConfig, err := chconfig.New(c.ctx.ChannelID(), chconfig.WithPeers(targets), chconfig.WithMinResponses(opts.MinTargets))
273288
if err != nil {
274289
return nil, errors.WithMessage(err, "QueryConfig failed")
275290
}
276291

277-
return channelConfig.Query()
292+
reqCtx, cancel := c.createRequestContext(opts)
293+
defer cancel()
294+
295+
return channelConfig.Query(reqCtx)
278296

279297
}
280298

281299
//prepareRequestOpts Reads Opts from Option array
282300
func (c *Client) prepareRequestOpts(options ...RequestOption) (requestOptions, error) {
283301
opts := requestOptions{}
284302
for _, option := range options {
285-
err := option(c.context, &opts)
303+
err := option(c.ctx, &opts)
286304
if err != nil {
287305
return opts, errors.WithMessage(err, "Failed to read request opts")
288306
}
@@ -318,7 +336,7 @@ func (c *Client) calculateTargets(opts requestOptions) ([]fab.Peer, error) {
318336
var err error
319337
if targets == nil {
320338
// Retrieve targets from discovery
321-
targets, err = c.context.DiscoveryService().GetPeers()
339+
targets, err = c.ctx.DiscoveryService().GetPeers()
322340
if err != nil {
323341
return nil, err
324342
}
@@ -352,6 +370,17 @@ func (c *Client) calculateTargets(opts requestOptions) ([]fab.Peer, error) {
352370
return targets[:numOfTargets], nil
353371
}
354372

373+
//createRequestContext creates request context for grpc
374+
func (c *Client) createRequestContext(opts requestOptions) (reqContext.Context, reqContext.CancelFunc) {
375+
376+
timeout := opts.Timeout
377+
if timeout == 0 {
378+
timeout = c.ctx.Config().TimeoutOrDefault(core.PeerResponse)
379+
}
380+
381+
return contextImpl.NewRequest(c.ctx, contextImpl.WithTimeout(timeout))
382+
}
383+
355384
// filterTargets is helper method to filter peers
356385
func filterTargets(peers []fab.Peer, filter TargetFilter) []fab.Peer {
357386

pkg/client/ledger/opts.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ SPDX-License-Identifier: Apache-2.0
77
package ledger
88

99
import (
10+
"time"
11+
1012
"github.com/hyperledger/fabric-sdk-go/pkg/common/context"
1113
"github.com/hyperledger/fabric-sdk-go/pkg/context/api/fab"
1214
"github.com/hyperledger/fabric-sdk-go/pkg/core/config"
@@ -40,10 +42,11 @@ type TargetFilter interface {
4042

4143
//requestOptions contains options for operations performed by LedgerClient
4244
type requestOptions struct {
43-
Targets []fab.Peer // target peers
44-
TargetFilter TargetFilter // target filter
45-
MaxTargets int // maximum number of targets to select
46-
MinTargets int // min number of targets that have to respond with no error (or agree on result)
45+
Targets []fab.Peer // target peers
46+
TargetFilter TargetFilter // target filter
47+
MaxTargets int // maximum number of targets to select
48+
MinTargets int // min number of targets that have to respond with no error (or agree on result)
49+
Timeout time.Duration //timeout options for QueryInfo,QueryBlockByHash,QueryBlock,QueryTransaction,QueryConfig
4750
}
4851

4952
//WithTargets encapsulates fab.Peer targets to ledger RequestOption
@@ -104,3 +107,12 @@ func WithMinTargets(minTargets int) RequestOption {
104107
return nil
105108
}
106109
}
110+
111+
//WithTimeout encapsulates timeout to ledger RequestOption
112+
//for QueryInfo,QueryBlockByHash,QueryBlock,QueryTransaction,QueryConfig functions
113+
func WithTimeout(timeout time.Duration) RequestOption {
114+
return func(ctx context.Client, opts *requestOptions) error {
115+
opts.Timeout = timeout
116+
return nil
117+
}
118+
}

pkg/client/msp/testdata/config_test.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ client:
4646
# Global configuration for peer, event service and orderer timeouts
4747
peer:
4848
timeout:
49+
response: 10s
4950
connection: 3s
5051
discovery:
5152
# Expiry period for discovery service greylist filter
@@ -65,6 +66,7 @@ client:
6566
timeout:
6667
query: 45s
6768
execute: 60s
69+
resmgmt: 60s
6870
cache:
6971
connectionIdle: 30s
7072

0 commit comments

Comments
 (0)