// backend\server.go package main import ( "context" "fmt" "net/http" "os" "os/signal" "sync" "syscall" "time" ) // --- main --- func main() { loadSettings() fixKeepRootFilesIntoModelSubdirs() postWorkQ.StartWorkers(2) enrichQ.StartWorkers(1) startPostWorkStatusRefresher() startEnrichStatusRefresher() go startGeneratedGarbageCollector() if err := initNSFWDetector(); err != nil { fmt.Println("❌ NSFW-ONNX Fehler:", err) os.Exit(1) } var closeNSFWOnce sync.Once closeNSFW := func() { closeNSFWOnce.Do(func() { _ = closeNSFWDetector() }) } defer closeNSFW() mux := http.NewServeMux() auth, err := NewAuthManager() if err != nil { fmt.Println("❌ auth init:", err) closeNSFW() os.Exit(1) } store := registerRoutes(mux, auth) setChaturbateOnlineModelStore(store) if err := clearAllPendingAutoStartOnStartup(); err != nil { fmt.Println("⚠️ [pending-autostart] startup clear failed:", err) } // Hintergrund-Worker go startChaturbateOnlinePoller(store) go startChaturbateAutoStartWorker(store) go startMyFreeCamsAutoStartWorker(store) go startDiskSpaceGuard() // optional: Bootstrap nur im Hintergrund if getSettings().UseChaturbateAPI { go func() { ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) defer cancel() if _, err := refreshChaturbateSnapshotNow(ctx); err != nil { fmt.Println("⚠️ [chaturbate] startup snapshot failed:", err) } else { fmt.Println("✅ [chaturbate] startup snapshot loaded") } }() } if _, err := ensureCoversDir(); err != nil { fmt.Println("⚠️ covers dir:", err) } fmt.Println("🌐 HTTP-API aktiv: http://localhost:9999") handler := withCORS(mux) srv := &http.Server{ Addr: ":9999", Handler: handler, } stopSig := make(chan os.Signal, 1) signal.Notify(stopSig, os.Interrupt, syscall.SIGTERM) go func() { <-stopSig fmt.Println("🛑 Beende Server...") ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() _ = srv.Shutdown(ctx) closeNSFW() }() if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { fmt.Println("❌ HTTP-Server Fehler:", err) closeNSFW() os.Exit(1) } closeNSFW() }