package internal import ( "fmt" netHttp "net/http" "os" "time" // _ "net/http/pprof" // Register pprof "github.com/debridmediamanager/zurg/internal/config" "github.com/debridmediamanager/zurg/internal/handlers" "github.com/debridmediamanager/zurg/internal/torrent" "github.com/debridmediamanager/zurg/internal/universal" "github.com/debridmediamanager/zurg/internal/version" "github.com/debridmediamanager/zurg/pkg/http" "github.com/debridmediamanager/zurg/pkg/logutil" "github.com/debridmediamanager/zurg/pkg/premium" "github.com/debridmediamanager/zurg/pkg/realdebrid" "github.com/debridmediamanager/zurg/pkg/utils" "github.com/go-chi/chi/v5" "github.com/panjf2000/ants/v2" "go.uber.org/zap/zapcore" ) func MainApp(configPath string) { utils.EnsureDirExists("logs") // Ensure the logs directory exists logPath := fmt.Sprintf("logs/zurg-%s.log", time.Now().Format(time.DateOnly)) log := logutil.NewLogger(logPath) zurglog := log.Named("zurg") zurglog.Debugf("PID: %d", os.Getpid()) zurglog.Infof("Version: %s", version.GetVersion()) zurglog.Infof("GitCommit: %s", version.GetGitCommit()) zurglog.Infof("BuiltAt: %s", version.GetBuiltAt()) if log.Level() == zapcore.DebugLevel { zurglog.Infof("Debug logging is enabled; if you are not debugging please set LOG_LEVEL=info in your environment") } config, configErr := config.LoadZurgConfig(configPath, log.Named("config")) if configErr != nil { zurglog.Errorf("Config failed to load: %v", configErr) os.Exit(1) } apiClient := http.NewHTTPClient(config.GetToken(), config.GetRetriesUntilFailed(), config.GetApiTimeoutSecs(), false, config, log.Named("httpclient")) rd := realdebrid.NewRealDebrid(apiClient, log.Named("realdebrid")) premium.MonitorPremiumStatus(rd, zurglog) workerOptions := ants.Options{ // Nonblocking: true, PanicHandler: func(i interface{}) {}, Logger: log.Named("worker"), } workerPool, err := ants.NewPool(config.GetNumOfWorkers(), ants.WithOptions(workerOptions)) if err != nil { zurglog.Errorf("Failed to create worker pool: %v", err) os.Exit(1) } defer workerPool.Release() refreshOptions := ants.Options{ // Nonblocking: true, PanicHandler: func(i interface{}) {}, Logger: log.Named("refreshworker"), } // extra 1 worker for the refresh job refreshPool, err := ants.NewPool(1, ants.WithOptions(refreshOptions)) if err != nil { zurglog.Errorf("Failed to create worker pool: %v", err) os.Exit(1) } defer refreshPool.Release() repairOptions := ants.Options{ // Nonblocking: true, PanicHandler: func(i interface{}) {}, Logger: log.Named("repairworker"), } var repairPool *ants.Pool if config.EnableRepair() { repairPool, err = ants.NewPool(1, ants.WithOptions(repairOptions)) if err != nil { zurglog.Errorf("Failed to create repair pool: %v", err) os.Exit(1) } defer repairPool.Release() } utils.EnsureDirExists("data") // Ensure the data directory exists torrentMgr := torrent.NewTorrentManager(config, rd, workerPool, refreshPool, repairPool, log.Named("manager")) downloadClient := http.NewHTTPClient(config.GetToken(), config.GetRetriesUntilFailed(), config.GetDownloadTimeoutSecs(), true, config, log.Named("dlclient")) downloader := universal.NewDownloader(downloadClient) router := chi.NewRouter() handlers.AttachHandlers(router, downloader, torrentMgr, config, rd, log.Named("router")) // go func() { // if err := netHttp.ListenAndServe(":6060", nil); err != nil && err != netHttp.ErrServerClosed { // zurglog.Errorf("Failed to start pprof: %v", err) // os.Exit(1) // } // }() addr := fmt.Sprintf("%s:%s", config.GetHost(), config.GetPort()) zurglog.Infof("Starting server on %s", addr) if err := netHttp.ListenAndServe(addr, router); err != nil && err != netHttp.ErrServerClosed { zurglog.Errorf("Failed to start server: %v", err) os.Exit(1) } }