github.com/suchongming/fabric@v2.1.1+incompatible/core/scc/inprocstream.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package scc 8 9 import ( 10 "errors" 11 "fmt" 12 "sync" 13 14 pb "github.com/hyperledger/fabric-protos-go/peer" 15 ) 16 17 //SendPanicFailure 18 type SendPanicFailure string 19 20 func (e SendPanicFailure) Error() string { 21 return fmt.Sprintf("send failure %s", string(e)) 22 } 23 24 // PeerChaincodeStream interface for stream between Peer and chaincode instance. 25 type inProcStream struct { 26 recv <-chan *pb.ChaincodeMessage 27 send chan<- *pb.ChaincodeMessage 28 closeOnce sync.Once 29 } 30 31 func newInProcStream(recv <-chan *pb.ChaincodeMessage, send chan<- *pb.ChaincodeMessage) *inProcStream { 32 return &inProcStream{recv: recv, send: send} 33 } 34 35 func (s *inProcStream) Send(msg *pb.ChaincodeMessage) (err error) { 36 //send may happen on a closed channel when the system is 37 //shutting down. Just catch the exception and return error 38 defer func() { 39 if r := recover(); r != nil { 40 err = SendPanicFailure(fmt.Sprintf("%s", r)) 41 return 42 } 43 }() 44 s.send <- msg 45 return 46 } 47 48 func (s *inProcStream) Recv() (*pb.ChaincodeMessage, error) { 49 msg, ok := <-s.recv 50 if !ok { 51 return nil, errors.New("channel is closed") 52 } 53 return msg, nil 54 } 55 56 func (s *inProcStream) CloseSend() error { 57 s.closeOnce.Do(func() { close(s.send) }) 58 return nil 59 }