Skip to content

Commit

Permalink
[FAB-10899] ignore context in VMController
Browse files Browse the repository at this point in the history
In go, a context is an object that carries cancellation signals across
API boundaries. In fabric, contexts are associated with gRPC requests
and get propagated through the system. When a request to invoke
chaincode is received, the context is propagated to the controller
responsible for managing container requests where it is misused.

The controller spawns a go routine to handle the container request and
signals completion via a channel. The Process function then waits for
the request to complete or for the context to get canceled. When the
context it canceled, the processor still waits for the request to
complete before returning to the caller. This means the operation is
never really canceled at this layer and, since it has to complete,
it's likely that it has succeeded.

Unfortunately, once the context is canceled, the controller returns the
cancellation error from the context causing the callers to treat the
operation as a failure.

As the code downstream of the controller doesn't properly honor the
context either and future releases remove it entirely, we'll simply
ignore context cancellation signals in the controller.

Change-Id: I51d8be9ef41e586c982abe268e6f9e0d61d4d7a7
Signed-off-by: Matthew Sykes <sykesmat@us.ibm.com>
  • Loading branch information
sykesm authored and mastersingh24 committed Jul 10, 2018
1 parent 6d4bf4e commit 613e845
Showing 1 changed file with 5 additions and 28 deletions.
33 changes: 5 additions & 28 deletions core/container/controller.go
Expand Up @@ -162,37 +162,14 @@ func (si StopContainerReq) GetCCID() ccintf.CCID {
return si.CCID
}

//Process should be used as follows
// . construct a context
// . construct req of the right type (e.g., CreateImageReq)
// . call it in a go routine
// . process response in the go routing
//context can be cancelled. VMCProcess will try to cancel calling functions if it can
//For instance docker clients api's such as BuildImage are not cancelable.
//In all cases VMCProcess will wait for the called go routine to return
func (vmc *VMController) Process(ctxt context.Context, vmtype string, req VMCReq) error {
v := vmc.newVM(vmtype)
ccid := req.GetCCID()
id := ccid.GetName()

c := make(chan error)
go func() {
ccid := req.GetCCID()
id := ccid.GetName()
vmc.lockContainer(id)
err := req.Do(ctxt, v)
vmc.unlockContainer(id)
c <- err
}()

select {
case err := <-c:
return err
case <-ctxt.Done():
//TODO cancel req.do ... (needed) ?
// XXX This logic doesn't make much sense, why return the context error if it's canceled,
// but still wait for the request to complete, and ignore its error
<-c
return ctxt.Err()
}
vmc.lockContainer(id)
defer vmc.unlockContainer(id)
return req.Do(ctxt, v)
}

// GetChaincodePackageBytes creates bytes for docker container generation using the supplied chaincode specification
Expand Down

0 comments on commit 613e845

Please sign in to comment.