Improve server state logical handling; allow setting state directly on the environment

This commit is contained in:
Dane Everitt
2020-11-06 21:53:00 -08:00
parent 3fce1b98d5
commit 944d381778
13 changed files with 73 additions and 105 deletions

View File

@@ -60,7 +60,7 @@ func (e *Environment) Attach() error {
defer cancel()
defer e.stream.Close()
defer func() {
e.setState(environment.ProcessOfflineState)
e.SetState(environment.ProcessOfflineState)
e.SetStream(nil)
}()
@@ -245,7 +245,7 @@ func (e *Environment) convertMounts() []mount.Mount {
// it will be forcibly stopped by Docker.
func (e *Environment) Destroy() error {
// We set it to stopping than offline to prevent crash detection from being triggered.
e.setState(environment.ProcessStoppingState)
e.SetState(environment.ProcessStoppingState)
err := e.client.ContainerRemove(context.Background(), e.Id, types.ContainerRemoveOptions{
RemoveVolumes: true,
@@ -261,7 +261,7 @@ func (e *Environment) Destroy() error {
return nil
}
e.setState(environment.ProcessOfflineState)
e.SetState(environment.ProcessOfflineState)
return err
}

View File

@@ -48,7 +48,7 @@ type Environment struct {
emitter *events.EventBus
// Tracks the environment state.
State system.AtomicString
st system.AtomicString
}
// Creates a new base Docker environment. The ID passed through will be the ID that is used to
@@ -67,7 +67,7 @@ func New(id string, m *Metadata, c *environment.Configuration) (*Environment, er
client: cli,
}
e.State.Store(environment.ProcessOfflineState)
e.st.Store(environment.ProcessOfflineState)
return e, nil
}

View File

@@ -57,8 +57,8 @@ func (e *Environment) Start() error {
// If we don't set it to stopping first, you'll trigger crash detection which
// we don't want to do at this point since it'll just immediately try to do the
// exact same action that lead to it crashing in the first place...
e.setState(environment.ProcessStoppingState)
e.setState(environment.ProcessOfflineState)
e.SetState(environment.ProcessStoppingState)
e.SetState(environment.ProcessOfflineState)
}
}()
@@ -74,7 +74,7 @@ func (e *Environment) Start() error {
} else {
// If the server is running update our internal state and continue on with the attach.
if c.State.Running {
e.setState(environment.ProcessRunningState)
e.SetState(environment.ProcessRunningState)
return e.Attach()
}
@@ -89,7 +89,7 @@ func (e *Environment) Start() error {
}
}
e.setState(environment.ProcessStartingState)
e.SetState(environment.ProcessStartingState)
// Set this to true for now, we will set it to false once we reach the
// end of this chain.
@@ -136,8 +136,8 @@ func (e *Environment) Stop() error {
// If the process is already offline don't switch it back to stopping. Just leave it how
// it is and continue through to the stop handling for the process.
if e.State.Load() != environment.ProcessOfflineState {
e.setState(environment.ProcessStoppingState)
if e.st.Load() != environment.ProcessOfflineState {
e.SetState(environment.ProcessStoppingState)
}
// Only attempt to send the stop command to the instance if we are actually attached to
@@ -153,7 +153,7 @@ func (e *Environment) Stop() error {
// an error.
if client.IsErrNotFound(err) {
e.SetStream(nil)
e.setState(environment.ProcessOfflineState)
e.SetState(environment.ProcessOfflineState)
return nil
}
@@ -217,16 +217,16 @@ func (e *Environment) Terminate(signal os.Signal) error {
// If the container is not running but we're not already in a stopped state go ahead
// and update things to indicate we should be completely stopped now. Set to stopping
// first so crash detection is not triggered.
if e.State.Load() != environment.ProcessOfflineState {
e.setState(environment.ProcessStoppingState)
e.setState(environment.ProcessOfflineState)
if e.st.Load() != environment.ProcessOfflineState {
e.SetState(environment.ProcessStoppingState)
e.SetState(environment.ProcessOfflineState)
}
return nil
}
// We set it to stopping than offline to prevent crash detection from being triggered.
e.setState(environment.ProcessStoppingState)
e.SetState(environment.ProcessStoppingState)
sig := strings.TrimSuffix(strings.TrimPrefix(signal.String(), "signal "), "ed")
@@ -234,7 +234,7 @@ func (e *Environment) Terminate(signal os.Signal) error {
return err
}
e.setState(environment.ProcessOfflineState)
e.SetState(environment.ProcessOfflineState)
return nil
}

View File

@@ -6,25 +6,24 @@ import (
"github.com/pterodactyl/wings/environment"
)
func (e *Environment) State() string {
return e.st.Load()
}
// Sets the state of the environment. This emits an event that server's can hook into to
// take their own actions and track their own state based on the environment.
func (e *Environment) setState(state string) error {
func (e *Environment) SetState(state string) {
if state != environment.ProcessOfflineState &&
state != environment.ProcessStartingState &&
state != environment.ProcessRunningState &&
state != environment.ProcessStoppingState {
return errors.New(fmt.Sprintf("invalid server state received: %s", state))
panic(errors.New(fmt.Sprintf("invalid server state received: %s", state)))
}
// Get the current state of the environment before changing it.
prevState := e.State.Load()
// Emit the event to any listeners that are currently registered.
if prevState != state {
if e.State() != state {
// If the state changed make sure we update the internal tracking to note that.
e.State.Store(state)
e.st.Store(state)
e.Events().Publish(environment.StateChangeEvent, state)
}
return nil
}

View File

@@ -20,7 +20,7 @@ func (e *Environment) pollResources(ctx context.Context) error {
l.Debug("starting resource polling for container")
defer l.Debug("stopped resource polling for container")
if e.State.Load() == environment.ProcessOfflineState {
if e.st.Load() == environment.ProcessOfflineState {
return errors.New("cannot enable resource polling on a stopped server")
}
@@ -50,7 +50,7 @@ func (e *Environment) pollResources(ctx context.Context) error {
}
// Disable collection if the server is in an offline state and this process is still running.
if e.State.Load() == environment.ProcessOfflineState {
if e.st.Load() == environment.ProcessOfflineState {
l.Debug("process in offline state while resource polling is still active; stopping poll")
return nil
}

View File

@@ -37,7 +37,7 @@ func (e *Environment) SendCommand(c string) error {
// the server as entering the stopping state otherwise the process will stop and Wings will think
// it has crashed and attempt to restart it.
if e.meta.Stop.Type == "command" && c == e.meta.Stop.Value {
e.Events().Publish(environment.StateChangeEvent, environment.ProcessStoppingState)
e.SetState(environment.ProcessStoppingState)
}
_, err := e.stream.Conn.Write([]byte(c + "\n"))