github.com/yous1230/fabric@v2.0.0-beta.0.20191224111736-74345bee6ac2+incompatible/core/chaincode/container_runtime.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package chaincode
     8  
     9  import (
    10  	"github.com/hyperledger/fabric/core/container"
    11  	"github.com/hyperledger/fabric/core/container/ccintf"
    12  	"github.com/pkg/errors"
    13  )
    14  
    15  // ContainerRouter is a poor abstraction used for building, and running chaincode processes.
    16  // This management probably does not belong in this package, chaincode process lifecycle should
    17  // be driven by what chaincodes are defined, what chaincodes are instantiated, and not driven by
    18  // invocations.  But, the legacy lifecycle makes this very challenging.  Once the legacy lifecycle
    19  // is removed (or perhaps before), this interface should probably go away entirely.
    20  type ContainerRouter interface {
    21  	Build(ccid string) error
    22  	ChaincodeServerInfo(ccid string) (*ccintf.ChaincodeServerInfo, error)
    23  	Start(ccid string, peerConnection *ccintf.PeerConnection) error
    24  	Stop(ccid string) error
    25  	Wait(ccid string) (int, error)
    26  }
    27  
    28  // ContainerRuntime is responsible for managing containerized chaincode.
    29  type ContainerRuntime struct {
    30  	ContainerRouter ContainerRouter
    31  	BuildRegistry   *container.BuildRegistry
    32  }
    33  
    34  // Build builds the chaincode if necessary and returns ChaincodeServerInfo if
    35  // the chaincode is a server
    36  func (c *ContainerRuntime) Build(ccid string) (*ccintf.ChaincodeServerInfo, error) {
    37  	buildStatus, ok := c.BuildRegistry.BuildStatus(ccid)
    38  	if !ok {
    39  		err := c.ContainerRouter.Build(ccid)
    40  		buildStatus.Notify(err)
    41  	}
    42  	<-buildStatus.Done()
    43  
    44  	if err := buildStatus.Err(); err != nil {
    45  		return nil, errors.WithMessage(err, "error building image")
    46  	}
    47  
    48  	return c.ContainerRouter.ChaincodeServerInfo(ccid)
    49  }
    50  
    51  // Start launches chaincode in a runtime environment.
    52  func (c *ContainerRuntime) Start(ccid string, ccinfo *ccintf.PeerConnection) error {
    53  	chaincodeLogger.Debugf("start container: %s", ccid)
    54  
    55  	if err := c.ContainerRouter.Start(ccid, ccinfo); err != nil {
    56  		return errors.WithMessage(err, "error starting container")
    57  	}
    58  
    59  	return nil
    60  }
    61  
    62  // Stop terminates chaincode and its container runtime environment.
    63  func (c *ContainerRuntime) Stop(ccid string) error {
    64  	if err := c.ContainerRouter.Stop(ccid); err != nil {
    65  		return errors.WithMessage(err, "error stopping container")
    66  	}
    67  
    68  	return nil
    69  }
    70  
    71  // Wait waits for the container runtime to terminate.
    72  func (c *ContainerRuntime) Wait(ccid string) (int, error) {
    73  	return c.ContainerRouter.Wait(ccid)
    74  }