Skip to content

Commit

Permalink
pkg: add resource manager api (#1511)
Browse files Browse the repository at this point in the history
Signed-off-by: husharp <[email protected]>
  • Loading branch information
HuSharp authored and baurine committed May 8, 2023
1 parent a87bf5f commit 65110d9
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 0 deletions.
2 changes: 2 additions & 0 deletions pkg/apiserver/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import (

// "github.com/pingcap/tidb-dashboard/pkg/apiserver/__APP_NAME__"
// NOTE: Don't remove above comment line, it is a placeholder for code generator.
resourcemanager "github.com/pingcap/tidb-dashboard/pkg/apiserver/resource_manager"
"github.com/pingcap/tidb-dashboard/pkg/apiserver/slowquery"
"github.com/pingcap/tidb-dashboard/pkg/apiserver/statement"
"github.com/pingcap/tidb-dashboard/pkg/apiserver/user"
Expand Down Expand Up @@ -139,6 +140,7 @@ var Modules = fx.Options(
topsql.Module,
visualplan.Module,
deadlock.Module,
resourcemanager.Module,
)

func (s *Service) Start(ctx context.Context) error {
Expand Down
10 changes: 10 additions & 0 deletions pkg/apiserver/resource_manager/module.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright 2023 PingCAP, Inc. Licensed under Apache-2.0.

package resourcemanager

import "go.uber.org/fx"

var Module = fx.Options(
fx.Provide(newService),
fx.Invoke(registerRouter),
)
149 changes: 149 additions & 0 deletions pkg/apiserver/resource_manager/service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// Copyright 2023 PingCAP, Inc. Licensed under Apache-2.0.

package resourcemanager

import (
"fmt"
"net/http"

"github.com/gin-gonic/gin"
"go.uber.org/fx"

"github.com/pingcap/tidb-dashboard/pkg/apiserver/user"
"github.com/pingcap/tidb-dashboard/pkg/apiserver/utils"
"github.com/pingcap/tidb-dashboard/pkg/tidb"
"github.com/pingcap/tidb-dashboard/util/featureflag"
"github.com/pingcap/tidb-dashboard/util/rest"
)

type ServiceParams struct {
fx.In
TiDBClient *tidb.Client
}

type Service struct {
FeatureResourceManager *featureflag.FeatureFlag

params ServiceParams
}

func newService(p ServiceParams, ff *featureflag.Registry) *Service {
return &Service{params: p, FeatureResourceManager: ff.Register("resource_manager", ">= 7.1.0")}
}

func registerRouter(r *gin.RouterGroup, auth *user.AuthService, s *Service) {
endpoint := r.Group("/resource_manager")
endpoint.Use(
auth.MWAuthRequired(),
s.FeatureResourceManager.VersionGuard(),
utils.MWConnectTiDB(s.params.TiDBClient),
)
{
endpoint.GET("/information", s.GetInformation)
endpoint.GET("/config", s.GetConfig)
endpoint.GET("/calibrate/hardware", s.GetCalibrateByHardware)
endpoint.GET("/calibrate/actual", s.GetCalibrateByActual)
}
}

type GetConfigResponse struct {
Enable bool `json:"enable" gorm:"column:tidb_enable_resource_control"`
}

// @Summary Get Resource Control enable config
// @Router /resource_manager/config [get]
// @Security JwtAuth
// @Success 200 {string} enable
// @Failure 401 {object} rest.ErrorResponse
// @Failure 500 {object} rest.ErrorResponse
func (s *Service) GetConfig(c *gin.Context) {
db := utils.GetTiDBConnection(c)
resp := &GetConfigResponse{}
err := db.Raw("SELECT @@GLOBAL.tidb_enable_resource_control as tidb_enable_resource_control").Find(resp).Error
if err != nil {
rest.Error(c, err)
return
}
c.JSON(http.StatusOK, resp)
}

type ResourceInfoRowDef struct {
Name string `json:"name" gorm:"column:NAME"`
RuPerSec string `json:"ru_per_sec" gorm:"column:RU_PER_SEC"`
Priority string `json:"priority" gorm:"column:PRIORITY"`
Burstable string `json:"burstable" gorm:"column:BURSTABLE"`
}

// @Summary Get Information of Resource Groups
// @Router /resource_manager/information [get]
// @Security JwtAuth
// @Success 200 {object} []ResourceInfoRowDef
// @Failure 401 {object} rest.ErrorResponse
// @Failure 500 {object} rest.ErrorResponse
func (s *Service) GetInformation(c *gin.Context) {
db := utils.GetTiDBConnection(c)
var cfg []ResourceInfoRowDef
err := db.Table("INFORMATION_SCHEMA.RESOURCE_GROUPS").Scan(&cfg).Error
if err != nil {
rest.Error(c, err)
return
}
c.JSON(http.StatusOK, cfg)
}

type CalibrateResponse struct {
EstimatedCapacity int `json:"estimated_capacity" gorm:"column:QUOTA"`
}

// @Summary Get calibrate of Resource Groups by hardware deployment
// @Router /resource_manager/calibrate/hardware [get]
// @Param workload query string true "workload" default("tpcc")
// @Success 200 {object} CalibrateResponse
// @Failure 401 {object} rest.ErrorResponse
// @Failure 500 {object} rest.ErrorResponse
func (s *Service) GetCalibrateByHardware(c *gin.Context) {
w := c.Query("workload")
if w == "" {
rest.Error(c, rest.ErrBadRequest.New("workload cannot be empty"))
return
}

db := utils.GetTiDBConnection(c)
resp := &CalibrateResponse{}
err := db.Raw(fmt.Sprintf("calibrate resource workload %s", w)).Scan(resp).Error
if err != nil {
rest.Error(c, err)
return
}
c.JSON(http.StatusOK, resp)
}

// @Summary Get calibrate of Resource Groups by actual workload
// @Router /resource_manager/calibrate/actual [get]
// @Param start_time query string true "start_time"
// @Param end_time query string true "end_time"
// @Success 200 {object} CalibrateResponse
// @Failure 401 {object} rest.ErrorResponse
// @Failure 500 {object} rest.ErrorResponse
func (s *Service) GetCalibrateByActual(c *gin.Context) {
sTime := c.Query("start_time")
if sTime == "" {
rest.Error(c, rest.ErrBadRequest.New("start_time cannot be empty"))
return
}

eTime := c.Query("end_time")
if eTime == "" {
rest.Error(c, rest.ErrBadRequest.New("end_time cannot be empty"))
return
}

db := utils.GetTiDBConnection(c)
resp := &CalibrateResponse{}
err := db.Raw(fmt.Sprintf("calibrate resource start_time '%s' end_time '%s'", sTime, eTime)).Scan(resp).Error
if err != nil {
rest.Error(c, err)
return
}
c.JSON(http.StatusOK, resp)
}

0 comments on commit 65110d9

Please sign in to comment.