diff --git a/server/cluster/cluster.go b/server/cluster/cluster.go index 1c7066bca29..ee61b9f0ecb 100644 --- a/server/cluster/cluster.go +++ b/server/cluster/cluster.go @@ -1609,12 +1609,19 @@ func (c *RaftCluster) GetHotReadRegions() *statistics.StoreHotPeersInfos { } // GetSchedulers gets all schedulers. -func (c *RaftCluster) GetSchedulers() map[string]*scheduleController { +func (c *RaftCluster) GetSchedulers() []string { c.RLock() defer c.RUnlock() return c.coordinator.getSchedulers() } +// GetSchedulerHandlers gets all scheduler handlers. +func (c *RaftCluster) GetSchedulerHandlers() map[string]http.Handler { + c.RLock() + defer c.RUnlock() + return c.coordinator.getSchedulerHandlers() +} + // AddScheduler adds a scheduler. func (c *RaftCluster) AddScheduler(scheduler schedule.Scheduler, args ...string) error { c.Lock() @@ -1636,6 +1643,13 @@ func (c *RaftCluster) PauseOrResumeScheduler(name string, t int64) error { return c.coordinator.pauseOrResumeScheduler(name, t) } +// IsSchedulerPaused checks if a scheduler is paused. +func (c *RaftCluster) IsSchedulerPaused(name string) (bool, error) { + c.RLock() + defer c.RUnlock() + return c.coordinator.isSchedulerPaused(name) +} + // GetStoreLimiter returns the dynamic adjusting limiter func (c *RaftCluster) GetStoreLimiter() *StoreLimiter { return c.limiter diff --git a/server/cluster/coordinator.go b/server/cluster/coordinator.go index 2b18a17a38f..4d1b916f762 100644 --- a/server/cluster/coordinator.go +++ b/server/cluster/coordinator.go @@ -16,6 +16,7 @@ package cluster import ( "context" "fmt" + "net/http" "sync" "sync/atomic" "time" @@ -354,10 +355,24 @@ func (c *coordinator) getHotReadRegions() *statistics.StoreHotPeersInfos { return nil } -func (c *coordinator) getSchedulers() map[string]*scheduleController { +func (c *coordinator) getSchedulers() []string { c.RLock() defer c.RUnlock() - return c.schedulers + names := make([]string, 0, len(c.schedulers)) + for name := range c.schedulers { + names = append(names, name) + } + return names +} + +func (c *coordinator) getSchedulerHandlers() map[string]http.Handler { + c.RLock() + defer c.RUnlock() + handlers := make(map[string]http.Handler, len(c.schedulers)) + for name, scheduler := range c.schedulers { + handlers[name] = scheduler.Scheduler + } + return handlers } func (c *coordinator) collectSchedulerMetrics() { @@ -535,6 +550,19 @@ func (c *coordinator) pauseOrResumeScheduler(name string, t int64) error { return err } +func (c *coordinator) isSchedulerPaused(name string) (bool, error) { + c.RLock() + defer c.RUnlock() + if c.cluster == nil { + return false, ErrNotBootstrapped + } + s, ok := c.schedulers[name] + if !ok { + return false, schedulers.ErrSchedulerNotFound + } + return s.IsPaused(), nil +} + func (c *coordinator) runScheduler(s *scheduleController) { defer logutil.LogPanic() defer c.wg.Done() diff --git a/server/handler.go b/server/handler.go index 4ef1be83266..fd6d132ac20 100644 --- a/server/handler.go +++ b/server/handler.go @@ -102,15 +102,11 @@ func (h *Handler) GetOperatorController() (*schedule.OperatorController, error) // IsSchedulerPaused returns whether scheduler is paused. func (h *Handler) IsSchedulerPaused(name string) (bool, error) { - c, err := h.GetRaftCluster() + rc, err := h.GetRaftCluster() if err != nil { - return true, err - } - sc, ok := c.GetSchedulers()[name] - if !ok { - return true, errors.Errorf("scheduler %v not found", name) + return false, err } - return sc.IsPaused(), nil + return rc.IsSchedulerPaused(name) } // GetScheduleConfig returns ScheduleConfig. @@ -124,11 +120,7 @@ func (h *Handler) GetSchedulers() ([]string, error) { if err != nil { return nil, err } - names := make([]string, 0, len(c.GetSchedulers())) - for name := range c.GetSchedulers() { - names = append(names, name) - } - return names, nil + return c.GetSchedulers(), nil } // GetStores returns all stores in the cluster. @@ -805,7 +797,7 @@ func (h *Handler) GetSchedulerConfigHandler() http.Handler { return nil } mux := http.NewServeMux() - for name, handler := range c.GetSchedulers() { + for name, handler := range c.GetSchedulerHandlers() { prefix := path.Join(pdRootPath, SchedulerConfigHandlerPath, name) urlPath := prefix + "/" mux.Handle(urlPath, http.StripPrefix(prefix, handler))