227 lines
5.3 KiB
Go
227 lines
5.3 KiB
Go
package heroagent
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"sync"
|
|
|
|
"git.threefold.info/herocode/heroagent/pkg/servers/redisserver"
|
|
"git.threefold.info/herocode/heroagent/pkg/servers/ui"
|
|
"git.threefold.info/herocode/heroagent/pkg/servers/webdavserver"
|
|
"github.com/gofiber/fiber/v2"
|
|
)
|
|
|
|
// ServerFactory manages the lifecycle of all servers
|
|
type ServerFactory struct {
|
|
config Config
|
|
|
|
// Server instances
|
|
redisServer *redisserver.Server
|
|
webdavServer *webdavserver.Server
|
|
uiApp *AppInstance
|
|
jobManager *JobManager
|
|
|
|
// Control channels
|
|
stopCh chan struct{}
|
|
wg sync.WaitGroup
|
|
}
|
|
|
|
// AppInstance wraps the UI app and its listening status
|
|
type AppInstance struct {
|
|
App *fiber.App
|
|
Port string
|
|
}
|
|
|
|
// New creates a new ServerFactory with the given configuration
|
|
func New(config Config) *ServerFactory {
|
|
return &ServerFactory{
|
|
config: config,
|
|
stopCh: make(chan struct{}),
|
|
}
|
|
}
|
|
|
|
// Start initializes and starts all enabled servers
|
|
func (f *ServerFactory) Start() error {
|
|
log.Println("Starting HeroAgent ServerFactory...")
|
|
|
|
// Start Redis server if enabled
|
|
if f.config.EnableRedis {
|
|
if err := f.startRedisServer(); err != nil {
|
|
return fmt.Errorf("failed to start Redis server: %w", err)
|
|
}
|
|
}
|
|
|
|
// Start WebDAV server if enabled
|
|
if f.config.EnableWebDAV {
|
|
if err := f.startWebDAVServer(); err != nil {
|
|
return fmt.Errorf("failed to start WebDAV server: %w", err)
|
|
}
|
|
}
|
|
|
|
// Start UI server if enabled
|
|
if f.config.EnableUI {
|
|
if err := f.startUIServer(); err != nil {
|
|
return fmt.Errorf("failed to start UI server: %w", err)
|
|
}
|
|
}
|
|
|
|
// Start job manager if enabled
|
|
if f.config.EnableJobs {
|
|
if err := f.startJobManager(); err != nil {
|
|
return fmt.Errorf("failed to start job manager: %w", err)
|
|
}
|
|
}
|
|
|
|
log.Println("All servers started successfully")
|
|
return nil
|
|
}
|
|
|
|
// Stop gracefully stops all running servers
|
|
func (f *ServerFactory) Stop() error {
|
|
log.Println("Stopping all servers...")
|
|
|
|
// Signal all goroutines to stop
|
|
close(f.stopCh)
|
|
|
|
// Stop WebDAV server if it's running
|
|
if f.webdavServer != nil {
|
|
if err := f.webdavServer.Stop(); err != nil {
|
|
log.Printf("Error stopping WebDAV server: %v", err)
|
|
}
|
|
}
|
|
|
|
// Stop job manager if it's running
|
|
if f.jobManager != nil {
|
|
if err := f.jobManager.Stop(); err != nil {
|
|
log.Printf("Error stopping job manager: %v", err)
|
|
}
|
|
}
|
|
|
|
// Wait for all goroutines to finish
|
|
f.wg.Wait()
|
|
|
|
log.Println("All servers stopped")
|
|
return nil
|
|
}
|
|
|
|
// startRedisServer initializes and starts the Redis server
|
|
func (f *ServerFactory) startRedisServer() error {
|
|
log.Println("Starting Redis server...")
|
|
|
|
// Create Redis server configuration
|
|
redisConfig := redisserver.ServerConfig{
|
|
TCPPort: f.config.Redis.TCPPort,
|
|
UnixSocketPath: f.config.Redis.UnixSocketPath,
|
|
}
|
|
|
|
// Create and start Redis server
|
|
f.redisServer = redisserver.NewServer(redisConfig)
|
|
|
|
log.Printf("Redis server started on port %d and socket %s",
|
|
redisConfig.TCPPort, redisConfig.UnixSocketPath)
|
|
return nil
|
|
}
|
|
|
|
// startWebDAVServer initializes and starts the WebDAV server
|
|
func (f *ServerFactory) startWebDAVServer() error {
|
|
log.Println("Starting WebDAV server...")
|
|
|
|
// Create WebDAV server
|
|
webdavServer, err := webdavserver.NewServer(f.config.WebDAV.Config)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create WebDAV server: %w", err)
|
|
}
|
|
|
|
f.webdavServer = webdavServer
|
|
|
|
// Start WebDAV server in a goroutine
|
|
f.wg.Add(1)
|
|
go func() {
|
|
defer f.wg.Done()
|
|
|
|
// Start the server
|
|
if err := webdavServer.Start(); err != nil {
|
|
log.Printf("WebDAV server error: %v", err)
|
|
}
|
|
}()
|
|
|
|
log.Printf("WebDAV server started on port %d", f.config.WebDAV.Config.TCPPort)
|
|
return nil
|
|
}
|
|
|
|
// startUIServer initializes and starts the UI server
|
|
func (f *ServerFactory) startUIServer() error {
|
|
log.Println("Starting UI server...")
|
|
|
|
// Create UI app
|
|
uiApp := ui.NewApp(f.config.UI.AppConfig)
|
|
|
|
// Store UI app instance
|
|
f.uiApp = &AppInstance{
|
|
App: uiApp,
|
|
Port: f.config.UI.Port,
|
|
}
|
|
|
|
// Start UI server in a goroutine
|
|
f.wg.Add(1)
|
|
go func() {
|
|
defer f.wg.Done()
|
|
|
|
// Start the server
|
|
addr := ":" + f.config.UI.Port
|
|
log.Printf("UI server listening on %s", addr)
|
|
if err := uiApp.Listen(addr); err != nil {
|
|
log.Printf("UI server error: %v", err)
|
|
}
|
|
}()
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetRedisServer returns the Redis server instance
|
|
func (f *ServerFactory) GetRedisServer() *redisserver.Server {
|
|
return f.redisServer
|
|
}
|
|
|
|
// GetWebDAVServer returns the WebDAV server instance
|
|
func (f *ServerFactory) GetWebDAVServer() *webdavserver.Server {
|
|
return f.webdavServer
|
|
}
|
|
|
|
// GetUIApp returns the UI app instance
|
|
func (f *ServerFactory) GetUIApp() *AppInstance {
|
|
return f.uiApp
|
|
}
|
|
|
|
// startJobManager initializes and starts the job manager
|
|
func (f *ServerFactory) startJobManager() error {
|
|
log.Println("Starting job manager...")
|
|
|
|
// Create Redis connection for job manager
|
|
redisConn := &RedisConnection{
|
|
TCPPort: f.config.Redis.TCPPort,
|
|
UnixSocketPath: f.config.Redis.UnixSocketPath,
|
|
}
|
|
|
|
// Create job manager
|
|
jobManager, err := NewJobManager(f.config.Jobs, redisConn)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create job manager: %w", err)
|
|
}
|
|
|
|
f.jobManager = jobManager
|
|
|
|
// Start job manager
|
|
if err := jobManager.Start(); err != nil {
|
|
return fmt.Errorf("failed to start job manager: %w", err)
|
|
}
|
|
|
|
log.Println("Job manager started")
|
|
return nil
|
|
}
|
|
|
|
// GetJobManager returns the job manager instance
|
|
func (f *ServerFactory) GetJobManager() *JobManager {
|
|
return f.jobManager
|
|
}
|