Remove use of semaphore while restarting; covered by changed power actions handling

This commit is contained in:
Dane Everitt 2020-08-01 15:22:39 -07:00
parent 177aa8e436
commit 78c5fd219a
No known key found for this signature in database
GPG Key ID: EEA66103B3D71F53

View File

@ -16,7 +16,6 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/pterodactyl/wings/api" "github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/config" "github.com/pterodactyl/wings/config"
"golang.org/x/sync/semaphore"
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
@ -47,10 +46,6 @@ type DockerEnvironment struct {
// Holds the stats stream used by the polling commands so that we can easily close // Holds the stats stream used by the polling commands so that we can easily close
// it out. // it out.
stats io.ReadCloser stats io.ReadCloser
// Locks when we're performing a restart to avoid trying to restart a process that is already
// being restarted.
restartSem *semaphore.Weighted
} }
// Set if this process is currently attached to the process. // Set if this process is currently attached to the process.
@ -325,60 +320,19 @@ func (d *DockerEnvironment) Stop() error {
return nil return nil
} }
// Try to acquire a lock to restart the server. If one cannot be obtained within 5 seconds return
// an error to the caller. You should ideally be checking IsRestarting() before calling this function
// to avoid unnecessary delays since you can respond immediately from that.
func (d *DockerEnvironment) acquireRestartLock() error {
if d.restartSem == nil {
d.restartSem = semaphore.NewWeighted(1)
}
ctx, _ := context.WithTimeout(context.Background(), time.Second*5)
return d.restartSem.Acquire(ctx, 1)
}
// Restarts the server process by waiting for the process to gracefully stop and then triggering a // Restarts the server process by waiting for the process to gracefully stop and then triggering a
// start command. This will return an error if there is already a restart process executing for the // start command. This will return an error if there is already a restart process executing for the
// server. The lock is released when the process is stopped and a start has begun. // server. The lock is released when the process is stopped and a start has begun.
func (d *DockerEnvironment) Restart() error { func (d *DockerEnvironment) Restart() error {
d.Server.Log().Debug("acquiring process restart lock...")
if err := d.acquireRestartLock(); err != nil {
d.Server.Log().Warn("failed to acquire restart lock; already acquired by a different process")
return err
}
d.Server.Log().Info("acquired process lock; beginning restart process...")
err := d.WaitForStop(60, false) err := d.WaitForStop(60, false)
if err != nil { if err != nil {
d.restartSem.Release(1)
return err return err
} }
// Release the restart lock, it is now safe for someone to attempt restarting the server again.
d.restartSem.Release(1)
// Start the process. // Start the process.
return d.Start() return d.Start()
} }
// Check if the server is currently running the restart process by checking if there is a semaphore
// allocated, and if so, if we can acquire a lock on it.
func (d *DockerEnvironment) IsRestarting() bool {
if d.restartSem == nil {
return false
}
if d.restartSem.TryAcquire(1) {
d.restartSem.Release(1)
return false
}
return true
}
// Attempts to gracefully stop a server using the defined stop command. If the server // Attempts to gracefully stop a server using the defined stop command. If the server
// does not stop after seconds have passed, an error will be returned, or the instance // does not stop after seconds have passed, an error will be returned, or the instance
// will be terminated forcefully depending on the value of the second argument. // will be terminated forcefully depending on the value of the second argument.