Skip to content

Commit c50a329

Browse files
author
Srinivasan Muralidharan
committed
FAB-2203 handle chaincode launch serially
https://jira.hyperledger.org/browse/FAB-2203 Chaincode-peer communication was made asynch to handle concurrent invokes. The state machine requires that launch (one time operation) requires serial communication to get into "ready" state. While it is not incorrect to have async communication for launch also, it makes it hard to write test cases against (we have to wait for CC to get to ready state). A better approach would be for the system to enforce that at the end of init the system woukd be in ready state for inits/invokes. This is achieved by sending ready state serially to the CC. Change-Id: Ib5d3ec1b6188d5aa933dbcb43adaf9995f75de2d Signed-off-by: Srinivasan Muralidharan <[email protected]>
1 parent 9a2d8fc commit c50a329

File tree

1 file changed

+28
-4
lines changed

1 file changed

+28
-4
lines changed

core/chaincode/handler.go

+28-4
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ type transactionContext struct {
6767
type nextStateInfo struct {
6868
msg *pb.ChaincodeMessage
6969
sendToCC bool
70+
71+
//the only time we need to send synchronously is
72+
//when launching the chaincode to take it to ready
73+
//state (look for the panic when sending serial)
74+
sendSync bool
7075
}
7176

7277
//chaincode registered name is of the form
@@ -261,7 +266,13 @@ func (handler *Handler) deregister() error {
261266
}
262267

263268
func (handler *Handler) triggerNextState(msg *pb.ChaincodeMessage, send bool) {
264-
handler.nextState <- &nextStateInfo{msg, send}
269+
//this will send Async
270+
handler.nextState <- &nextStateInfo{msg: msg, sendToCC: send, sendSync: false}
271+
}
272+
273+
func (handler *Handler) triggerNextStateSync(msg *pb.ChaincodeMessage) {
274+
//this will send sync
275+
handler.nextState <- &nextStateInfo{msg: msg, sendToCC: true, sendSync: true}
265276
}
266277

267278
func (handler *Handler) waitForKeepaliveTimer() <-chan time.Time {
@@ -361,8 +372,18 @@ func (handler *Handler) processStream() error {
361372

362373
if nsInfo != nil && nsInfo.sendToCC {
363374
chaincodeLogger.Debugf("[%s]sending state message %s", shorttxid(in.Txid), in.Type.String())
364-
//if error bail in select
365-
handler.serialSendAsync(in, errc)
375+
//ready messages are sent sync
376+
if nsInfo.sendSync {
377+
if in.Type.String() != pb.ChaincodeMessage_READY.String() {
378+
panic(fmt.Sprintf("[%s]Sync send can only be for READY state %s\n", shorttxid(in.Txid), in.Type.String()))
379+
}
380+
if err = handler.serialSend(in); err != nil {
381+
return fmt.Errorf("[%s]Error sending ready message, ending stream: %s", shorttxid(in.Txid), err)
382+
}
383+
} else {
384+
//if error bail in select
385+
handler.serialSendAsync(in, errc)
386+
}
366387
}
367388
}
368389
}
@@ -1264,7 +1285,10 @@ func (handler *Handler) ready(ctxt context.Context, chainID string, txid string,
12641285
return nil, err
12651286
}
12661287

1267-
handler.triggerNextState(ccMsg, true)
1288+
//send the ready synchronously as the
1289+
//ready message is during launch and needs
1290+
//to happen before any init/invokes can sneak in
1291+
handler.triggerNextStateSync(ccMsg)
12681292

12691293
return txctx.responseNotifier, nil
12701294
}

0 commit comments

Comments
 (0)