✨ Process lifecycle management
This commit is contained in:
@@ -15,8 +15,5 @@ func InitializeWarden(regions []*Region) {
|
||||
|
||||
// Hot swap
|
||||
warden.InstancePool = pool
|
||||
|
||||
for _, instance := range warden.InstancePool {
|
||||
instance.Wake()
|
||||
}
|
||||
warden.StartPool()
|
||||
}
|
||||
|
@@ -8,8 +8,13 @@ import (
|
||||
)
|
||||
|
||||
func getApplications(c *fiber.Ctx) error {
|
||||
applications := lo.FlatMap(navi.R.Regions, func(item *navi.Region, idx int) []warden.Application {
|
||||
return item.Applications
|
||||
applications := lo.FlatMap(navi.R.Regions, func(item *navi.Region, idx int) []warden.ApplicationInfo {
|
||||
return lo.Map(item.Applications, func(item warden.Application, index int) warden.ApplicationInfo {
|
||||
return warden.ApplicationInfo{
|
||||
Application: item,
|
||||
Status: warden.GetFromPool(item.ID).Status,
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
return c.JSON(applications)
|
||||
@@ -24,3 +29,45 @@ func getApplicationLogs(c *fiber.Ctx) error {
|
||||
return c.SendString(instance.Logs())
|
||||
}
|
||||
}
|
||||
|
||||
func letApplicationStart(c *fiber.Ctx) error {
|
||||
if instance, ok := lo.Find(warden.InstancePool, func(item *warden.AppInstance) bool {
|
||||
return item.Manifest.ID == c.Params("id")
|
||||
}); !ok {
|
||||
return fiber.NewError(fiber.StatusNotFound)
|
||||
} else {
|
||||
if err := instance.Wake(); err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||
}
|
||||
return c.SendStatus(fiber.StatusOK)
|
||||
}
|
||||
}
|
||||
|
||||
func letApplicationStop(c *fiber.Ctx) error {
|
||||
if instance, ok := lo.Find(warden.InstancePool, func(item *warden.AppInstance) bool {
|
||||
return item.Manifest.ID == c.Params("id")
|
||||
}); !ok {
|
||||
return fiber.NewError(fiber.StatusNotFound)
|
||||
} else {
|
||||
if err := instance.Stop(); err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||
}
|
||||
return c.SendStatus(fiber.StatusOK)
|
||||
}
|
||||
}
|
||||
|
||||
func letApplicationRestart(c *fiber.Ctx) error {
|
||||
if instance, ok := lo.Find(warden.InstancePool, func(item *warden.AppInstance) bool {
|
||||
return item.Manifest.ID == c.Params("id")
|
||||
}); !ok {
|
||||
return fiber.NewError(fiber.StatusNotFound)
|
||||
} else {
|
||||
if err := instance.Stop(); err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||
}
|
||||
if err := instance.Start(); err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||
}
|
||||
return c.SendStatus(fiber.StatusOK)
|
||||
}
|
||||
}
|
||||
|
@@ -49,6 +49,9 @@ func InitSideload() *fiber.App {
|
||||
cgi.Get("/regions/cfg/:id", getRegionConfig)
|
||||
cgi.Get("/applications", getApplications)
|
||||
cgi.Get("/applications/:id/logs", getApplicationLogs)
|
||||
cgi.Post("/applications/:id/start", letApplicationStart)
|
||||
cgi.Post("/applications/:id/stop", letApplicationStop)
|
||||
cgi.Post("/applications/:id/restart", letApplicationRestart)
|
||||
|
||||
cgi.Post("/reload", doReload)
|
||||
}
|
||||
|
@@ -2,10 +2,11 @@ package warden
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"github.com/rs/zerolog/log"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/samber/lo"
|
||||
@@ -87,15 +88,16 @@ func (v *AppInstance) Start() error {
|
||||
// Monitor
|
||||
go func() {
|
||||
for {
|
||||
if v.Cmd.Process == nil || v.Cmd.ProcessState == nil {
|
||||
if v.Cmd != nil && v.Cmd.Process == nil {
|
||||
v.Status = AppStarting
|
||||
} else if !v.Cmd.ProcessState.Exited() {
|
||||
} else if v.Cmd != nil && v.Cmd.ProcessState == nil {
|
||||
v.Status = AppStarted
|
||||
} else {
|
||||
v.Status = lo.Ternary(v.Cmd.ProcessState.Success(), AppExited, AppFailure)
|
||||
v.Status = lo.Ternary(v.Cmd == nil, AppExited, AppFailure)
|
||||
v.Cmd = nil
|
||||
return
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
time.Sleep(1000 * time.Millisecond)
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -104,8 +106,13 @@ func (v *AppInstance) Start() error {
|
||||
|
||||
func (v *AppInstance) Stop() error {
|
||||
if v.Cmd != nil && v.Cmd.Process != nil {
|
||||
if err := v.Cmd.Process.Signal(os.Interrupt); err != nil {
|
||||
v.Cmd.Process.Kill()
|
||||
if err := v.Cmd.Process.Signal(syscall.SIGTERM); err != nil {
|
||||
log.Warn().Int("pid", v.Cmd.Process.Pid).Err(err).Msgf("Failed to send SIGTERM to process...")
|
||||
if err = v.Cmd.Process.Kill(); err != nil {
|
||||
log.Error().Int("pid", v.Cmd.Process.Pid).Err(err).Msgf("Failed to kill process...")
|
||||
} else {
|
||||
v.Cmd = nil
|
||||
}
|
||||
return err
|
||||
} else {
|
||||
v.Cmd = nil
|
||||
|
@@ -6,3 +6,8 @@ type Application struct {
|
||||
Command []string `json:"command" toml:"command"`
|
||||
Environment []string `json:"environment" toml:"environment"`
|
||||
}
|
||||
|
||||
type ApplicationInfo struct {
|
||||
Application
|
||||
Status AppStatus `json:"status"`
|
||||
}
|
||||
|
Reference in New Issue
Block a user