// GetResponse looks up a response matching the specified cmdID. If the // response is found, it is returned along with its associated error. // If the response is not found, nil is returned for both the response // and its error. In all cases, the third return value is the error // returned from the engine when reading the on-disk cache. func (rc *ResponseCache) GetResponse(e engine.Engine, cmdID proto.ClientCmdID) (proto.ResponseWithError, error) { // Do nothing if command ID is empty. if cmdID.IsEmpty() { return proto.ResponseWithError{}, nil } // Pull response from the cache and read into reply if available. var rcEntry proto.ResponseCacheEntry key := keys.ResponseCacheKey(rc.rangeID, &cmdID) ok, err := engine.MVCCGetProto(e, key, proto.ZeroTimestamp, true, nil, &rcEntry) if err != nil { return proto.ResponseWithError{}, err } if ok { resp := rcEntry.GetValue().(proto.Response) header := resp.Header() defer func() { header.Error = nil }() return proto.ResponseWithError{Reply: resp, Err: header.GoError()}, nil } return proto.ResponseWithError{}, nil }
// PutResponse writes a response and an error associated with it to the // cache for the specified cmdID. func (rc *ResponseCache) PutResponse(e engine.Engine, cmdID proto.ClientCmdID, replyWithErr proto.ResponseWithError) error { // Do nothing if command ID is empty. if cmdID.IsEmpty() { return nil } // Write the response value to the engine. if rc.shouldCacheResponse(replyWithErr) { // Write the error into the reply before caching. header := replyWithErr.Reply.Header() header.SetGoError(replyWithErr.Err) // Be sure to clear it when you're done! defer func() { header.Error = nil }() key := keys.ResponseCacheKey(rc.rangeID, &cmdID) var rcEntry proto.ResponseCacheEntry if !rcEntry.SetValue(replyWithErr.Reply) { panic(fmt.Sprintf("response %T not supported by response cache", replyWithErr.Reply)) } return engine.MVCCPutProto(e, nil, key, proto.ZeroTimestamp, nil, &rcEntry) } return nil }