Fix race condition and flawed logic mis-querying panel for servers; closes pterodactyl/panel#3059

This commit is contained in:
Dane Everitt 2021-02-01 20:26:15 -08:00
parent de9b413bc2
commit 1393937904
No known key found for this signature in database
GPG Key ID: EEA66103B3D71F53
2 changed files with 18 additions and 18 deletions

View File

@ -71,31 +71,31 @@ func (c *client) GetServersPaged(ctx context.Context, page, limit int) ([]api.Ra
return r.Data, r.Meta, nil return r.Data, r.Meta, nil
} }
func (c *client) GetServers(ctx context.Context, perPage int) ([]api.RawServerData, error) { // GetServers returns all of the servers that are present on the Panel making
servers, pageMeta, err := c.GetServersPaged(ctx, 0, perPage) // parallel API calls to the endpoint if more than one page of servers is returned.
func (c *client) GetServers(ctx context.Context, limit int) ([]api.RawServerData, error) {
servers, meta, err := c.GetServersPaged(ctx, 0, limit)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// if the amount of servers exceeds the page limit, get the remaining pages in parallel var mu sync.Mutex
if pageMeta.LastPage > 1 { if meta.LastPage > 1 {
eg, _ := errgroup.WithContext(ctx) g, ctx := errgroup.WithContext(ctx)
serversMu := sync.Mutex{} for page := meta.CurrentPage + 1; page <= meta.LastPage; page++ {
page := page
for page := pageMeta.CurrentPage + 1; page <= pageMeta.LastPage; page++ { g.Go(func() error {
eg.Go(func() error { ps, _, err := c.GetServersPaged(ctx, int(page), limit)
ps, _, err := c.GetServersPaged(ctx, perPage, int(page))
if err != nil { if err != nil {
return err return err
} }
serversMu.Lock() mu.Lock()
servers = append(servers, ps...) servers = append(servers, ps...)
serversMu.Unlock() mu.Unlock()
return nil return nil
}) })
} }
if err := g.Wait(); err != nil {
if err := eg.Wait(); err != nil {
return nil, err return nil, err
} }
} }

View File

@ -28,11 +28,11 @@ type Manager struct {
// the servers that are currently present on the filesystem and set them into // the servers that are currently present on the filesystem and set them into
// the manager. // the manager.
func NewManager(ctx context.Context, client remote.Client) (*Manager, error) { func NewManager(ctx context.Context, client remote.Client) (*Manager, error) {
c := NewEmptyManager() m := NewEmptyManager()
if err := c.initializeFromRemoteSource(ctx, client); err != nil { if err := m.init(ctx, client); err != nil {
return nil, err return nil, err
} }
return c, nil return m, nil
} }
// NewEmptyManager returns a new empty manager collection without actually // NewEmptyManager returns a new empty manager collection without actually
@ -44,7 +44,7 @@ func NewEmptyManager() *Manager {
// initializeFromRemoteSource iterates over a given directory and loads all of // initializeFromRemoteSource iterates over a given directory and loads all of
// the servers listed before returning them to the calling function. // the servers listed before returning them to the calling function.
func (m *Manager) initializeFromRemoteSource(ctx context.Context, client remote.Client) error { func (m *Manager) init(ctx context.Context, client remote.Client) error {
log.Info("fetching list of servers from API") log.Info("fetching list of servers from API")
servers, err := client.GetServers(ctx, config.Get().RemoteQuery.BootServersPerPage) servers, err := client.GetServers(ctx, config.Get().RemoteQuery.BootServersPerPage)
if err != nil { if err != nil {