Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FABGW-6 Use concurrent go routines for endorsement #2453

Merged
merged 1 commit into from Mar 4, 2021

Conversation

andrew-coleman
Copy link
Member

Replace the current sequential logic for getting multiple endorsements with concurrent fan-out/fan-in using go routines
Add configurable endorsement timeout option to the global config and pass through to gateway

Signed-off-by: andrew-coleman andrew_coleman@uk.ibm.com

@andrew-coleman andrew-coleman requested a review from a team as a code owner March 2, 2021 12:10
@andrew-coleman andrew-coleman marked this pull request as draft March 2, 2021 12:11
@andrew-coleman
Copy link
Member Author

/ci-run

@github-actions
Copy link

github-actions bot commented Mar 2, 2021

AZP build triggered!

@andrew-coleman andrew-coleman marked this pull request as ready for review March 2, 2021 15:15
@@ -274,7 +274,12 @@ func (c *Config) load() error {
}

c.GatewayOptions = gateway.DefaultOptions()
c.GatewayOptions.Enabled = viper.GetBool("peer.gateway.enabled")
if viper.IsSet("peer.gateway.enabled") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is new code, the logic to create the gateway configuration should live in the gateway code. If possible (and I think we're finally at a level of the code that supports it), the viper instance should be passed to the constructor to avoid dealing with global state.

@@ -825,7 +825,7 @@ func serve(args []string) error {
logger.Info("Starting peer with Gateway enabled")
gatewayprotos.RegisterGatewayServer(
peerServer.Server(),
gateway.CreateServer(&gateway.EndorserServerAdapter{Server: serverEndorser}, discoveryService, peerInstance.GossipService.SelfMembershipInfo().Endpoint),
gateway.CreateServer(&gateway.EndorserServerAdapter{Server: serverEndorser}, discoveryService, peerInstance.GossipService.SelfMembershipInfo().Endpoint, coreConfig.GatewayOptions),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's time to break this across multiple lines.

}(endorser)
}

timeout := time.After(gs.options.EndorsementTimeout)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Under load, this can result in significant memory pressure. This problem is highlighted in the doc: The underlying Timer is not recovered by the garbage collector until the timer fires

That said, why do this? Why not decorate the context with a timeout and use the same one across all of the calls? (I'm guessing you copied this code from somewhere...) Once you know the calls have a proper timeout and cancelation, you could choose to keep using a select in a for loop or move to something simpler (like a WaitGroup) to wait for the calls to complete.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rewritten to use context.WithTimeout, as suggested

@@ -74,6 +76,7 @@ type contextKey string
func TestGateway(t *testing.T) {
const testChannel = "test_channel"
const testChaincode = "test_chaincode"
const endorsementTimeout = 1 * time.Second
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to multiply by 1

signedProposal: validSignedProposal,
setupRegistry: func(reg *registry) {
reg.localEndorser.(*mocks.EndorserClient).ProcessProposalStub = func(context.Context, *peer.SignedProposal, ...grpc.CallOption) (*peer.ProposalResponse, error) {
time.Sleep(endorsementTimeout + 10*time.Millisecond)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should rarely see a sleep in tests because there's no way to preempt them.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test is now redundant - removed

Replace the current sequential logic for getting multiple endorsements with concurrent fan-out/fan-in using go routines

Signed-off-by: andrew-coleman <andrew_coleman@uk.ibm.com>
@sykesm sykesm merged commit 9ac47b1 into hyperledger:master Mar 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants