这是indexloc提供的服务,不要输入任何密码
Skip to content
This repository was archived by the owner on Mar 30, 2018. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions core/chaincode/chaincode_support.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"bytes"
"fmt"
"io"
"strconv"
"sync"
"time"

Expand Down Expand Up @@ -129,6 +130,21 @@ func NewChaincodeSupport(chainname ChainName, getPeerEndpoint func() (*pb.PeerEn
s.peerTLSSvrHostOrd = viper.GetString("peer.tls.serverhostoverride")
}

kadef := 0
if ka := viper.GetString("chaincode.keepalive"); ka == "" {
s.keepalive = time.Duration(kadef) * time.Second
} else {
t, terr := strconv.Atoi(ka)
if terr != nil {
chaincodeLogger.Errorf("Invalid keepalive value %s (%s) defaulting to %d", ka, terr, kadef)
t = kadef
} else if t <= 0 {
chaincodeLogger.Debugf("Turn off keepalive(value %s)", ka)
t = kadef
}
s.keepalive = time.Duration(t) * time.Second
}

return s
}

Expand All @@ -153,6 +169,7 @@ type ChaincodeSupport struct {
peerTLSCertFile string
peerTLSKeyFile string
peerTLSSvrHostOrd string
keepalive time.Duration
}

// DuplicateChaincodeHandlerError returned if attempt to register same chaincodeID while a stream already exists.
Expand Down
5 changes: 5 additions & 0 deletions core/chaincode/chaincodetest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,11 @@ chaincode:
# the image
installpath: /opt/gopath/bin/

