Skip to content

Commit

Permalink
Pay back WRU when the request fails
Browse files Browse the repository at this point in the history
Signed-off-by: JmPotato <ghzpotato@gmail.com>
  • Loading branch information
JmPotato committed Feb 8, 2023
1 parent cd381eb commit 78082cf
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 9 deletions.
4 changes: 2 additions & 2 deletions client/resource_manager/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ const (
maxNotificationChanLen = 200
)

// ResourceGroupKVInterceptor is used as quato limit controller for resource group using kv store.
// ResourceGroupKVInterceptor is used as quota limit controller for resource group using kv store.
type ResourceGroupKVInterceptor interface {
// OnRequestWait is used to check whether resource group has enough tokens. It maybe needs wait some time.
OnRequestWait(ctx context.Context, resourceGroupName string, info RequestInfo) error
// OnResponse is used to consume tokens atfer receiving response
// OnResponse is used to consume tokens after receiving response
OnResponse(ctx context.Context, resourceGroupName string, req RequestInfo, resp ResponseInfo) error
}

Expand Down
39 changes: 32 additions & 7 deletions client/resource_manager/client/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ type RequestInfo interface {
type ResponseInfo interface {
ReadBytes() uint64
KVCPUMs() uint64
// Succeed is used to tell whether the request is successfully returned.
// If not, we need to pay back the WRU cost of the request.
Succeed() bool
}

// ResourceCalculator is used to calculate the resource consumption of a request.
Expand Down Expand Up @@ -72,9 +75,7 @@ func (kc *KVCalculator) BeforeKVRequest(consumption *rmpb.Consumption, req Reque
if req.IsWrite() {
consumption.KvWriteRpcCount += 1
// Write bytes are knowable in advance, so we can calculate the WRU cost here.
writeBytes := float64(req.WriteBytes())
consumption.WriteBytes += writeBytes
consumption.WRU += float64(kc.WriteBaseCost) + float64(kc.WriteBytesCost)*writeBytes
kc.calculateWriteCost(consumption, req)
} else {
consumption.KvReadRpcCount += 1
// Read bytes could not be known before the request is executed,
Expand All @@ -83,20 +84,44 @@ func (kc *KVCalculator) BeforeKVRequest(consumption *rmpb.Consumption, req Reque
}
}

func (kc *KVCalculator) calculateWriteCost(consumption *rmpb.Consumption, req RequestInfo) {
writeBytes := float64(req.WriteBytes())
consumption.WriteBytes += writeBytes
consumption.WRU += float64(kc.WriteBaseCost) + float64(kc.WriteBytesCost)*writeBytes
}

// AfterKVRequest ...
func (kc *KVCalculator) AfterKVRequest(consumption *rmpb.Consumption, req RequestInfo, res ResponseInfo) {
// For now, we can only collect the KV CPU cost for a read request.
if !req.IsWrite() {
kvCPUMs := float64(res.KVCPUMs())
consumption.TotalCpuTimeMs += kvCPUMs
consumption.RRU += float64(kc.CPUMsCost) * kvCPUMs
// For now, we can only collect the KV CPU cost for a read request.
kc.calculateCPUCost(consumption, res)
} else if !res.Succeed() {
// If the write request is not successfully returned, we need to pay back the WRU cost.
kc.payBackWriteCost(consumption, req)
}
// A write request may also read data, which should be counted into the RRU cost.
// This part should be counted even if the request does not succeed.
kc.calculateReadCost(consumption, res)
}

func (kc *KVCalculator) calculateReadCost(consumption *rmpb.Consumption, res ResponseInfo) {
readBytes := float64(res.ReadBytes())
consumption.ReadBytes += readBytes
consumption.RRU += float64(kc.ReadBytesCost) * readBytes
}

func (kc *KVCalculator) calculateCPUCost(consumption *rmpb.Consumption, res ResponseInfo) {
kvCPUMs := float64(res.KVCPUMs())
consumption.TotalCpuTimeMs += kvCPUMs
consumption.RRU += float64(kc.CPUMsCost) * kvCPUMs
}

func (kc *KVCalculator) payBackWriteCost(consumption *rmpb.Consumption, req RequestInfo) {
writeBytes := float64(req.WriteBytes())
consumption.WriteBytes -= writeBytes
consumption.WRU -= float64(kc.WriteBaseCost) + float64(kc.WriteBytesCost)*writeBytes
}

// SQLCalculator is used to calculate the SQL-side consumption.
type SQLCalculator struct {
*Config
Expand Down

0 comments on commit 78082cf

Please sign in to comment.