feat: add 'start' app method, add state transition checks

This commit is contained in:
2025-06-23 15:16:04 -05:00
parent fc96753188
commit 486b425e99

View File

@@ -1,6 +1,7 @@
package app package app
import ( import (
"fmt"
"log/slog" "log/slog"
"sync" "sync"
) )
@@ -25,15 +26,55 @@ const (
func NewApp(logger *slog.Logger) *App { func NewApp(logger *slog.Logger) *App {
return &App{ return &App{
logger: logger, logger: logger,
state: StateRunning, state: StateStopped,
} }
} }
// Start transitions the application from Stopped or Paused to Running
func (app *App) Start() error {
app.mu.Lock()
defer app.mu.Unlock()
switch app.state {
case StateRunning:
return fmt.Errorf("application is already running")
case StateStopped, StatePaused:
// valid states to start from, do nothing
default:
return fmt.Errorf("cannot start application from state: %s", app.state)
}
app.logger.Info("starting application",
"action", "start",
"previous_state", app.state,
"new_state", StateRunning)
// TODO: Implement actual start logic
// - Connect to Home Assistant WebSocket
// - Start background tasks
// - Start sensor monitoring
app.state = StateRunning
app.logger.Info("started successfully",
"action", "start",
"state", app.state)
return nil
}
// Pause disconnects from the server and ceases any background tasks // Pause disconnects from the server and ceases any background tasks
func (app *App) Pause() error { func (app *App) Pause() error {
app.mu.Lock() app.mu.Lock()
defer app.mu.Unlock() defer app.mu.Unlock()
switch app.state {
case StatePaused:
return fmt.Errorf("application is already paused")
case StateStopped:
return fmt.Errorf("cannot pause application when stopped")
}
app.logger.Info("pausing application", app.logger.Info("pausing application",
"action", "pause", "action", "pause",
"previous_state", app.state, "previous_state", app.state,
@@ -58,6 +99,17 @@ func (app *App) Resume() error {
app.mu.Lock() app.mu.Lock()
defer app.mu.Unlock() defer app.mu.Unlock()
switch app.state {
case StateRunning:
return fmt.Errorf("application is already running")
case StateStopped:
return fmt.Errorf("cannot resume application when stopped, instead, start the application")
case StatePaused:
// valid state to resume from, do nothing
default:
return fmt.Errorf("cannot resume application from state: %s", app.state)
}
app.logger.Info("resuming application", app.logger.Info("resuming application",
"action", "resume", "action", "resume",
"previous_state", app.state, "previous_state", app.state,
@@ -79,18 +131,37 @@ func (app *App) Resume() error {
// Reload pauses the application, re-reads configuration files, then resumes // Reload pauses the application, re-reads configuration files, then resumes
func (a *App) Reload() error { func (a *App) Reload() error {
a.mu.Lock()
defer a.mu.Unlock()
switch a.state {
case StateStopped:
return fmt.Errorf("cannot reload application when stopped")
case StatePaused:
return fmt.Errorf("cannot reload application when paused")
case StateRunning:
// valid state to reload from, do nothing
default:
return fmt.Errorf("cannot reload application from state: %s", a.state)
}
a.logger.Info("starting application reload", a.logger.Info("starting application reload",
"action", "reload", "action", "reload",
"current_state", a.state) "current_state", a.state)
// Pause if not already paused // Pause if not already paused
if a.state != StatePaused { switch a.state {
case StatePaused:
// already paused, do nothing
case StateRunning:
if err := a.Pause(); err != nil { if err := a.Pause(); err != nil {
a.logger.Error("failed to pause during reload", a.logger.Error("failed to pause during reload",
"action", "reload", "action", "reload",
"error", err) "error", err)
return err return err
} }
default:
return fmt.Errorf("unexpected state encountered while pausing for reload: %s", a.state)
} }
// TODO: Implement configuration reload logic // TODO: Implement configuration reload logic
@@ -103,7 +174,7 @@ func (a *App) Reload() error {
// Resume the application // Resume the application
if err := a.Resume(); err != nil { if err := a.Resume(); err != nil {
a.logger.Error("failed to resume after reload", a.logger.Error("failed to resume during reload",
"action", "reload", "action", "reload",
"error", err) "error", err)
return err return err
@@ -128,6 +199,15 @@ func (app *App) Stop() error {
app.mu.Lock() app.mu.Lock()
defer app.mu.Unlock() defer app.mu.Unlock()
switch app.state {
case StateStopped:
return fmt.Errorf("application is already stopped")
case StatePaused, StateRunning:
// valid state to stop from, do nothing
default:
return fmt.Errorf("unexpected state encountered while stopping application: %s", app.state)
}
app.logger.Info("stopping application", app.logger.Info("stopping application",
"action", "stop", "action", "stop",
"previous_state", app.state, "previous_state", app.state,