#keepalive in seconds. In situations where the communiction goes through a
#proxy that does not support keep-alive, this parameter will maintain connection
#between peer and chaincode.
#A value <= 0 turns keepalive off
keepalive: 1
###############################################################################
#
# Ledger section - ledger configuration encompases both the blockchain
Expand Down
3 changes: 3 additions & 0 deletions core/chaincode/exectransaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,9 @@ func TestExecuteInvokeTransaction(t *testing.T) {
//TLS is on by default. This is the ONLY test that does NOT use TLS
viper.Set("peer.tls.enabled", false)

//turn OFF keepalive. All other tests use keepalive
viper.Set("peer.chaincode.keepalive", "0")

if viper.GetBool("peer.tls.enabled") {
creds, err := credentials.NewServerTLSFromFile(viper.GetString("peer.tls.cert.file"), viper.GetString("peer.tls.key.file"))
if err != nil {
Expand Down
34 changes: 34 additions & 0 deletions core/chaincode/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,16 @@ func (handler *Handler) triggerNextState(msg *pb.ChaincodeMessage, send bool) {
handler.nextState <- &nextStateInfo{msg, send}
}

func (handler *Handler) waitForKeepaliveTimer() <-chan time.Time {
if handler.chaincodeSupport.keepalive > 0 {
c := time.After(handler.chaincodeSupport.keepalive)
return c
}
//no one will signal this channel, listner blocks forever
c := make(chan time.Time, 1)
return c
}

func (handler *Handler) processStream() error {
defer handler.deregister()
msgAvail := make(chan *pb.ChaincodeMessage)
Expand Down Expand Up @@ -307,6 +317,13 @@ func (handler *Handler) processStream() error {

// we can spin off another Recv again
recv = true

if in.Type == pb.ChaincodeMessage_KEEPALIVE {
chaincodeLogger.Debug("Received KEEPALIVE Response")
// Received a keep alive message, we don't do anything with it for now
// and it does not touch the state machine
continue
}
case nsInfo = <-handler.nextState:
in = nsInfo.msg
if in == nil {
Expand All @@ -315,12 +332,29 @@ func (handler *Handler) processStream() error {
return err
}
chaincodeLogger.Debugf("[%s]Move state message %s", shortuuid(in.Uuid), in.Type.String())
case <-handler.waitForKeepaliveTimer():
if handler.chaincodeSupport.keepalive <= 0 {
chaincodeLogger.Errorf("Invalid select: keepalive not on (keepalive=%d)", handler.chaincodeSupport.keepalive)
continue
}

//TODO we could use this to hook into container lifecycle (kill the chaincode if not in use, etc)
kaerr := handler.serialSend(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_KEEPALIVE})
if kaerr != nil {
chaincodeLogger.Errorf("Error sending keepalive, err=%s", kaerr)
} else {
chaincodeLogger.Debug("Sent KEEPALIVE request")
}
//keepalive message kicked in. just continue
continue
}

err = handler.HandleMessage(in)
if err != nil {
chaincodeLogger.Errorf("[%s]Error handling message, ending stream: %s", shortuuid(in.Uuid), err)
return fmt.Errorf("Error handling message, ending stream: %s", err)
}

if nsInfo != nil && nsInfo.sendToCC {
chaincodeLogger.Debugf("[%s]sending state message %s", shortuuid(in.Uuid), in.Type.String())
if err = handler.serialSend(in); err != nil {
Expand Down
11 changes: 9 additions & 2 deletions core/chaincode/shim/chaincode.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,14 @@ func chatWithPeer(chaincodename string, stream PeerChaincodeStream, cc Chaincode
err = fmt.Errorf("Error handling message: %s", err)
return
}
if nsInfo != nil && nsInfo.sendToCC {
chaincodeLogger.Debugf("[%s]send state message %s", shortuuid(in.Uuid), in.Type.String())

//keepalive messages are PONGs to the fabric's PINGs
if (nsInfo != nil && nsInfo.sendToCC) || (in.Type == pb.ChaincodeMessage_KEEPALIVE) {
if in.Type == pb.ChaincodeMessage_KEEPALIVE {
chaincodeLogger.Debug("Sending KEEPALIVE response")
} else {
chaincodeLogger.Debugf("[%s]send state message %s", shortuuid(in.Uuid), in.Type.String())
}
if err = handler.serialSend(in); err != nil {
err = fmt.Errorf("Error sending %s: %s", in.Type.String(), err)
return
Expand Down Expand Up @@ -832,6 +838,7 @@ func (stub *ChaincodeStub) insertRowInternal(tableName string, row Row, update b
}

// ------------- ChaincodeEvent API ----------------------

// SetEvent saves the event to be sent when a transaction is made part of a block
func (stub *ChaincodeStub) SetEvent(name string, payload []byte) error {
stub.chaincodeEvent = &pb.ChaincodeEvent{EventName: name, Payload: payload}
Expand Down
5 changes: 5 additions & 0 deletions core/chaincode/shim/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,11 @@ func (handler *Handler) handleQueryChaincode(chaincodeName string, function stri

// handleMessage message handles loop for shim side of chaincode/validator stream.
func (handler *Handler) handleMessage(msg *pb.ChaincodeMessage) error {
if msg.Type == pb.ChaincodeMessage_KEEPALIVE {
// Received a keep alive message, we don't do anything with it for now
// and it does not touch the state machine
return nil
}
chaincodeLogger.Debugf("[%s]Handling ChaincodeMessage of type: %s(state:%s)", shortuuid(msg.Uuid), msg.Type, handler.FSM.Current())
if handler.FSM.Cannot(msg.Type.String()) {
errStr := fmt.Sprintf("[%s]Chaincode handler FSM cannot handle message (%s) with payload size (%d) while in state: %s", msg.Uuid, msg.Type.String(), len(msg.Payload), handler.FSM.Current())
Expand Down
8 changes: 8 additions & 0 deletions peer/core.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,14 @@ chaincode:
# the image
installpath: /opt/gopath/bin/

# keepalive in seconds. In situations where the communiction goes through a
# proxy that does not support keep-alive, this parameter will maintain connection
# between peer and chaincode.
# A value <= 0 turns keepalive off
keepalive: 0

###############################################################################
#
###############################################################################
#
# Ledger section - ledger configuration encompases both the blockchain
Expand Down
2 changes: 1 addition & 1 deletion protos/api.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions protos/chaincode.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions protos/chaincode.proto
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ message ChaincodeMessage {
RANGE_QUERY_STATE = 17;
RANGE_QUERY_STATE_NEXT = 18;
RANGE_QUERY_STATE_CLOSE = 19;
KEEPALIVE = 20;
}

Type type = 1;
Expand Down