Add simple service dependency system

This commit is contained in:
EnumDev 2025-03-03 22:05:21 +02:00
parent f59dc1b7ce
commit ec92777135

View File

@ -31,6 +31,7 @@ const (
type EnitService struct { type EnitService struct {
Name string `yaml:"name"` Name string `yaml:"name"`
Description string `yaml:"description,omitempty"` Description string `yaml:"description,omitempty"`
Dependencies []string `yaml:"dependencies,omitempty"`
Type string `yaml:"type"` Type string `yaml:"type"`
StartCmd string `yaml:"start_cmd"` StartCmd string `yaml:"start_cmd"`
ExitMethod string `yaml:"exit_method"` ExitMethod string `yaml:"exit_method"`
@ -125,6 +126,7 @@ func Init() {
logger.Fatalf("Could not initialize ESVM! Error: %s", err) logger.Fatalf("Could not initialize ESVM! Error: %s", err)
} }
// Read and initialize service files
for _, entry := range dirEntries { for _, entry := range dirEntries {
if !entry.IsDir() && strings.HasSuffix(entry.Name(), ".esv") { if !entry.IsDir() && strings.HasSuffix(entry.Name(), ".esv") {
logger.Printf("Initializing service (%s)...\n", entry.Name()) logger.Printf("Initializing service (%s)...\n", entry.Name())
@ -137,6 +139,7 @@ func Init() {
service := EnitService{ service := EnitService{
Name: "", Name: "",
Description: "", Description: "",
Dependencies: make([]string, 0),
Type: "", Type: "",
StartCmd: "", StartCmd: "",
ExitMethod: "", ExitMethod: "",
@ -178,11 +181,46 @@ func Init() {
Services = append(Services, service) Services = append(Services, service)
if err := service.StartService(); err != nil { logger.Printf("Service (%s) has been initialized!\n", service.Name)
logger.Printf("Could not start service %s: %s\n", service.Name, err) }
} }
logger.Printf("Service (%s) has been initialized!\n", service.Name) // Get services that meet their dependencies
servicesWithMetDepends := make([]EnitService, 0)
for _, service := range Services {
if len(service.GetUnmetDependencies()) == 0 {
servicesWithMetDepends = append(servicesWithMetDepends, service)
}
}
// Loop until all services have started or timed out
for start := time.Now(); time.Since(start) < 60*time.Second; {
if len(servicesWithMetDepends) == 0 {
break
}
for i := len(servicesWithMetDepends) - 1; i >= 0; i-- {
service := servicesWithMetDepends[i]
canStart := true
for _, dependency := range service.Dependencies {
if GetServiceByName(dependency).GetCurrentState() != EnitServiceRunning && GetServiceByName(dependency).GetCurrentState() != EnitServiceCompleted {
canStart = false
break
}
}
if canStart {
err := service.StartService()
if err != nil {
logger.Printf("Could not start service (%s)! Error: %s", service.Name, err)
}
servicesWithMetDepends = append(servicesWithMetDepends[:i], servicesWithMetDepends[i+1:]...)
}
}
}
if len(servicesWithMetDepends) > 0 {
for _, service := range servicesWithMetDepends {
logger.Printf("Could not start service (%s)! Error: dependencies not met", service.Name)
} }
} }
@ -208,6 +246,17 @@ func GetServiceByName(name string) *EnitService {
return nil return nil
} }
func (service *EnitService) GetUnmetDependencies() (missingDependencies []string) {
for _, dependency := range service.Dependencies {
depService := GetServiceByName(dependency)
if depService == nil {
missingDependencies = append(missingDependencies, dependency)
}
}
return missingDependencies
}
func (service *EnitService) GetProcess() *os.Process { func (service *EnitService) GetProcess() *os.Process {
bytes, err := os.ReadFile(path.Join(service.ServiceRunPath, "process")) bytes, err := os.ReadFile(path.Join(service.ServiceRunPath, "process"))
if err != nil { if err != nil {