// Copyright 2022 PingCAP, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package resourcemanager import ( "time" "github.com/google/uuid" "github.com/pingcap/tidb/pkg/resourcemanager/scheduler" "github.com/pingcap/tidb/pkg/resourcemanager/util" tidbutil "github.com/pingcap/tidb/pkg/util" "github.com/pingcap/tidb/pkg/util/cpu" ) // InstanceResourceManager is a local instance resource manager var InstanceResourceManager = NewResourceManger() // RandomName is to get a random name for register pool. It is just for test. func RandomName() string { return uuid.New().String() } // ResourceManager is a resource manager type ResourceManager struct { poolMap *util.ShardPoolMap scheduler []scheduler.Scheduler cpuObserver *cpu.Observer exitCh chan struct{} wg tidbutil.WaitGroupWrapper } // NewResourceManger is to create a new resource manager func NewResourceManger() *ResourceManager { sc := make([]scheduler.Scheduler, 0, 1) sc = append(sc, scheduler.NewCPUScheduler()) return &ResourceManager{ cpuObserver: cpu.NewCPUObserver(), exitCh: make(chan struct{}), poolMap: util.NewShardPoolMap(), scheduler: sc, } } // Start is to start resource manager func (r *ResourceManager) Start() { r.wg.Run(r.cpuObserver.Start) r.wg.Run(func() { tick := time.NewTicker(100 * time.Millisecond) defer tick.Stop() for { select { case <-tick.C: r.schedule() case <-r.exitCh: return } } }) } // Stop is to stop resource manager func (r *ResourceManager) Stop() { r.cpuObserver.Stop() close(r.exitCh) r.wg.Wait() } // Register is to register pool into resource manager func (r *ResourceManager) Register(pool util.GoroutinePool, name string, component util.Component) error { p := util.PoolContainer{Pool: pool, Component: component} return r.registerPool(name, &p) } func (r *ResourceManager) registerPool(name string, pool *util.PoolContainer) error { return r.poolMap.Add(name, pool) } // Unregister is to unregister pool into resource manager. func (r *ResourceManager) Unregister(name string) { r.poolMap.Del(name) } // Reset is to Reset resource manager. it is just for test. func (r *ResourceManager) Reset() { r.poolMap = util.NewShardPoolMap() }