func applyTxn(kv dstorage.KV, le lease.Lessor, rt *pb.TxnRequest) (*pb.TxnResponse, error) { var revision int64 ok := true for _, c := range rt.Compare { if revision, ok = applyCompare(kv, c); !ok { break } } var reqs []*pb.RequestUnion if ok { reqs = rt.Success } else { reqs = rt.Failure } if err := checkRequestLeases(le, reqs); err != nil { return nil, err } if err := checkRequestRange(kv, reqs); err != nil { return nil, err } // When executing the operations of txn, we need to hold the txn lock. // So the reader will not see any intermediate results. txnID := kv.TxnBegin() defer func() { err := kv.TxnEnd(txnID) if err != nil { panic(fmt.Sprint("unexpected error when closing txn", txnID)) } }() resps := make([]*pb.ResponseUnion, len(reqs)) for i := range reqs { resps[i] = applyUnion(txnID, kv, reqs[i]) } if len(resps) != 0 { revision += 1 } txnResp := &pb.TxnResponse{} txnResp.Header = &pb.ResponseHeader{} txnResp.Header.Revision = revision txnResp.Responses = resps txnResp.Succeeded = ok return txnResp, nil }
func applyTxn(kv dstorage.KV, le lease.Lessor, rt *pb.TxnRequest) (*pb.TxnResponse, error) { var revision int64 txnID := kv.TxnBegin() defer func() { err := kv.TxnEnd(txnID) if err != nil { panic(fmt.Sprint("unexpected error when closing txn", txnID)) } }() ok := true for _, c := range rt.Compare { if revision, ok = applyCompare(txnID, kv, c); !ok { break } } // TODO: check potential errors before actually applying anything var reqs []*pb.RequestUnion if ok { reqs = rt.Success } else { reqs = rt.Failure } if err := checkRequestLeases(le, reqs); err != nil { return nil, err } resps := make([]*pb.ResponseUnion, len(reqs)) for i := range reqs { resps[i] = applyUnion(txnID, kv, reqs[i]) } if len(resps) != 0 { revision += 1 } txnResp := &pb.TxnResponse{} txnResp.Header = &pb.ResponseHeader{} txnResp.Header.Revision = revision txnResp.Responses = resps txnResp.Succeeded = ok return txnResp, nil }